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.
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]
app = Server(name=f'Gameserver v{version}',
gzip=4, verbose=debug)
domain1 = Domain('osu.ppy.sh')
domain2 = Domain('cmyui.codes')
@domain1.route('/ingame/getfriends.php')
async def ingame_getfriends(conn: Connection) -> Optional[bytes]:
if 'token' not in conn.headers:
return (400, b'Bad Request')
token = conn.headers['token']
global players
if not token in conn.headers:
return (401, b'Unauthorized')
return '\n'.join(players[token].friends).encode()
@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'])
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]:
...
app.add_domains({domain1, domain2})
async def on_start():
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()})
server_addr = ('127.0.0.1', 5001)
server_addr = '/tmp/myserver.sock'
app.run(server_addr)