This repository has been archived by the owner on Jul 10, 2022. It is now read-only.
forked from udf/uniborg
-
Notifications
You must be signed in to change notification settings - Fork 446
/
uniborg.py
112 lines (88 loc) · 3.59 KB
/
uniborg.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import asyncio
import importlib.util
import logging
import os
from pathlib import Path
from telethon import TelegramClient
import telethon.utils
import telethon.events
from .storage import Storage
from . import hacks
# the secret configuration specific things
ENV = bool(os.environ.get("ENV", False))
if ENV:
from sample_config import Config
else:
from config import Config
class Uniborg(TelegramClient):
def __init__(
self, session, *, plugin_path="plugins", storage=None,
bot_token=None, **kwargs):
# TODO: handle non-string session
#
# storage should be a callable accepting plugin name -> Storage object.
# This means that using the Storage type as a storage would work too.
self._name = session
self.storage = storage or (lambda n: Storage(Path("data") / n))
self._logger = logging.getLogger(session)
self._plugins = {}
self._plugin_path = plugin_path
kwargs = {
"api_id": 6, "api_hash": "eb06d4abfb49dc3eeb1aeb98ae0f581e",
**kwargs}
super().__init__(session, **kwargs)
# This is a hack, please avert your eyes
# We want this in order for the most recently added handler to take
# precedence
self._event_builders = hacks.ReverseList()
self.loop.run_until_complete(self._async_init(bot_token=bot_token))
core_plugin = Path(__file__).parent / "_core.py"
self.load_plugin_from_file(core_plugin)
for p in Path().glob(f"{self._plugin_path}/*.py"):
self.load_plugin_from_file(p)
async def _async_init(self, **kwargs):
print(self)
await self.start(**kwargs)
self.me = await self.get_me()
self.uid = telethon.utils.get_peer_id(self.me)
self.verson = "20.10.2018 09:30:45"
def load_plugin(self, shortname):
self.load_plugin_from_file(f"{self._plugin_path}/{shortname}.py")
def load_plugin_from_file(self, path):
path = Path(path)
shortname = path.stem
name = f"_UniborgPlugins.{self._name}.{shortname}"
spec = importlib.util.spec_from_file_location(name, path)
mod = importlib.util.module_from_spec(spec)
mod.borg = self
mod.logger = logging.getLogger(shortname)
mod.storage = self.storage(f"{self._name}/{shortname}")
# declare Config to be accessible by all modules
mod.Config = Config
spec.loader.exec_module(mod)
self._plugins[shortname] = mod
self._logger.info(f"Successfully loaded plugin {shortname}")
def remove_plugin(self, shortname):
name = self._plugins[shortname].__name__
for i in reversed(range(len(self._event_builders))):
ev, cb = self._event_builders[i]
if cb.__module__ == name:
del self._event_builders[i]
del self._plugins[shortname]
self._logger.info(f"Removed plugin {shortname}")
def await_event(self, event_matcher, filter=None):
fut = asyncio.Future()
@self.on(event_matcher)
async def cb(event):
try:
if filter is None or await filter(event):
fut.set_result(event)
except telethon.events.StopPropagation:
fut.set_result(event)
raise
fut.add_done_callback(
lambda _: self.remove_event_handler(cb, event_matcher))
return fut