From b0e6dd82129869acd7640a9567538c423886ebce Mon Sep 17 00:00:00 2001 From: VincentRPS Date: Thu, 20 Jul 2023 21:21:01 +0800 Subject: [PATCH 1/2] refactor!: complete rewrite --- .coveragerc | 10 -- .github/checkers/pylint.json | 18 ---- .github/checkers/pyright.json | 18 ---- .github/workflows/lint.yaml | 97 ----------------- .github/workflows/tests.yaml | 26 ----- .gitignore | 144 +------------------------- .pre-commit-config.yaml | 37 ------- .readthedocs.yaml | 15 --- LICENSE | 2 +- README.md | 43 -------- docs/Makefile | 20 ---- docs/_static/.gitkeep | 0 docs/_static/logo.ico | Bin 10287 -> 0 bytes docs/_static/logo.svg | 11 -- docs/_static/speed-showcase.mp4 | Bin 94291 -> 0 bytes docs/conf.py | 73 ------------- docs/contributing/getting_started.rst | 45 -------- docs/index.rst | 42 -------- docs/make.bat | 35 ------- docs/releasenotes.rst | 2 - docs/requirements.txt | 3 - examples/README.md | 1 - newsfragments/.gitkeep | 0 orx/__init__.py | 44 +++----- orx/bot.py | 84 +++++++++++++++ orx/events/__init__.py | 10 ++ orx/events/dispatcher.py | 38 +++++++ orx/flags.py | 64 ++++++++++++ orx/models/__init__.py | 12 +++ orx/py.typed | 2 - orx/state/__init__.py | 11 ++ orx/state/cache.py | 113 ++++++++++++++++++++ orx/state/core.py | 35 +++++++ pyproject.toml | 92 ++-------------- tests/.gitkeep | 0 tests/utils.py | 38 ------- 36 files changed, 392 insertions(+), 793 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .github/checkers/pylint.json delete mode 100644 .github/checkers/pyright.json delete mode 100644 .github/workflows/lint.yaml delete mode 100644 .github/workflows/tests.yaml delete mode 100644 .pre-commit-config.yaml delete mode 100644 .readthedocs.yaml delete mode 100644 README.md delete mode 100644 docs/Makefile delete mode 100644 docs/_static/.gitkeep delete mode 100644 docs/_static/logo.ico delete mode 100644 docs/_static/logo.svg delete mode 100644 docs/_static/speed-showcase.mp4 delete mode 100644 docs/conf.py delete mode 100644 docs/contributing/getting_started.rst delete mode 100644 docs/index.rst delete mode 100644 docs/make.bat delete mode 100644 docs/releasenotes.rst delete mode 100644 docs/requirements.txt delete mode 100644 examples/README.md delete mode 100644 newsfragments/.gitkeep create mode 100644 orx/bot.py create mode 100644 orx/events/__init__.py create mode 100644 orx/events/dispatcher.py create mode 100644 orx/flags.py create mode 100644 orx/models/__init__.py delete mode 100644 orx/py.typed create mode 100644 orx/state/__init__.py create mode 100644 orx/state/cache.py create mode 100644 orx/state/core.py delete mode 100644 tests/.gitkeep delete mode 100644 tests/utils.py 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 61d7e366a5e45222ccef889780a2855a2ad9392a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10287 zcmdVAg;N~e^F2I^E$$Ft@gN~M1Xy%QfZ*~32+rc}5ZpC5fdIiFSa7%C?ht~z6Wm>Y z`}zJA?>kddbEodi)YP5s)7|GZ0Dutt|27an3y{A708+#_Tt!J52a^I5F~pITk^J<( z+5a8rNQl!UK8*W+SN2XyYM}9-Zm9skJSi*rUd?^s$R{ifGCke!9C6~+l1gux_w8e= zwbx0>@*2LJJ6-LcW+KlMzBPdyi4RCyivArCbgD@&oK|DwsOb4Rlgty&Ti?_J^%(B!II3y#6nb?OBAd@mban3IjdeY=*6-*Kp%tu4%RATB*W(qINpOOZDI*I)!mO9Wb zn&f2%y_hq&Kk*q9{=G3vlKX0hzU1$^gmGt89NuXMW`ig(6*tJ>6=nOI9lH0%@lfJR zDpITueXFy{D3N}`dUHHFo9>mqruDU^80!LQLsBh&?O&mtPLsr)oXC&WFplomejOC5 z%18RSsz9`VH0vT$Ie;MTTFwZC%)}Ko2`|Vp5fQ?6$O|E z8T(7+DZb#Yb|mC>*)UX{M%Y0D?Os(Sdrjyso`)>(U5@Uffe83CJrN@|?9tt!A_fJi zgXhBNO973FcY92j-5aSaN(DcWZ>#8wW;6KxCknUSoJ<$2uLELm+afh2K}nj^Tj#Et z`=6gc?U`>y#D0juAmljr#05m?z|rWz{l%b2&m(_O4n~quuz(hC zdVu@&Iq^$jftt*j++>MqY5*N*9~bR!xNO~8vSdX=ZV>QC-#eCOZGie0%j~OM&KQ$6 zol7Hj!(1xO{k}0WW^(`!DHrwGF0s413Uc~p1u|a7(YtoW%lw`es1;iM=lyrRYHc*5 zYW8DIr9=Js`a^ztu(BX~zV?_9*Cg-nJ$S}u-7S0M*gJ(>FHgb;OF0!?QZ5Tt!2OE^ zKT9N7Dp5zs_#|qZKRI%w^k2V#urP9%WYCw~5)Wk`DQR#fx`I~KHo=b%{+Zs{oZ+@6 zT(m%AhS24YC(QvjDSaA@<#upPU2uBDz8|U$!4++$fUs{3Q)%L9e?n$^NQqbQpA|y*fg@&+z zOiBf~Miey(UZT2R7JYZr1Oqn%CZ^0UpZ;+I*{{R&rFAR*QOQ&kSkL@a&wAYVH*H(P zuTwa+#AlkoAnY0CSI<*aVGfqV!I7kB08s+#YtZS?{T{u>L!05T;WHy!#5nT>*Wg+R zO!T|23+>gZIOb{=g&Yi)9uRqcaz?3ty6i%5sQ)67EJC0&UYKwv@1(uJT$duXWvS=f zE=;>RMXn>D=Kwi4i4S`l$$eYa{JXA@@B;dd`fZT~Ud|Os! zlgK+c72+s5cjA<1yWT=K0&8n!T_K8Fe4WxY>12jCvTKd`AL-b?A%rN)stTC4!9KLAo!%cDtKK>dee>8+RR+VHGE)k zkerKH=CQ$#1!{f@gefJhA7Fdk#+?XzCb@BZx#8^yWr>e|<=(zHL}xfX#&6>hk6l_6K{jJ-0fu(ZCTdKf3+1q>+Xd zCQKA++W0OGQ(f!x(<_tLz{RX;NW`>^fe<+J>13r5J1OmXtz-{TF=dk5wAIXu9=A~T6d_cxx8AV}y5o1r ztoIXzcA+&?V=S|FEm=viXdFA=?~kff>4Lgu=pU)FFB)r(?Pth#%@yMmcE;71rG7r# zLd2KcE_|*}*j{^Hg^2*sONQ^f^-50HYe~klU+%l%otHb+d~|%Si2(w^9abdH14lrI zAi`?-$E`+CgDC<)f3OcYL$;rMa9KgXTIvTiiw%~_RtK-O-Zq~2x_u^Guk$;T=M7y3 zmdIlbRO;kNKbwuz90gwQKFyc3A|&tK@HqInwkpck+zc#mo71s2Fn+aXLTzAo?ns91 zB!;2c#i5mNxo+IiBLpo*S@O|Xa|Jp&^ep(3OWf_1kw&z!KDlU~q`ow^TI*|l5PmUp zo6@{B{ldbe^~$tQ=ZT)s-4$w_^LCC)wWVZn8blwP<^#9UHRe;f%5&9Zd9dcA>ydcH zE3q4&Ua!<{k3?utT$aV*T|zYGtJ>6PS@0EZ#CSU@lrf|9iq>LwAGVo%%iQ9$sX*|& zyW?cprmL+(c#t*F#!-zRFJHX`B^55;!W!RRB9B2iA+2@HD3}YNUJ@XLzE-vFs^KC0@%c%$m}b?F6!)-@<+jkLD`4K?NFagk z#eD!qdLE7Da~t#0%Q<|{>PL-XPzRO{lI{uWXZpZgI90>5K73AL@|dxF)_%qG!WZZ1 z3%!`pyxt6doK;2rgCUzJ-7!&;d;e3nrwhtSWN01w7c51RwN}3G6>IIY3jdgRLLn4{ z2$kRkor&2A!@!ov+OXMDO{W~z{XxG7T1f_i54Dq=cn7xu{%aBY>U&(oYQ29Yg?>qk z3mp_di~2JP+L^**aZ}rDLk|7EFz8&$vkD0PxOuPBx`Iuto~`a2OF5)GmTo}E z)`eII)J6gs6b*jrm}VpTK`8&8N(4G<>2Do5 zQGDmqQpij|jB4dJ^19=TirQU(&J(iBFtSf&Fr~0?Y>D^kdiDuXf>xG0ciw=*Bsoa3 z8M&ikGsh!SkScAscXi>f&f*ae*Rlc;Ha7EtTl~AICWwD}%=>HV5$z`5H_mkN5R4oX zd?Io@zdMnA;+(Kuuad2dlTTDF1FUU$Vi&RDP9{ddx{^jypkb+|NRR;%d_KK8l^3?!JBRJ_~XmrljwiN*QA1vP0R!dhu!}D zI2-NoGanV1)T zVo5yq@rYMGeXbK&HyHF&&ocJ#FF3tE6B*l|Z)6jLrE~LLxjwlVwxfrLH8r;*zB%0% zxkbI5^3ClX+DB2uUERj-RXv#IzBhXjf`&YHyg9&DLrkwOVIeKe^<;?)B*2=nDpkeX z`=y-u%B&ukJy0rF!eRM%JI}Bx$r&5eEK-)*Y>J|0cM|ciyA$~`p&J+7XoCIWOSy}b z{zZL0nxn*g*Fvu6WlDa}#` zw&)fb(mBHUGW!{j(LbSSj$VL~h`#ow-zqGIr(MuKH#M-P7MG`&Q8Y#ic))4CjHE7r zrPj|nU3@^10-bG1U?7wIAFts{Wq}8#6wJ0EkYm}HnazO#JJGr3Tbi&j!pPr#HhFl= zJ%XOd%3dleq_Vm%*AWCeuUt4ci? zlh83wLT)W?*DfrfCeowtoBOudx_E-|h*rU75zEytcl0Ir{NAQ7JmL&1*xhDvGI8Di zEI_sLyYF_Oq4dfT^Wt>a97g%~CHa4+UuuO0Es$Ol8jEW z{x(G|KHksrO~7@l^^_uu+1f}q6M1}@`H`^h*QfCQKQa~XQ=PFv$?_3vjaNTkZPE8L zd`O^!@yhBEW_EpI6z!H5V8cLjNRvyTYJw6Y8_v__ei4sp! zel|w;f`%`>O??UiW5hR`Dd@&TfCE}AnH|rF6+GR@Ctb7>tQ1J~cxU44dBciq_KRb&tCW3fthBp3Eh-mRm>k!| z4kDnDF;6eQyJ|0F4j6wL`^z0K9QmTmd?6~r44(%9-d8NuXDbbJy3(Pd8}cL}399=g zujlXPZAEIEAzr8RuM+MMaGexuEr71}M{?k0cBSWjZ)2tx>Vph^Bb>ODVwMpG$OLH|-FfN@JcuGY&+=NYRQ>>cP6 z6OawpD3c4Lql&JfRfXeS6@Cm9t60Y~`WU0S4Z2-|x%TU{v148n#I!g*fORdL55V4| zzn+sJZ&5(To!5;8_|Y=1d8O4X8zu7GjhWM-n)?}5l%-Y`hD}_>Zsiq1->Kcqm`0{a zPv;yA)}r_%EH}yVTe3X<@n&LyX$K%l&LpBjxUz%lS~a8CkzMS1XY4i6i`4ET2%vaK z+Y@p()puqP#f?X$RG%;~8rQNZg67YGD-oBI5fub-8zrp!sQk4FD2#$@O+LOT+!AzkCxe4klEI2U$b zmJ*;oQNj7y5#s)p6AFQ_NBmyXiw~(knk*4-!(RyRiie z1A#wJ=dv-tYi!MwfLWTBJ`ls)S|V)daU8+sZqE;saIJ87^5(H$!bd_nVk5b&(iMvG zd$-gr{QFZe-vWP+$u(3|K9b0;HZ_0WE~-v>eOmrY`-VyhZsW>d@?;#&O|k=<%2vDA z9rG0fWui2ILM2>s-l7zRn)c41s{jJn92oq$*<(mvfH_QOmD+8Zip1C?jf?H{^`MvojfX*th!JlTN zW>`fKgF0q3#Q`euZHwnn{1TzcPO@u-|yK%(=~Tj?Vj}kQ%$~ zl&FpcZfx=x-Rb!JkYy%$ojC%}t|a{d>J{o!>CkSrv|&asE8vuXxlnC|;*pUR^G{*Z4DePa7M z(E?Gy5=)iMvn4A}{>P_!MtZm|)r8)DCBpyXv!w7n-6<+?XrQVgli@4;DH1ubY3DE+ z1Pr`rO;VLvC%SwCPFOWv-RM$?>B+M$&(UAmYvO@S56MYS)~&4IdR&fR>@>Q!jf zZ_r5ml$eZSk>lce1*DGv@e7~mIW`tyyNpl>w_wY?C|==!O=Z3h;OcV`uzrxH=!ygC zAn(sR@{B#hEE`EOXnj`%`n>!82K5E3D1fGi$QE3{ zwibJ>Ms~PdDSAmsr2B&O5XP>T7W(e_vHj$kcWH%vUPh?(8#5nI)`Tx-#Ao!e?duuwz6%3U zkcv{lOxrIVxA%J7LnMHDE0)AXS@fxTFr(nNP3`zd0a(KXxuim_m_dfPq2RY`l%6}J z>=}$<2lU-gqp5m+{DO!nilidEYvweX!+xPJVqycc20?YM;zTp48XBru+G@~tTZVGI zkq&N5lNOTl(U8+p+*{|&*%E`0NGAgMQq2l6wFDYKlO~l(-rjMEnPK|GEMmGqQTjHT z)s`~+VBOsOWw}y2opTn6$<;N`-^SNJ4bt&f$c$a6S6eZp;ItXrOn_^2F)MDqu&~?x z)U3<;b`g;QxbpX|qxxr)_eM|ZS)NeZxOTo9=PkCFRuqd|6zgZFv8x$WXcR3alG{Sm zzTM&8#`2~&a7Hh$pB~V8Sl=X0DdvxNYq}IP8phX{HtKS9^$dhvUjpzx!zl(ef4J>U zL--M_--0ejY9L7ealvBdIb5>^h`W|OAv3Pfews3AV>NIKQ)D~m!F|fqG*2$gFDpZB zX#qSGNDTq#cD-CuRcBlf4|5K#2v>15UhNCnvdH z>5d-LqhL3S(q<{Qq)ZCAO;fYx>)#N7Y6VfxSR3nM7ymw%pPRbo!5j ze%{E6C(6|OZ-r53Lw_~IJfdd3eBaz0lz7rE9%J+!C4 zrKH616f7x)OMcg`*l8+gq*=A!i&$*=r!T5-sp4m)+5|PX|1%B(C<*W=Y)m==L$9~m zj*ktD;@zz^ypws0vBkO&aX)v1&TAo;h7`+}f8O9%)z8ABl@*d$p&X|idjzxl;chPB z?tl#V>@vj^$ws!5*?;sFSgr~2vEx6VR_i1-uA=Qr%hj?F5eAzaLNHqL@OI07pzOO% z_OfDW&(Zl{;her&juxEZBg*ywtxbKmYN7dDhP1F3ei}u0jRB@6pCj!qCo_0DF^_Qj z!hC=0cDguE`u0A5I-g9!X4*d_6t$fvKIA$MwIXN|Y`-7%)ZR44dNkzfI)Wnf+V&^i z(q>GmxNs>YM<=41%|$L+DD(9Zp@w{|-SV4NeDy3CC&WOZX4N%CKCE~>;~BcLME>AF zFVJohPm@~~S!-E1e{)~lu?f}0-Bh}aqwSF z10L-tOxyg&zc>(wN2#!EW zBUXQ2#z^}ZQ>`_3hF#|+k{wk4NF3zs;xK{)9*}{SN~;PA>G^cXFL4Tgb%yyYZ0W7< z5C=Q{Pg){3$Nt^rl^0^->NLy~9*eI~FY>^(QX?Y(s#*OSxV|$45aVs7xfGB<+K@Q8) zyKv$8zXHa_f)(>gv%afoARbR31SVIfGaN)%V-Pbu$o~7fdmHH=DGWSVK&?!WG4YOx zQm8%vox}#}#}cXcmFJTPj_MVt`&Bb3M`HSNhF4stfWFC`g9IU43!EO;M?_F;|4NuB zslgaA&*@*asFmfSCi4A;b5%zM@tS39VD1aq$a@G{a7OwkMADDYXR;t;x|y>>rL3J! zACRm&feU1_{gT{yM0s=~&pppaF}NcH(y;KiRjlfFeiD%{nOoY>ZZ2=Kz0y?|#eEu4 zp^&-Nf_4m6ySPasR?mh!CMAY*yU5$_Z#(Jaspdc1qd69vqfR)MRiB3ZM^Ga zhPznK1kyl9{aK|ZJ{s5cQvBXV`5ypmF;o!xv3Z?~7Nbuv4{e&_NP2{Cp`s*&W=M+m z0*=hG8~1v%^IJA2N94JYF36(N<%+l;OBxa+sRe;`?X6&+(>xcs3|JyO`TMx+Pf*U@#~iyMLw1ca!% zyD5X0vhv18x~oNLC|G96|G1UQ)nq3u5rJhLVt*sb`=B9%#YH0@y9(B@qkzJFDQS`lc>uTBLjPlkx^Y2QO zna)R*&x<&&X${@ojo&?-itq1?%?YNUC+U5D@`*@4lQonDxbluXW{EL8Nl3D>qQ0P- zl+v8UDmRs}KHnNpG^5DEPa1SBElMX=>dNKfdW(#AvRkG{&R```gn6ns-Go==&9o)P~ELF!ZtSU0%#{x7to0>=Kw z_j^dz>y5RB|M8~%ABAj`aBD7S^JcdhA&AH}{7HKI)2-iG%B#Qo6vbcc%|l610oqda z$E25Cd8N=tY_+6P94~L};-rWH`)do+hmYE@(Wibktv|xN-9>Xy)!dUSohF?7@zYez z;kb~a=<+i8=N6+q`m-EnM)l6}Uup}?8OhO8Ov5L6rKf2J5xC#cy>46ih;I;N@{X5> zv9(y%hy>}*Q#@mXnoa6-5zCj1e9vt1Uux;My8cJ!Eqx~&rYr~2dD>`0k*`zOYnm;# z28N8n0*`p;3d&LXKD6!N91A742&Ia0Ye5+QieS%WN!*rgiUcob^q9Qldnm3CK1E%v z<8)bixX_~JYb-x8jwGU%`8Wk6*>#fdotj0WJs3QkepbdVScmnN`Um_v2*6oliu;}P za5mtO`?U0XYbIapF-02fQ<~ZJJ1)Hb`ym;A`{pZqB19$VplWUt`9<5e1UHCJf_&~w zE32oP0-{fSSPO}m*k*bd9}70cE!*6m9e30cVIuIf;c9g(Xq=_JbjTa=`(>FHy2tZKvbDqR)R`Z}?dF|mWj>bFI)|}|Q;&M;bz_>2-Pbgof z*Fc}_zy?B^6BWI%!~&CvUx@L37vnA}xH825C^?*nYI_F->ZV>ocmDHw6(-u%7M9^0 zz;Oaud$^ZF$dU+3gL1s;YVOga%V@cqD9BRj%sw6b9b0nQV_rsCJjr#FnhVEQlkIkN ziYFp?L$-ozCc4sY-Tew=H8%+Fm#CaYz-uWyJww%U19RiirU%E=f?8T^x&)5-?8b8a zq);W)FTcF`5Ju#YK2JAc;9AvZ8lq&wvt`LbLRj^C#3&no(fZ6GVt2lw=Q1N+g3OX>{tR^d!*C*_;et~-gQ z+iT6^%*-A}K^%pbG?&|Zqe}#vZTyN@zTaLeKF(OSKEzS*)ARx5*hnxDPl^36DzJ(7 z7;`j=4?=QwuKw2in+QR}p7Qiv>aYvZGCfq?DMc5#5CHqd2I6M{eActU>BzM5la>mO zBe?&-o0yM|w%idxExD}E1LByw+QUv$^~%dd{Hc2?T3xI1s~3e*`oYoQ?Yn6;(8^Tm z`pC;A6J6e`krvqJ2ZWYdFgB--dX!Xtn-FB#LQ?wP6`z#n>F?|RsanuNmYbLXML{f!_vUgfW(k>)nHWi@ezKqBzX}P*_<^^L3`{kW#VyhqTt(?74qI)N;#lX}L+)e^66`zW&v9@>)M0xyRSJC&L$0c&nP{r0ho z%4%+`>(VPz|l z!+wV-LSuWdmWzxjZ+chZSclE(`2`d_fp7dYv&5*(%JKV{zI$DmmuTi7wzU0s7_Xa_ zeuB2MABw2`-8v`|Cuhj0`sl!uow`TmpxW0OIU5(b!q?uxh5j=3c}tsjTgEHV;pU1l zH-7H-(L@z5m;4I#uy$a8=k$beP@PjGc1fR|>5e5BU>lWGK{3?6f~$T-K=f0UV2FRa zk1KSNBu?kaKOg`uiA1yK#xe^1K+@`Y5Oa)ZyCSsvb^IMLNVw<^O~bOO5dJv%6iJ?gAs>TxWMkV;h-iZ_iN!35!+>*DDV - 3 - - - - - - - diff --git a/docs/_static/speed-showcase.mp4 b/docs/_static/speed-showcase.mp4 deleted file mode 100644 index 439158e3c1c8ea45d189fcd6fda5fe578ef52303..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 94291 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. - -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..8f9ae85 100644 --- a/orx/__init__.py +++ b/orx/__init__.py @@ -1,30 +1,14 @@ -# 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. - -from __future__ import annotations - -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from typing import Final - -__version__: Final[str] = "1.0.0a" -__all__: Final[tuple[str, ...]] = ("__version__",) +""" +orx +~~~ +A simple wrapper for the Discord API. + +:license: MIT +:copyright: 2023 tag-epic +""" + +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 From 9a9da2731ad077a8b57f7483adde0907ca881b84 Mon Sep 17 00:00:00 2001 From: VincentRPS Date: Thu, 20 Jul 2023 21:23:17 +0800 Subject: [PATCH 2/2] chore: add version --- orx/__init__.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/orx/__init__.py b/orx/__init__.py index 8f9ae85..0c54e74 100644 --- a/orx/__init__.py +++ b/orx/__init__.py @@ -7,6 +7,12 @@ :copyright: 2023 tag-epic """ +from typing import Literal + + +__version__: Literal['0.1.0'] = '0.1.0' + + from .bot import * from .events import * from .flags import *