import aiohttp as ah import time import asyncio import datetime import traceback from dataclasses import dataclass from asyncio import iscoroutinefunction func=type(lambda:1) # Gross, but I can't actually find it. # And yes, lamdas are too. tracing=False def trace(*msg): if tracing: print(datetime.datetime.now(),*msg) class ChatClient(): def __init__(self,homeserver,token): self.event_queue=asyncio.Queue() #Contains Events. Everything in here must be an Event. self.listeners=[] self.timers=[] def addlistener(self,name=None,match=None): if isinstance(name,func) and match==None: match=name; name=None def __wrap__(funky): self.listeners.append(Listener(name,match,funky)) return funky def loop(timer=0): def _loop(funky): @functools.wraps(funky) async def _wrapper(*args,**kwargs): while True: try: await funky(*args,**kwargs) except Exception: open('error '+str(datetime.datetime.now()),'w').write(traceback.format_exc()) await asyncio.sleep(timer) self.timers.append(_wrapper) return _wrapper return _loop async def process_queue(self): item=await self.event_queue.get(): for listener in self.listeners: if listener==item: await listener(item) @dataclass class Event(): event_type:str data:Object=None raw_data:dict=None outbound:bool=False class Listener(): def __init__(self,name,match,function): self.name=name or function.__name__ self.match=match self._matchstr=isinstance(match,str) self.function=function self._async=iscoroutinefunction(function) async def __call__(self,*args,**kwargs): if not self._async: return self.function(*args,**kwargs) return await self.function(*args,**kwargs) def __eq__(self,other): if isinstance(other,Event): if self._matchstr: return self.match==other.event_type return self.match(other) # If it's not a string, assume it's a callable. else: return super.__eq__(self,other) def __str__(self): return self.name