readme
and some untested `exact` and `flag` code also
This commit is contained in:
parent
5f49cd7f46
commit
da1d9a23d6
@ -1,2 +1,3 @@
|
||||
# v25
|
||||
|
||||
replace public keys in `dev-config.json` and `staging-config.json` with your own to allow messaging
|
||||
|
@ -1,6 +1,6 @@
|
||||
__all__ = ('Flags',)
|
||||
import nacl.hash
|
||||
|
||||
Q_FLAG = '<?>'
|
||||
__all__ = ('Flags',)
|
||||
|
||||
|
||||
class Flags:
|
||||
@ -9,14 +9,17 @@ class Flags:
|
||||
def __init__(self, flags: str):
|
||||
self.flags: str = flags
|
||||
|
||||
def quable(self) -> bool:
|
||||
return Q_FLAG in self.flags
|
||||
def hash(self):
|
||||
return nacl.hash.sha256(self.flags.encode()).decode()
|
||||
|
||||
def deq(self) -> str:
|
||||
return Flags(self.flags.replace(Q_FLAG, '')).deq() if self.quable() else self.flags
|
||||
def joint(self, flags: str):
|
||||
return flags.startswith(self.hash())
|
||||
|
||||
def enq(self) -> str:
|
||||
return self.flags if self.quable() else self.flags + Q_FLAG
|
||||
def join(self, flags: str):
|
||||
h = self.hash()
|
||||
if flags.startswith(h):
|
||||
return flags
|
||||
return h + flags
|
||||
|
||||
|
||||
Flags.default = Flags('<unedited>').enq()
|
||||
Flags.default = '<unedited>'
|
||||
|
@ -95,7 +95,7 @@ class Message:
|
||||
def edit(self, pcontent: bytes) -> 'Message':
|
||||
return Message(self.sfrom, self.sto, self.idnonce, None,
|
||||
Encoding.nonce(), pcontent, None,
|
||||
Flags(self.flags.replace('<unedited>', '<edited>')).enq()).sealed()
|
||||
self.flags.replace('<unedited>', '<edited>')).sealed()
|
||||
|
||||
def edit_(self):
|
||||
return self.flags_(self.flags)
|
||||
|
@ -258,30 +258,36 @@ class DBStorage(PushStorage):
|
||||
),
|
||||
))
|
||||
query: Query = cquery
|
||||
if 'ts' in params:
|
||||
if '>' in params:
|
||||
query = query.filter(Msg.ts > params['ts']['>'])
|
||||
if '<' in params:
|
||||
query = query.filter(Msg.ts < params['ts']['<'])
|
||||
if params.get('before'):
|
||||
query = query.filter(Msg.oid < cquery.filter(Msg.idn == Encoding.decode(params['before'])).one().oid)
|
||||
if params.get('after'):
|
||||
query = query.filter(Msg.oid > cquery.filter(Msg.idn == Encoding.decode(params['after'])).one().oid)
|
||||
if params.get('exact'):
|
||||
query = query.filter_by(idn=Encoding.decode(params['exact']))
|
||||
query = query.filter_by(idn=Encoding.decode(params['exact']), sf=pair[0].vkey.encode())
|
||||
for flag in params.get('flags', ()):
|
||||
query = query.filter(Msg.flags.contains(flag))
|
||||
query = query.order_by(Msg.oid.desc())
|
||||
if 'limit' in params:
|
||||
query = query.limit(params['limit'])
|
||||
return map(Msg.to_message, list(query.from_self().order_by(Msg.oid)))
|
||||
res = map(Msg.to_message, list(query.from_self().order_by(Msg.oid)))
|
||||
if 'edit_' in params:
|
||||
res = (m.edit_() for m in res)
|
||||
return res
|
||||
|
||||
def exact(self, sfrom: Subject, sto: Subject, idnonce: bytes, editnonce: Optional[bytes]) -> Optional[Message]:
|
||||
with closing(self.Session()) as session:
|
||||
query: Query = session.query(Msg)
|
||||
query = query.filter_by(sf=sfrom, st=sto, idn=idnonce)
|
||||
if editnonce:
|
||||
query = query.filter_by(en=editnonce)
|
||||
msg: Optional[Msg] = query.one_or_none()
|
||||
return msg or msg.to_message()
|
||||
|
||||
def flags(self, m: Message, flags: str):
|
||||
assert not Flags(flags).quable(), 'flags misuse'
|
||||
with closing(self.Session()) as session:
|
||||
msg: Msg = self.one_alike(session, m)
|
||||
assert msg.en == m.editnonce, 'flags misuse'
|
||||
assert Flags(msg.flags).quable(), 'flags misuse'
|
||||
assert Flags(msg.flags).joint(flags)
|
||||
msg.flags = flags
|
||||
session.commit()
|
||||
|
||||
|
@ -33,6 +33,10 @@ class SecureStorage(PushStorage):
|
||||
assert self.subject in pair, self.asrt()
|
||||
return self.storage.pull(pair, params)
|
||||
|
||||
def exact(self, sfrom: Subject, sto: Subject, idnonce: bytes, editnonce: Optional[bytes]) -> Optional[Message]:
|
||||
assert self.subject in (sfrom, sto)
|
||||
return self.storage.exact(sfrom, sto, idnonce, editnonce)
|
||||
|
||||
def flags(self, m: Message, flags: str):
|
||||
assert self.subject in m.pair, self.asrt()
|
||||
return self.storage.flags(m, flags)
|
||||
|
@ -21,6 +21,9 @@ class AbstractStorage(ABC):
|
||||
def pull(self, pair: Tuple[Subject, Subject], params: Optional[dict] = None) -> Iterable[Message]:
|
||||
raise NotImplementedError
|
||||
|
||||
def exact(self, sfrom: Subject, sto: Subject, idnonce: bytes, editnonce: Optional[bytes]) -> Optional[Message]:
|
||||
raise NotImplementedError
|
||||
|
||||
def flags(self, m: Message, flags: str):
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -42,6 +42,9 @@ class RemoteStorage(PushStorage):
|
||||
return map(Message.loads,
|
||||
self.req('pull', {'params': params, 'pair': [subject.dumps() for subject in pair]}))
|
||||
|
||||
def exact(self, sfrom: Subject, sto: Subject, idnonce: bytes, editnonce: Optional[bytes]) -> Optional[Message]:
|
||||
raise NotImplementedError
|
||||
|
||||
def flags(self, m: Message, flags: str):
|
||||
self.req('flags', {'m': m.dumps(), 'flags': flags})
|
||||
|
||||
@ -50,6 +53,13 @@ class RemoteStorage(PushStorage):
|
||||
self.req('events', {'sfrom': sfrom.dumps(), 'sto': sto.dumps(),
|
||||
'after': Encoding.encode(after)})]
|
||||
|
||||
def typing(self, sfrom: Subject, sto: Subject, last: float) -> float:
|
||||
return self.req('typing', {
|
||||
'sfrom': sfrom.dumps(),
|
||||
'sto': sto.dumps(),
|
||||
'last': last
|
||||
})
|
||||
|
||||
def subscribe(self, subject: Subject, subscription: dict):
|
||||
self.req('subscribe', {
|
||||
'subject': subject.dumps(),
|
||||
|
Loading…
Reference in New Issue
Block a user