diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..69f4ba6
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..726c1c5
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..0b48162
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/v6d3vote.iml b/.idea/v6d3vote.iml
new file mode 100644
index 0000000..74d515a
--- /dev/null
+++ b/.idea/v6d3vote.iml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index ecc1362..74d36de 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,4 +1,4 @@
aiohttp~=3.7.4.post0
-discord.py
-git+https://gitea.ongoteam.net/PTV/v6d0auth.git
-git+https://gitea.ongoteam.net/PTV/v6d1tokens.git
+discord.py~=1.7.3
+git+https://gitea.ongoteam.net/PTV/v6d1tokens.git@2dca5338ecec2042f731ff2855225417f66e1372
+git+https://gitea.ongoteam.net/PTV/v6d2ctx.git@087aa39918a147ad9df7de35e6484ccb3efdc6c9
diff --git a/v6d3vote/context.py b/v6d3vote/context.py
deleted file mode 100644
index ed501fe..0000000
--- a/v6d3vote/context.py
+++ /dev/null
@@ -1,102 +0,0 @@
-import asyncio
-import time
-from io import StringIO
-from typing import Union, Optional, Callable, Awaitable
-
-# noinspection PyPackageRequirements
-import discord
-
-usertype = Union[discord.abc.User, discord.user.BaseUser, discord.Member, discord.User]
-
-
-class Context:
- def __init__(self, message: discord.Message):
- self.message: discord.Message = message
- self.channel: discord.abc.Messageable = message.channel
- self.dm_or_text: Union[discord.DMChannel, discord.TextChannel] = message.channel
- self.author: usertype = message.author
- self.content: str = message.content
- self.member: Optional[discord.Member] = message.author if isinstance(message.author, discord.Member) else None
- self.guild: Optional[discord.Guild] = None if self.member is None else self.member.guild
-
- async def reply(self, content=None, **kwargs) -> discord.Message:
- return await self.message.reply(content, mention_author=False, **kwargs)
-
- async def long(self, s: str):
- resio = StringIO(s)
- res = ''
- for line in resio:
- if len(res) + len(line) < 2000:
- res += line
- else:
- await self.reply(res)
- res = line
- if res:
- await self.reply(res)
-
-
-ESCAPED = '`_*\'"\\'
-
-
-def escape(s: str):
- res = StringIO()
- for c in s:
- if c in ESCAPED:
- c = '\\' + c
- res.write(c)
- return res.getvalue()
-
-
-buckets: dict[str, dict[str, Callable[[Context, list[str]], Awaitable[None]]]] = {}
-
-
-def at(bucket: str, name: str):
- def wrap(f: Callable[[Context, list[str]], Awaitable[None]]):
- buckets.setdefault(bucket, {})[name] = f
-
- return f
-
- return wrap
-
-
-class Explicit(Exception):
- def __init__(self, msg: str):
- self.msg = msg
-
-
-class Implicit(Exception):
- pass
-
-
-def of(bucket: str, name: str) -> Callable[[Context, list[str]], Awaitable[None]]:
- try:
- return buckets[bucket][name]
- except KeyError:
- raise Implicit
-
-
-benchmarks: dict[str, dict[str, float]] = {}
-_t = time.perf_counter()
-
-
-class Benchmark:
- def __init__(self, benchmark: str):
- self.benchmark = benchmark
-
- def __enter__(self):
- self.t = time.perf_counter()
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- d = (time.perf_counter() - self.t)
- benchmarks.setdefault(self.benchmark, {'integral': 0.0, 'max': 0.0})
- benchmarks[self.benchmark]['integral'] += d
- benchmarks[self.benchmark]['max'] = max(benchmarks[self.benchmark]['max'], d)
-
-
-async def monitor():
- while True:
- await asyncio.sleep(10)
- dt = time.perf_counter() - _t
- print('Benchmarks:')
- for benchmark, metrics in benchmarks.items():
- print(benchmark, '=', metrics['integral'] / max(dt, .00001), ':', metrics['max'])
diff --git a/v6d3vote/run-bot.py b/v6d3vote/run-bot.py
index 4f5a5eb..acac8a7 100644
--- a/v6d3vote/run-bot.py
+++ b/v6d3vote/run-bot.py
@@ -8,9 +8,9 @@ import discord
from ptvp35 import Db, KVJson
from v6d0auth.config import root
from v6d1tokens.client import request_token
+from v6d2ctx.context import Context, of, at, Implicit, monitor, Explicit
from v6d3vote.config import prefix
-from v6d3vote.context import Context, of, at, Implicit, monitor, Explicit
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)