Still splitting matrix out from corelib

This commit is contained in:
Zergling_man 2022-08-10 00:00:55 +10:00
parent 80856ef17d
commit 9dd3b82bf8
7 changed files with 51 additions and 55 deletions

View File

@ -3,7 +3,8 @@ import time
import asyncio
import datetime
import traceback
from .utils import Event,Listener
from dataclasses import dataclass
from asyncio import iscoroutinefunction
func=type(lambda:1) # Gross, but I can't actually find it.
# And yes, lamdas are <class 'function'> too.
@ -12,26 +13,12 @@ tracing=False
def trace(*msg):
if tracing: print(datetime.datetime.now(),*msg)
class MatrixClient():
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=[]
async def request(self,endpoint='sync',method='GET', ver=0,headers={} *args,**kwargs):
async with self.session.request(method, f'{self.baseurl}/r{ver}/{endpoint}', headers=headers|{'Authorization':f'Bearer {self.token}'}, *args,**kwargs) as fetched:
if fetched.status_code!=200: raise Exception('fix ur shit')
try: return await fetched.json()
except JSONDecodeError: pass # TODO: Figure out what this is called
# This function just dumps /sync blobs in the event queue as a raw event.
# ALL handling is deferred to handlers.
# ... Except updating the since token. That's important to do here to guarantee that it never calls with the same token twice.
async def sync(self):
blob=await self.request(params={'timeout':30000,'since':self.since})
self.since=blob['next_batch']
self.event_queue.put(Event('m.sync',None,blob))
def addlistener(self,name=None,match=None):
if isinstance(name,func) and match==None: match=name; name=None
def __wrap__(funky):
@ -55,4 +42,29 @@ class MatrixClient():
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

View File

@ -1,5 +1,6 @@
from .utils import Listener as _l, Event as _e, get_or_create as goc
from .utils import get_or_create as goc
import .models
from .chatlib import Listener as _l, Event as _e
# Default handlers will be given two parts each:
# 1) Mould the raw event into a parsed event (update internal state)

5
matrixapi.py Normal file
View File

@ -0,0 +1,5 @@
async def request(self,endpoint='sync',method='GET', ver=0,headers={} *args,**kwargs):
async with self.session.request(method, f'{self.baseurl}/r{ver}/{endpoint}', headers=headers|{'Authorization':f'Bearer {self.token}'}, *args,**kwargs) as fetched:
if fetched.status_code!=200: raise Exception('fix ur shit')
try: return await fetched.json()
except JSONDecodeError: pass # TODO: Figure out what this is called

View File

@ -1,4 +1,4 @@
from .matrix import *
from .chatlib import *
import .listeners
real_listeners=dict(filter(lambda x:isinstance(x,Listener),listeners.__dict__.items()))

View File

@ -1,6 +1,6 @@
from .utils import redc
from dataclasses import dataclass, field
@redc
@dataclass
class Account():
mxid:str
username:str
@ -9,7 +9,7 @@ class Account():
nickname:str=''
rooms:List[Room]=field(default_factory=list)
@redc
@dataclass
class Room():
id:str
name:str=''
@ -17,23 +17,23 @@ class Room():
parents:List[Space]=field(default_factory=list)
messages:List[Message]=field(default_factory=list)
@redc
@dataclass
class Space(Room):
children:List[Room]=field(default_factory=list)
@redc
@dataclass
class Message():
id:str
contents:str
author:Member
@redc
@dataclass
class User():
mxid:str
nick:str
avatar:str
@redc
@dataclass
class Member(User):
room_av:str
room_nick:str

7
timers.py Normal file
View File

@ -0,0 +1,7 @@
# This function just dumps /sync blobs in the event queue as a raw event.
# ALL handling is deferred to handlers.
# ... Except updating the since token. That's important to do here to guarantee that it never calls with the same token twice.
async def sync(self):
blob=await self.request(params={'timeout':30000,'since':self.since})
self.since=blob['next_batch']
self.event_queue.put(Event('m.sync',None,blob))

View File

@ -1,32 +1,3 @@
from dataclasses import dataclass, field, _MISSING_TYPE as mt
from asyncio import iscoroutinefunction
@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
def get_or_create(needle,haystack,default):
"""
This is a wrapper for filter that can add stuff. Nothing special. Needle is a function, default isn't. Haystack is a list. I might fix that later.