diff --git a/.coveragerc b/.coveragerc
deleted file mode 100644
index b8e2873..0000000
--- a/.coveragerc
+++ /dev/null
@@ -1,10 +0,0 @@
-[report]
-exclude_lines =
- import
- : TypeAlias
- _HAS_ORJSON
- \.{3}
- TypeVar
- Callable
-[run]
-include = orx/*
diff --git a/.github/checkers/pylint.json b/.github/checkers/pylint.json
deleted file mode 100644
index 71480fd..0000000
--- a/.github/checkers/pylint.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "problemMatcher": [
- {
- "owner": "pylint",
- "serverity": "warning",
- "pattern": [
- {
- "regexp": "(.+):(\\d+):(\\d+): (?:I|R|C|W|E|F)(?:\\d+): (.+) \\((.+)\\)",
- "file": 1,
- "line": 2,
- "column": 3,
- "message": 4,
- "code": 5
- }
- ]
- }
- ]
-}
diff --git a/.github/checkers/pyright.json b/.github/checkers/pyright.json
deleted file mode 100644
index 70523e8..0000000
--- a/.github/checkers/pyright.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "problemMatcher": [
- {
- "owner": "pyright",
- "pattern": [
- {
- "regexp": "/home/runner/work/orx/orx/(.+):(\\d+):(\\d+) - (information|warning|error): (.+) \\((.+)\\)",
- "file": 1,
- "line": 2,
- "column": 3,
- "severity": 4,
- "message": 5,
- "code": 6
- }
- ]
- }
- ]
-}
diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml
deleted file mode 100644
index a496bfd..0000000
--- a/.github/workflows/lint.yaml
+++ /dev/null
@@ -1,97 +0,0 @@
-name: Lint
-permissions:
- contents: read
-on:
- pull_request: {}
- push:
- branches: ["master"]
-jobs:
- black:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python 3.10
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install poetry
- run: pip install poetry
- - name: Install dependencies
- run: poetry install
- - name: Run tests
- run: poetry run task black_check
- isort:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python 3.10
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install poetry
- run: pip install poetry
- - name: Install dependencies
- run: poetry install
- - name: Run tests
- run: poetry run task isort_check
- pyright:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python 3.10
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install poetry
- run: pip install poetry
- - name: Install dependencies
- run: poetry install -E speed
- - uses: actions/setup-node@v2
- name: Install node
- with:
- node-version: "14"
- - name: Install pyright
- run: npm install -g pyright
- - name: Enable the problem checker
- run: echo "::add-matcher::.github/checkers/pyright.json"
- - name: Run pyright
- run: poetry run pyright orx/
- style-guide:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python 3.10
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install poetry
- run: pip install poetry
- - name: Install SSH key
- uses: shimataro/ssh-key-action@v2
- with:
- key: ${{ secrets.DEPLOY_KEY }}
- known_hosts: ${{ secrets.KNOWN_HOSTS }}
- if_key_exists: replace
- - name: Install style-guide
- run: poetry add git+ssh://git@github.com/nextsnake/style-guide.git --dev
- - name: Install dependencies
- run: poetry install
- - name: Enable the problem checker
- run: echo "::add-matcher::.github/checkers/pylint.json"
- - name: Run pylint
- run: poetry run pylint -d all -e asyncio-best-practices,license,outdated-typing --load-plugins=nextstyle orx/
- slots-check:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python 3.10
- uses: actions/setup-python@v3
- with:
- python-version: "3.10"
- - name: Install poetry
- run: pip install poetry
- - name: Install dependencies
- run: poetry install
- - name: Run slotscheck
- run: poetry run slotscheck orx/
-
diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
deleted file mode 100644
index 2ee6b16..0000000
--- a/.github/workflows/tests.yaml
+++ /dev/null
@@ -1,26 +0,0 @@
-name: Tests
-permissions:
- contents: read
-on:
- pull_request: {}
- push:
- branches: ["master"]
-jobs:
- pytest:
- runs-on: ubuntu-latest
- strategy:
- matrix:
- python-version: ["3.8", "3.9", "3.10"]
- name: Pytest (${{ matrix.python-version }})
- steps:
- - uses: actions/checkout@v1
- - name: Set up Python
- uses: actions/setup-python@v3
- with:
- python-version: ${{ matrix.python-version }}
- - name: Install poetry
- run: pip install poetry
- - name: Install dependencies
- run: poetry install
- - name: Run tests
- run: poetry run task tests
diff --git a/.gitignore b/.gitignore
index b647843..a096ff3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,143 +1,3 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
+__pycache__
poetry.lock
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-*.py,cover
-.hypothesis/
-.pytest_cache/
-cover/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-db.sqlite3-journal
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-.pybuilder/
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-# For a library or package, you might want to ignore these files since the code is
-# intended to run in multiple environments; otherwise, check them in:
-# .python-version
-
-# pipenv
-# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-# However, in case of collaboration, if having platform-specific dependencies or dependencies
-# having no cross-platform support, pipenv may install dependencies that don't work, or not
-# install all needed dependencies.
-#Pipfile.lock
-
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow
-__pypackages__/
-
-# Celery stuff
-celerybeat-schedule
-celerybeat.pid
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
-.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
-
-# pytype static type analyzer
-.pytype/
-
-# Cython debug symbols
-cython_debug/
-
-# Editors
-.vscode/
-.idea/
+test.py
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 721995b..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-# See https://pre-commit.com for more information
-# See https://pre-commit.com/hooks.html for more hooks
-repos:
- - repo: https://github.com/psf/black
- rev: 22.3.0
- hooks:
- - id: black
- args: ["--check"]
- - repo: https://github.com/pycqa/isort
- rev: 5.10.1
- hooks:
- - id: isort
- args: ["--check"]
- - repo: local
- hooks:
- - id: pytest
- name: pytest
- entry: pytest
- language: system
- pass_filenames: false
- always_run: true
- - repo: local
- hooks:
- - id: pyright
- name: pyright
- entry: pyright
- language: system
- pass_filenames: false
- always_run: true
- - repo: local
- hooks:
- - id: slotscheck
- name: slotscheck
- entry: slotscheck orx/
- language: system
- pass_filenames: false
- always_run: true
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
deleted file mode 100644
index eef29ed..0000000
--- a/.readthedocs.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-version: 2
-
-build:
- os: ubuntu-22.04
- tools:
- python: "3.11"
- jobs:
- post_create_environment:
- - pip install poetry
- - poetry config virtualenvs.create false
- post_install:
- - poetry install
-
-sphinx:
- configuration: docs/conf.py
diff --git a/LICENSE b/LICENSE
index e8375a7..d8d42f0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2023-present nextsnake developers
+Copyright (c) 2023 tag-epic
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
deleted file mode 100644
index fa0b6aa..0000000
--- a/README.md
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
- # Orx
- A high level Discord API wrapper made using nextcore
-
-
-
-### ✨ Features
-
-- #### Speed
-
- We try to make the library as fast as possible, without compromising on readability of the code or features.
-
-- #### Modularity
-
- All the components can easily be swapped out with your own.
-
-- #### Control
-
- Orx offers fine-grained control over things most libraries don't support by giving you low level access to our low level library
-
-
-
-
-
- # Examples
-
-
-
-### 🏓 Ping pong
-A simple "ping pong" example in nextcore.
-This will respond with "pong" each time someone sends "ping" in the chat.
-
-TODO: Add example
-
-> More examples can be seen in the [examples](examples/) directory.
-
-
-
-## Contributing
-Want to help us out? Please read our [contributing](https://orx.readthedocs.io/en/latest/contributing/getting_started.html) docs.
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index dcee282..0000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line, and also
-# from the environment for the first two.
-SPHINXOPTS ?= -j auto
-SPHINXBUILD ?= sphinx-build
-SOURCEDIR = .
-BUILDDIR = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/.gitkeep b/docs/_static/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/docs/_static/logo.ico b/docs/_static/logo.ico
deleted file mode 100644
index 61d7e36..0000000
Binary files a/docs/_static/logo.ico and /dev/null differ
diff --git a/docs/_static/logo.svg b/docs/_static/logo.svg
deleted file mode 100644
index 739a5c6..0000000
--- a/docs/_static/logo.svg
+++ /dev/null
@@ -1,11 +0,0 @@
-
diff --git a/docs/_static/speed-showcase.mp4 b/docs/_static/speed-showcase.mp4
deleted file mode 100644
index 439158e..0000000
Binary files a/docs/_static/speed-showcase.mp4 and /dev/null differ
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index a77ac60..0000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Configuration file for the Sphinx documentation builder.
-#
-# This file only contains a selection of the most common options. For a full
-# list see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
-
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-import os
-import sys
-
-sys.path.insert(0, os.path.abspath(".."))
-
-
-# -- Project information -----------------------------------------------------
-
-project = "orx"
-copyright = "2023 nextsnake developers"
-author = "nextsnake developers"
-
-
-# -- General configuration ---------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
- "sphinx.ext.autodoc",
- "sphinx.ext.napoleon",
- "sphinx.ext.intersphinx",
- "sphinx.ext.autosectionlabel",
- "sphinxext.opengraph",
- "sphinx_inline_tabs",
-]
-autodoc_typehints = "description"
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ["_templates"]
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
-
-# -- Extension configuration -------------------------------------------------
-# Intersphinx
-intersphinx_mapping = {
- "aiohttp": ("https://docs.aiohttp.org/en/stable/", None),
- "python": ("https://docs.python.org/3/", None),
- "towncrier": ("https://towncrier.readthedocs.io/en/stable", None),
-}
-
-# Opengraph
-ogp_image = "/_static/logo.svg"
-ogp_site_name = "Orx Documentation"
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = "furo"
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ["_static"]
-html_logo = "_static/logo.svg"
-html_favicon = "_static/logo.ico"
diff --git a/docs/contributing/getting_started.rst b/docs/contributing/getting_started.rst
deleted file mode 100644
index 82bca40..0000000
--- a/docs/contributing/getting_started.rst
+++ /dev/null
@@ -1,45 +0,0 @@
-:og:title: Orx contribution guide
-:og:description: Info about getting started helping out with the orx project!
-
-Contributing
-=============
-
-Setting up a development environment
---------------------------------------
-First, you will need to fork the `repository `__.
-
-Then you will need to setup a ssh-key. See `GitHub's tutorial `__.
-
-.. code-block:: sh
-
- git clone https://github.com//orx
-
- cd orx
-
- poetry install
-
- git checkout -b
-
- poetry shell # You will need to run this every time you need access to your development version of orx.
-
-We recommend making a "development" folder and adding it to your .git/info/exclude file.
-
-This can be done by making a ``.dev`` folder and appending ``.dev`` to the .git/info/exclude file on a new line.
-Every file in the ``.dev`` directory will now be invisible to git.
-
-Submitting your changes
--------------------------
-Before submitting we recommend checking a few things
-
-1. You have linted your code. This can be done by running ``task lint``
-2. You have checked your code for type errors. This can be done by running ``pyright``
-
-.. hint::
- Pyright needs to be installed. This can be done by using ``npm install --global pyright``
-
-3. Did you remember to write a changelog? See :external+towncrier:doc:`the towncrier tutorial `
-
-Do's and Dont's
-----------------
-- Do keep your PR scope small. We would rather review many small PRs with seperate features than one giant one.
-- Make draft PRs.
diff --git a/docs/index.rst b/docs/index.rst
deleted file mode 100644
index 8f5a557..0000000
--- a/docs/index.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-:og:description: A high level Discord API wrapper built on nextcore
-
-Welcome to Orx's documentation!
-====================================
-
-.. toctree::
- :maxdepth: 1
- :caption: Contents:
-
- releasenotes
-
-.. toctree::
- :hidden:
-
- contributing/getting_started
-
-
-Quickstart
-==========
-First, you need to install the library.
-
-.. tab:: Pip
-
- .. code-block:: shell
-
- pip install orx
-
-.. tab:: Poetry
-
- .. code-block:: shell
-
- poetry add orx
-
-.. warning::
-
- Using :data:`logging.DEBUG` logging may include secrets.
-
-
-Helping out
-=============
-We would appriciate your help writing orx and related libraries.
-See :ref:`contributing` for more info
diff --git a/docs/make.bat b/docs/make.bat
deleted file mode 100644
index 153be5e..0000000
--- a/docs/make.bat
+++ /dev/null
@@ -1,35 +0,0 @@
-@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set SOURCEDIR=.
-set BUILDDIR=_build
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.https://www.sphinx-doc.org/
- exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-
-:end
-popd
diff --git a/docs/releasenotes.rst b/docs/releasenotes.rst
deleted file mode 100644
index 352cc6a..0000000
--- a/docs/releasenotes.rst
+++ /dev/null
@@ -1,2 +0,0 @@
-Release notes
-=============
diff --git a/docs/requirements.txt b/docs/requirements.txt
deleted file mode 100644
index d50d7ec..0000000
--- a/docs/requirements.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Sphinx>=4.4.0
-sphinx-copybutton>=0.4.0
-furo>=2022.1.2
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index b58b781..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# Orx examples
diff --git a/newsfragments/.gitkeep b/newsfragments/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/orx/__init__.py b/orx/__init__.py
index 2b4b128..0c54e74 100644
--- a/orx/__init__.py
+++ b/orx/__init__.py
@@ -1,30 +1,20 @@
-# The MIT License (MIT)
-# Copyright (c) 2023-present nextsnake developers
-#
-# Permission is hereby granted, free of charge, to any person obtaining a
-# copy of this software and associated documentation files (the "Software"),
-# to deal in the Software without restriction, including without limitation
-# the rights to use, copy, modify, merge, publish, distribute, sublicense,
-# and/or sell copies of the Software, and to permit persons to whom the
-# Software is furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-# DEALINGS IN THE SOFTWARE.
+"""
+orx
+~~~
+A simple wrapper for the Discord API.
-from __future__ import annotations
+:license: MIT
+:copyright: 2023 tag-epic
+"""
-from typing import TYPE_CHECKING
+from typing import Literal
-if TYPE_CHECKING:
- from typing import Final
-__version__: Final[str] = "1.0.0a"
-__all__: Final[tuple[str, ...]] = ("__version__",)
+__version__: Literal['0.1.0'] = '0.1.0'
+
+
+from .bot import *
+from .events import *
+from .flags import *
+from .models import *
+from .state import *
diff --git a/orx/bot.py b/orx/bot.py
new file mode 100644
index 0000000..e317bbe
--- /dev/null
+++ b/orx/bot.py
@@ -0,0 +1,84 @@
+# cython: language_level=3
+# Copyright (c) 2023 tag-epic
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import asyncio
+import typing as t
+
+from nextcore.gateway import ShardManager
+from nextcore.http import BotAuthentication, HTTPClient
+
+from .events.dispatcher import ClassDispatcher
+from .flags import Intents
+from .models import Model
+from .state import DEFAULT_MODELS, State
+
+
+class Bot:
+ """A class representing a Discord bot controlled by the user."""
+
+ def __init__(
+ self,
+ token: str,
+ intents: Intents,
+ state_cls: t.Type[State] = State,
+ models: dict[Model, Model] = DEFAULT_MODELS,
+ shards: int | None = None,
+ shard_ids: list[int] | None = None,
+ **state_kwargs
+ ) -> None:
+ mods = DEFAULT_MODELS
+ for k, v in models.items():
+ mods[k] = v
+
+ self._state = state_cls(token, mods, **state_kwargs)
+ self._auth = BotAuthentication(token)
+ self._http_client = HTTPClient()
+ self._shard_manager = ShardManager(
+ self._auth,
+ int(intents),
+ self._http_client,
+ shard_count=shards,
+ shard_ids=shard_ids,
+ )
+ self.intents = intents
+ self._dispatcher = ClassDispatcher()
+
+ async def _on_gateway_event(self, event: str, data: dict[str, t.Any]) -> None:
+ print(event)
+
+ async def connect(self, block: bool = True) -> None:
+ self._shard_manager.event_dispatcher.add_listener(
+ self._on_gateway_event, event_name=None
+ )
+ await self._http_client.setup()
+ await self._shard_manager.connect()
+
+ if block:
+ try:
+ await asyncio.Future()
+ except (asyncio.CancelledError, KeyboardInterrupt):
+ await self._shard_manager.close()
+ await self._http_client.close()
+ self._dispatcher.close()
+
+ def start(self, *, debug: bool = False) -> None:
+ asyncio.run(self.connect(), debug=debug)
diff --git a/orx/events/__init__.py b/orx/events/__init__.py
new file mode 100644
index 0000000..24f3c5b
--- /dev/null
+++ b/orx/events/__init__.py
@@ -0,0 +1,10 @@
+"""
+orx.events
+~~~~~~~~~~
+Module housing orx's event handling
+
+:license: MIT
+:copyright: 2023 tag-epic
+"""
+
+from .dispatcher import *
diff --git a/orx/events/dispatcher.py b/orx/events/dispatcher.py
new file mode 100644
index 0000000..ec40009
--- /dev/null
+++ b/orx/events/dispatcher.py
@@ -0,0 +1,38 @@
+# cython: language_level=3
+# Copyright (c) 2023 tag-epic
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+import typing as t
+
+from nextcore.common import Dispatcher
+
+
+class Event(t.Protocol):
+ cache = False
+
+ def __init__(self) -> None:
+ ...
+
+
+class CacheEvent(Event):
+ cache = True
+
+
+ClassDispatcher = Dispatcher[t.Type[Event]]
diff --git a/orx/flags.py b/orx/flags.py
new file mode 100644
index 0000000..561ba4e
--- /dev/null
+++ b/orx/flags.py
@@ -0,0 +1,64 @@
+# cython: language_level=3
+# Copyright (c) 2023 tag-epic
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+# TODO: test whether performance of these flags are subnominal
+
+import typing as t
+from enum import IntFlag
+
+T = t.TypeVar("T")
+
+
+class BaseFlag(IntFlag):
+ @classmethod
+ def all(cls: t.Type[T]) -> T:
+ value: int = 0
+
+ for name in dir(cls):
+ attr = getattr(cls, name)
+
+ if isinstance(attr, BaseFlag):
+ value += int(attr)
+
+ return cls(value)
+
+
+class Intents(BaseFlag):
+ guilds = 1 << 0
+ guild_members = 1 << 1
+ guild_moderation = 1 << 2
+ guild_emojis_and_stickers = 1 << 3
+ guild_integrations = 1 << 4
+ guild_webhooks = 1 << 5
+ guild_invites = 1 << 6
+ guild_voice_states = 1 << 7
+ guild_presences = 1 << 8
+ guild_messages = 1 << 9
+ guild_message_reactions = 1 << 10
+ guild_message_typing = 1 << 11
+ direct_messages = 1 << 12
+ direct_message_reactions = 1 << 13
+ direct_message_typing = 1 << 14
+ message_content = 1 << 15
+ guild_scheduled_events = 1 << 16
+ auto_moderation_configuration = 1 << 20
+ auto_moderation_execution = 1 << 21
diff --git a/orx/models/__init__.py b/orx/models/__init__.py
new file mode 100644
index 0000000..e017e36
--- /dev/null
+++ b/orx/models/__init__.py
@@ -0,0 +1,12 @@
+"""
+orx.models
+~~~~~~~~~~
+Modular representations of Discord objects and items.
+
+:license: MIT
+:copyright: 2023 tag-epic
+"""
+
+
+class Model:
+ """The highest level model. Only used for typing purposes."""
diff --git a/orx/py.typed b/orx/py.typed
deleted file mode 100644
index d040955..0000000
--- a/orx/py.typed
+++ /dev/null
@@ -1,2 +0,0 @@
-# Marker file for PEP 561.
-# This marks that we use inline typings for type checkers
diff --git a/orx/state/__init__.py b/orx/state/__init__.py
new file mode 100644
index 0000000..1753760
--- /dev/null
+++ b/orx/state/__init__.py
@@ -0,0 +1,11 @@
+"""
+orx.state
+~~~~~~~~~
+Orx state handling.
+
+:license: MIT
+:copyright: 2023 tag-epic
+"""
+
+from .cache import *
+from .core import *
diff --git a/orx/state/cache.py b/orx/state/cache.py
new file mode 100644
index 0000000..37fee45
--- /dev/null
+++ b/orx/state/cache.py
@@ -0,0 +1,113 @@
+# cython: language_level=3
+# Copyright (c) 2023 tag-epic
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+import typing as t
+
+
+class _stored:
+ __slots__ = ("parents", "id", "storing")
+
+ def __init__(self, parents: set[t.Any], self_id: t.Any, storing: t.Any) -> None:
+ self.parents = parents
+ self.id = self_id
+ self.storing = storing
+
+
+T = t.TypeVar("T")
+
+
+class Store:
+ __slots__ = ("_store", "max_items")
+
+ _store: set[_stored]
+
+ def __init__(self, max_items: int | None = None) -> None:
+ self._store = set()
+ self.max_items = max_items
+
+ async def fetch_one(self, parents: list[t.Any], id: t.Any) -> t.Any | None:
+ ps = set(parents)
+
+ for store in self._store:
+ if store.parents & ps and store.id == id:
+ return store.storing
+
+ async def fetch_from_id(self, id: t.Any) -> tuple[set[t.Any], t.Any] | None:
+ for store in self._store:
+ if store.id == id:
+ return store.parents, store.storing
+
+ async def insert(self, parents: list[t.Any], id: t.Any, data: t.Any) -> None:
+ if self.max_items and len(self._store) == self.max_items:
+ self._store = set()
+
+ self._store.add(_stored(set(parents), id, data))
+
+ async def replace(
+ self, parents: list[t.Any], id: t.Any, data: t.Any
+ ) -> t.Any | None:
+ ps = set(parents)
+
+ for store in self._store:
+ if store.parents & ps and store.id == id:
+ old_data = store.storing
+ self._store.discard(store)
+ store.storing = data
+ self._store.add(store)
+ return old_data
+ else:
+ if self.max_items and len(self._store) == self.max_items:
+ self._store = {}
+
+ store = _stored(set(parents), id, data)
+ self._store.add(store)
+
+ async def delete(
+ self, parents: list[t.Any], id: t.Any, type: t.Type[T] | T = None
+ ) -> T:
+ ps = set(parents)
+
+ for store in self._store:
+ if store.parents & ps or store.id == id:
+ self._store.remove(store)
+ return store
+
+ async def fetch_all(self):
+ for store in self._store:
+ yield store.storing
+
+ async def fetch_children(self, parents: list[t.Any]):
+ ps = set(parents)
+
+ for store in self._store:
+ if store.parents & ps:
+ yield store.storing
+
+ async def clear(self) -> None:
+ self._store.clear()
+
+ async def delete_children(self, parents: list[t.Any]) -> None:
+ ps = set(parents)
+
+ for store in self._store:
+ if store.parents & ps:
+ self._store.remove(store)
diff --git a/orx/state/core.py b/orx/state/core.py
new file mode 100644
index 0000000..d796d41
--- /dev/null
+++ b/orx/state/core.py
@@ -0,0 +1,35 @@
+# cython: language_level=3
+# Copyright (c) 2023 tag-epic
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from ..events.dispatcher import Event
+from ..models import Model
+from .cache import Store
+
+DEFAULT_MODELS: dict[Model, Model] = {}
+
+
+class State:
+ def __init__(self, token: str, models: dict[Model, Model] = DEFAULT_MODELS) -> None:
+ self.token = token
+ self.stores: dict[str, Store] = {}
+ self.models: dict[Model, Model] = models
+ self.cache_events: list[Event] = []
diff --git a/pyproject.toml b/pyproject.toml
index ada3b54..f9e9742 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,95 +1,19 @@
[tool.poetry]
name = "orx"
-version = "1.0.0a"
-description = "A high level Discord API wrapper made using nextcore"
-authors = ["nextsnake developers"]
+version = "0.1.0"
+description = "A simple and powerful Python wrapper for the Discord API"
+authors = ["tag-epic", "VincentRPS "]
license = "MIT"
-classifiers = [
- "Private :: Do Not Upload",
- "Development Status :: 3 - Alpha",
- "Framework :: AsyncIO",
- "Framework :: aiohttp",
- "Intended Audience :: Developers",
- "Natural Language :: English",
- "Operating System :: OS Independent",
- "Programming Language :: Cython",
- "Programming Language :: Python :: Implementation :: CPython",
- "Topic :: Communications :: Chat",
- "Topic :: Software Development :: Libraries :: Python Modules",
- "Typing :: Typed"
-]
readme = "README.md"
-homepage = "https://nextcord.dev" # TODO: Replace this?
-repository = "https://github.com/nextsnake/orx"
-documentation = "https://docs.nextcord.gay" # TODO: Replace this
-keywords = ["discord", "bot", "wrapper", "api"]
-packages = [
- { include = "orx" }
-]
-
-[tool.poetry.urls]
-"Bug Tracker" = "https://github.com/nextsnake/orx/issues"
[tool.poetry.dependencies]
-python = "^3.8"
-aiohttp = ">=3.6.0,<4.0.0"
-frozendict = "^2.3.0"
-types-frozendict = "^2.0.6" # Could we extend the version requirement
-typing-extensions = "^4.1.1" # Same as above
-orjson = {version = "^3.6.8", optional = true}
-types-orjson = {version = "^3.6.2", optional = true}
-discord-typings = "^0.5.0"
+python = "^3.11"
+nextcore = {git = "https://github.com/nextsnake/nextcore"}
[tool.poetry.group.dev.dependencies]
-Sphinx = "^5.0.0"
-sphinx-copybutton = "^0.4.0"
-furo = "*" # CalVer, the version does not make sense to lock.
-isort = "^5.10.1"
-black = "^22.6.0"
-pytest = "^6.2.5"
-taskipy = "^1.9.0"
-pytest-asyncio = "^0.18.1"
-pytest-mock = "^3.7.0"
-pre-commit = "^2.18.1"
-sphinxext-opengraph = "^0.6.3"
-slotscheck = "^0.14.0"
-sphinx-inline-tabs = "*" # CalVer, the version does not make sense to lock.
-towncrier = "^22.12.0"
+black = "^23.3.0"
+isort = "^5.12.0"
[build-system]
-requires = ["poetry-core>=1.0.0"]
+requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
-
-[tool.poetry.extras]
-speed = ["orjson", "types-orjson"]
-
-# Tools
-[tool.taskipy.tasks]
-black_check = "black . --diff --check"
-isort_check = "isort . --check --diff"
-tests = "pytest"
-black = "black ."
-isort = "isort ."
-lint = "black . && isort ."
-
-[tool.black]
-line-length = 120
-target-version = ["py38"]
-
-[tool.isort]
-profile = "black"
-
-[tool.pytest.ini_options]
-asyncio_mode = "strict"
-testpaths = ["tests"]
-
-[tool.pyright]
-pythonPlatform = "All"
-typeCheckingMode = "strict"
-pythonVersion = "3.8"
-exclude = ["tests/"]
-
-[tool.towncrier]
-package = "orx"
-filename = "docs/releasenotes.rst"
-directory = "newsfragments/"
diff --git a/tests/.gitkeep b/tests/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/utils.py b/tests/utils.py
deleted file mode 100644
index 1a97f09..0000000
--- a/tests/utils.py
+++ /dev/null
@@ -1,38 +0,0 @@
-from __future__ import annotations
-
-from asyncio import TimeoutError, wait_for
-from time import time
-from typing import TYPE_CHECKING
-
-if TYPE_CHECKING:
- from typing import Any, Callable
-
- from typing_extensions import ParamSpec
-
- P = ParamSpec("P")
-
-
-def match_time(estimated: float, max_offset: float):
- """Errror if the estimated time is off"""
-
- def outer(func: Callable[P, Any]):
- async def inner(*args: P.args, **kwargs: P.kwargs) -> None:
- start = time()
- try:
- await wait_for(func(*args, **kwargs), timeout=estimated + max_offset)
- except TimeoutError:
- raise TimeoutError(
- f"Function returned too slowly (terminated). Expected {estimated}s, got {estimated + max_offset}s"
- ) from None
- end = time()
- time_used = end - start
- assert (
- time_used >= estimated - max_offset
- ), f"Function returned too quickly. Expected {estimated}s, got {time_used}s"
- assert (
- time_used <= estimated + max_offset
- ), f"Function returned too slowly. Expected {estimated}s, got {time_used}s"
-
- return inner
-
- return outer