summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--python-cmyui.spec522
-rw-r--r--sources1
3 files changed, 524 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..fa47add 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/cmyui-1.9.3.tar.gz
diff --git a/python-cmyui.spec b/python-cmyui.spec
new file mode 100644
index 0000000..284c913
--- /dev/null
+++ b/python-cmyui.spec
@@ -0,0 +1,522 @@
+%global _empty_manifest_terminate_build 0
+Name: python-cmyui
+Version: 1.9.3
+Release: 1
+Summary: Tools I find myself constantly rebuilding and reusing.
+License: MIT
+URL: https://github.com/cmyui/cmyui_pkg
+Source0: https://mirrors.nju.edu.cn/pypi/web/packages/bd/a8/a30468b80172024715b8d34a557cf1263f5decbc3e4c7efc16e835c4a130/cmyui-1.9.3.tar.gz
+BuildArch: noarch
+
+
+%description
+# Generic multipurpose library for the average cmyui (and alike)
+
+## The good stuff
+
+- Async multi-domain http server & sql wrapper
+- Simple logging utilities, for printing in colour w/ timestamps.
+- osu! tools, such as replay and beatmap parsers, and more.
+- Simple discord webhook wrapper, likely going to grow into more.
+
+```py
+# Example of how to use some of the stuff.
+
+import asyncio
+import time
+import re
+from typing import NoReturn
+from typing import Optional
+
+from cmyui.logging import Ansi
+from cmyui.logging import log
+from cmyui.logging import Rainbow
+from cmyui.logging import RGB
+from cmyui.mysql import AsyncSQLPool
+from cmyui.version import Version
+from cmyui.utils import rstring
+from cmyui.web import Connection
+from cmyui.web import Domain
+from cmyui.web import Server
+from pathlib import Path
+
+version = Version(1, 0, 3)
+debug = True
+
+sql: Optional[AsyncSQLPool] = None
+players = [just imagine this is a list with
+ player objects on a game server]
+
+# server has built-in gzip compression support,
+# simply pass the level you'd like to use (1-9).
+app = Server(name=f'Gameserver v{version}',
+ gzip=4, verbose=debug)
+
+# usually, domains are defined externally in
+# other files, generally in a 'domains' folder.
+domain1 = Domain('osu.ppy.sh')
+domain2 = Domain('cmyui.codes')
+
+# domains can then have their routes defined
+# in similar syntax to many other popular web
+# frameworks. these domains can be defined
+# either with a plaintext url route, or using
+# regular expressions, allowing for much
+# greater complexity.
+@domain1.route('/ingame/getfriends.php')
+async def ingame_getfriends(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers:
+ # returning a tuple of (int, bytes) allows
+ # for customization of the return code.
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ # returning bytes alone will simply use 200.
+ return '\n'.join(players[token].friends).encode()
+
+# methods can be specified as a list in the route definition
+@domain1.route('/ingame/screenshot.php', methods=['POST'])
+async def ingame_screenshot(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers or 'ss' not in conn.files:
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ p = players[token]
+ ss_file = Path.cwd() / 'ss' / rstring(8)
+
+ with open(ss_file, 'wb') as f:
+ f.write(conn.files['ss'])
+
+ # there are three colour options available,
+ log(f'{p!r} uploaded {ss_file}.', Ansi.LBLUE)
+ log(f'{p!r} uploaded {ss_file}.', RGB(0x77ffdd))
+ log(f'{p!r} uploaded {ss_file}.', Rainbow)
+
+ return b'Uploaded'
+
+@domain2.route(re.compile('^/u/(?P<id>\d{1,10}$'))
+async def user_profile(conn: Connection) -> Optional[bytes]:
+ ... # TODO: templates implementation?
+
+# finally, the domains themselves
+# can be added to the server object.
+app.add_domains({domain1, domain2})
+
+# and the server allows for any number
+# of async callables to be enqueued as
+# tasks once the server is started up.
+async def on_start():
+ # this should probably be
+ # in a config somewhere lol
+ sql_info = {
+ 'db': 'cmyui',
+ 'host': 'localhost',
+ 'password': 'lol123',
+ 'user': 'cmyui'
+ }
+
+ global sql
+ sql = AsyncSQLPool()
+ await sql.connect(sql_info)
+
+async def disconnect_inactive_players() -> NoReturn:
+ ping_timeout = 120
+ global players
+
+ while True:
+ for p in players:
+ if time.time() - p.last_recv_time > ping_timeout:
+ await p.logout()
+
+ await asyncio.sleep(ping_timeout)
+
+app.add_task(on_start())
+app.add_tasks({on_start(), disconnect_inactive_players()})
+
+# both inet & unix sockets are supported.
+server_addr = ('127.0.0.1', 5001) # inet4
+server_addr = '/tmp/myserver.sock' # unix
+
+# then, the server can be run; this is a blocking
+# call after which the server will indefinitely
+# continue to listen for and handle connections.
+app.run(server_addr)
+
+# and voila, you have an async server. the server
+# will use uvloop if you have it installed; if you
+# don't know about the project, consider checking
+# out https://github.com/MagicStack/uvloop.
+
+# cheers B)
+
+
+
+
+%package -n python3-cmyui
+Summary: Tools I find myself constantly rebuilding and reusing.
+Provides: python-cmyui
+BuildRequires: python3-devel
+BuildRequires: python3-setuptools
+BuildRequires: python3-pip
+%description -n python3-cmyui
+# Generic multipurpose library for the average cmyui (and alike)
+
+## The good stuff
+
+- Async multi-domain http server & sql wrapper
+- Simple logging utilities, for printing in colour w/ timestamps.
+- osu! tools, such as replay and beatmap parsers, and more.
+- Simple discord webhook wrapper, likely going to grow into more.
+
+```py
+# Example of how to use some of the stuff.
+
+import asyncio
+import time
+import re
+from typing import NoReturn
+from typing import Optional
+
+from cmyui.logging import Ansi
+from cmyui.logging import log
+from cmyui.logging import Rainbow
+from cmyui.logging import RGB
+from cmyui.mysql import AsyncSQLPool
+from cmyui.version import Version
+from cmyui.utils import rstring
+from cmyui.web import Connection
+from cmyui.web import Domain
+from cmyui.web import Server
+from pathlib import Path
+
+version = Version(1, 0, 3)
+debug = True
+
+sql: Optional[AsyncSQLPool] = None
+players = [just imagine this is a list with
+ player objects on a game server]
+
+# server has built-in gzip compression support,
+# simply pass the level you'd like to use (1-9).
+app = Server(name=f'Gameserver v{version}',
+ gzip=4, verbose=debug)
+
+# usually, domains are defined externally in
+# other files, generally in a 'domains' folder.
+domain1 = Domain('osu.ppy.sh')
+domain2 = Domain('cmyui.codes')
+
+# domains can then have their routes defined
+# in similar syntax to many other popular web
+# frameworks. these domains can be defined
+# either with a plaintext url route, or using
+# regular expressions, allowing for much
+# greater complexity.
+@domain1.route('/ingame/getfriends.php')
+async def ingame_getfriends(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers:
+ # returning a tuple of (int, bytes) allows
+ # for customization of the return code.
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ # returning bytes alone will simply use 200.
+ return '\n'.join(players[token].friends).encode()
+
+# methods can be specified as a list in the route definition
+@domain1.route('/ingame/screenshot.php', methods=['POST'])
+async def ingame_screenshot(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers or 'ss' not in conn.files:
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ p = players[token]
+ ss_file = Path.cwd() / 'ss' / rstring(8)
+
+ with open(ss_file, 'wb') as f:
+ f.write(conn.files['ss'])
+
+ # there are three colour options available,
+ log(f'{p!r} uploaded {ss_file}.', Ansi.LBLUE)
+ log(f'{p!r} uploaded {ss_file}.', RGB(0x77ffdd))
+ log(f'{p!r} uploaded {ss_file}.', Rainbow)
+
+ return b'Uploaded'
+
+@domain2.route(re.compile('^/u/(?P<id>\d{1,10}$'))
+async def user_profile(conn: Connection) -> Optional[bytes]:
+ ... # TODO: templates implementation?
+
+# finally, the domains themselves
+# can be added to the server object.
+app.add_domains({domain1, domain2})
+
+# and the server allows for any number
+# of async callables to be enqueued as
+# tasks once the server is started up.
+async def on_start():
+ # this should probably be
+ # in a config somewhere lol
+ sql_info = {
+ 'db': 'cmyui',
+ 'host': 'localhost',
+ 'password': 'lol123',
+ 'user': 'cmyui'
+ }
+
+ global sql
+ sql = AsyncSQLPool()
+ await sql.connect(sql_info)
+
+async def disconnect_inactive_players() -> NoReturn:
+ ping_timeout = 120
+ global players
+
+ while True:
+ for p in players:
+ if time.time() - p.last_recv_time > ping_timeout:
+ await p.logout()
+
+ await asyncio.sleep(ping_timeout)
+
+app.add_task(on_start())
+app.add_tasks({on_start(), disconnect_inactive_players()})
+
+# both inet & unix sockets are supported.
+server_addr = ('127.0.0.1', 5001) # inet4
+server_addr = '/tmp/myserver.sock' # unix
+
+# then, the server can be run; this is a blocking
+# call after which the server will indefinitely
+# continue to listen for and handle connections.
+app.run(server_addr)
+
+# and voila, you have an async server. the server
+# will use uvloop if you have it installed; if you
+# don't know about the project, consider checking
+# out https://github.com/MagicStack/uvloop.
+
+# cheers B)
+
+
+
+
+%package help
+Summary: Development documents and examples for cmyui
+Provides: python3-cmyui-doc
+%description help
+# Generic multipurpose library for the average cmyui (and alike)
+
+## The good stuff
+
+- Async multi-domain http server & sql wrapper
+- Simple logging utilities, for printing in colour w/ timestamps.
+- osu! tools, such as replay and beatmap parsers, and more.
+- Simple discord webhook wrapper, likely going to grow into more.
+
+```py
+# Example of how to use some of the stuff.
+
+import asyncio
+import time
+import re
+from typing import NoReturn
+from typing import Optional
+
+from cmyui.logging import Ansi
+from cmyui.logging import log
+from cmyui.logging import Rainbow
+from cmyui.logging import RGB
+from cmyui.mysql import AsyncSQLPool
+from cmyui.version import Version
+from cmyui.utils import rstring
+from cmyui.web import Connection
+from cmyui.web import Domain
+from cmyui.web import Server
+from pathlib import Path
+
+version = Version(1, 0, 3)
+debug = True
+
+sql: Optional[AsyncSQLPool] = None
+players = [just imagine this is a list with
+ player objects on a game server]
+
+# server has built-in gzip compression support,
+# simply pass the level you'd like to use (1-9).
+app = Server(name=f'Gameserver v{version}',
+ gzip=4, verbose=debug)
+
+# usually, domains are defined externally in
+# other files, generally in a 'domains' folder.
+domain1 = Domain('osu.ppy.sh')
+domain2 = Domain('cmyui.codes')
+
+# domains can then have their routes defined
+# in similar syntax to many other popular web
+# frameworks. these domains can be defined
+# either with a plaintext url route, or using
+# regular expressions, allowing for much
+# greater complexity.
+@domain1.route('/ingame/getfriends.php')
+async def ingame_getfriends(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers:
+ # returning a tuple of (int, bytes) allows
+ # for customization of the return code.
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ # returning bytes alone will simply use 200.
+ return '\n'.join(players[token].friends).encode()
+
+# methods can be specified as a list in the route definition
+@domain1.route('/ingame/screenshot.php', methods=['POST'])
+async def ingame_screenshot(conn: Connection) -> Optional[bytes]:
+ if 'token' not in conn.headers or 'ss' not in conn.files:
+ return (400, b'Bad Request')
+
+ token = conn.headers['token']
+
+ global players
+ if not token in conn.headers:
+ return (401, b'Unauthorized')
+
+ p = players[token]
+ ss_file = Path.cwd() / 'ss' / rstring(8)
+
+ with open(ss_file, 'wb') as f:
+ f.write(conn.files['ss'])
+
+ # there are three colour options available,
+ log(f'{p!r} uploaded {ss_file}.', Ansi.LBLUE)
+ log(f'{p!r} uploaded {ss_file}.', RGB(0x77ffdd))
+ log(f'{p!r} uploaded {ss_file}.', Rainbow)
+
+ return b'Uploaded'
+
+@domain2.route(re.compile('^/u/(?P<id>\d{1,10}$'))
+async def user_profile(conn: Connection) -> Optional[bytes]:
+ ... # TODO: templates implementation?
+
+# finally, the domains themselves
+# can be added to the server object.
+app.add_domains({domain1, domain2})
+
+# and the server allows for any number
+# of async callables to be enqueued as
+# tasks once the server is started up.
+async def on_start():
+ # this should probably be
+ # in a config somewhere lol
+ sql_info = {
+ 'db': 'cmyui',
+ 'host': 'localhost',
+ 'password': 'lol123',
+ 'user': 'cmyui'
+ }
+
+ global sql
+ sql = AsyncSQLPool()
+ await sql.connect(sql_info)
+
+async def disconnect_inactive_players() -> NoReturn:
+ ping_timeout = 120
+ global players
+
+ while True:
+ for p in players:
+ if time.time() - p.last_recv_time > ping_timeout:
+ await p.logout()
+
+ await asyncio.sleep(ping_timeout)
+
+app.add_task(on_start())
+app.add_tasks({on_start(), disconnect_inactive_players()})
+
+# both inet & unix sockets are supported.
+server_addr = ('127.0.0.1', 5001) # inet4
+server_addr = '/tmp/myserver.sock' # unix
+
+# then, the server can be run; this is a blocking
+# call after which the server will indefinitely
+# continue to listen for and handle connections.
+app.run(server_addr)
+
+# and voila, you have an async server. the server
+# will use uvloop if you have it installed; if you
+# don't know about the project, consider checking
+# out https://github.com/MagicStack/uvloop.
+
+# cheers B)
+
+
+
+
+%prep
+%autosetup -n cmyui-1.9.3
+
+%build
+%py3_build
+
+%install
+%py3_install
+install -d -m755 %{buildroot}/%{_pkgdocdir}
+if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi
+if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi
+if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi
+if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi
+pushd %{buildroot}
+if [ -d usr/lib ]; then
+ find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/lib64 ]; then
+ find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/bin ]; then
+ find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+if [ -d usr/sbin ]; then
+ find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst
+fi
+touch doclist.lst
+if [ -d usr/share/man ]; then
+ find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst
+fi
+popd
+mv %{buildroot}/filelist.lst .
+mv %{buildroot}/doclist.lst .
+
+%files -n python3-cmyui -f filelist.lst
+%dir %{python3_sitelib}/*
+
+%files help -f doclist.lst
+%{_docdir}/*
+
+%changelog
+* Wed May 10 2023 Python_Bot <Python_Bot@openeuler.org> - 1.9.3-1
+- Package Spec generated
diff --git a/sources b/sources
new file mode 100644
index 0000000..7197c36
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+8c787f5d9c7f051cc0bd7c8bdaa410e3 cmyui-1.9.3.tar.gz