kopia lustrzana https://gitlab.com/marnanel/chapeau
rodzic
a2c02abc2c
commit
677f704db1
|
@ -1,5 +1,74 @@
|
|||
def flavour_to_message(flavour):
|
||||
pass
|
||||
|
||||
assert 'type' in flavour, flavour
|
||||
result = {}
|
||||
|
||||
if flavour['type']=='follow':
|
||||
result = {
|
||||
"actor": "https://them.example.org/users/them",
|
||||
"id": "https://them.example.org/c9876",
|
||||
"object": "https://us.example.org/users/us",
|
||||
"type": "Follow",
|
||||
}
|
||||
elif flavour['type']=='unfollow':
|
||||
result = {
|
||||
"actor": "https://us.example.org/users/them",
|
||||
"id": "https://us.example.org/c5678",
|
||||
"object": {
|
||||
"actor": "https://them.example.org/users/them",
|
||||
"id": "https://them.example.org/c9876",
|
||||
"object": "https://us.example.org/users/us",
|
||||
"type": "Follow",
|
||||
},
|
||||
"type": "Undo",
|
||||
}
|
||||
elif flavour['type']=='post':
|
||||
result = {
|
||||
"actor": flavour['from'],
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
],
|
||||
"cc": [
|
||||
],
|
||||
"id": flavour['activity-id'],
|
||||
"object": {
|
||||
"atomUri": flavour['atom'],
|
||||
"attachment": [],
|
||||
"attributedTo": flavour['from'],
|
||||
"cc": [
|
||||
],
|
||||
"content": (
|
||||
flavour['content'],
|
||||
),
|
||||
"contentMap": {
|
||||
# XXX do this properly
|
||||
"en": flavour['content'],
|
||||
},
|
||||
"conversation": (
|
||||
"tag:them.example.org,2019-04-04:objectId=13169876:"
|
||||
"objectType=Conversation"
|
||||
),
|
||||
"id": flavour['content-id'],
|
||||
"published": flavour['date'],
|
||||
"sensitive": False,
|
||||
"summary": None,
|
||||
"tag": [
|
||||
],
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type": "Note",
|
||||
"url": flavour['content-id'],
|
||||
},
|
||||
"published": flavour['date'],
|
||||
"type": "Create",
|
||||
}
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unknown flavour type: {flavour['type']}"
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
def message_to_flavour(message):
|
||||
pass
|
||||
|
|
|
@ -1,22 +1,32 @@
|
|||
import os
|
||||
import sqlite3
|
||||
import random
|
||||
import string
|
||||
import logging
|
||||
import uuid
|
||||
|
||||
DB_DIR = '/var/spool/kepi'
|
||||
DB_FILENAME = 'kepi.sqlite3'
|
||||
|
||||
STATES = {'unverified', 'inbox', 'received',
|
||||
'outbox', 'sent', 'gone',
|
||||
'errors',
|
||||
}
|
||||
STATES = {
|
||||
'U': 'unverified',
|
||||
'I': 'inbox',
|
||||
'R': 'received',
|
||||
'O': 'outbox',
|
||||
'S': 'sent',
|
||||
'Z': 'gone',
|
||||
'X': 'errors',
|
||||
}
|
||||
|
||||
print(dir())
|
||||
|
||||
TABLE_CREATION = [
|
||||
(
|
||||
'create table message (local_id, content, state)'
|
||||
'create table message ('
|
||||
'uuid varchar(36), '
|
||||
'state varchar(1), '
|
||||
'content varchar'
|
||||
')'
|
||||
),
|
||||
'create table waiting_on (url, local_id)',
|
||||
]
|
||||
|
||||
logger = logging.getLogger('kepi.daemon')
|
||||
|
@ -63,54 +73,47 @@ class Spool:
|
|||
for sql in TABLE_CREATION:
|
||||
self._db_exec(sql, cu=cu, ignore_errors=True)
|
||||
|
||||
def _make_local_id(self):
|
||||
result = ''.join([
|
||||
random.choice(string.ascii_letters)
|
||||
for i in range(8)
|
||||
])
|
||||
return result
|
||||
|
||||
def _make_spooledfile_object(self,
|
||||
local_id,
|
||||
uuid,
|
||||
message,
|
||||
state,
|
||||
):
|
||||
result = SpooledFile.__new__(SpooledFile)
|
||||
result._spool = self
|
||||
result._local_id = local_id
|
||||
result._uuid = uuid
|
||||
result._message = message
|
||||
return result
|
||||
|
||||
def add_incoming(self,
|
||||
message,
|
||||
starting_state = 'unverified',
|
||||
starting_state = 'U',
|
||||
):
|
||||
assert isinstance(message, str)
|
||||
assert starting_state in STATES
|
||||
|
||||
local_id = self._make_local_id()
|
||||
our_uuid = str(uuid.uuid4())
|
||||
|
||||
self._db_exec(
|
||||
'insert into message values (?, ?, ?)',
|
||||
'insert into message (uuid, content, state) values (?, ?, ?)',
|
||||
(
|
||||
local_id,
|
||||
our_uuid,
|
||||
message,
|
||||
starting_state,
|
||||
),
|
||||
)
|
||||
return self._make_spooledfile_object(
|
||||
local_id = local_id,
|
||||
uuid = our_uuid,
|
||||
message = message,
|
||||
state = starting_state,
|
||||
)
|
||||
|
||||
def items(self):
|
||||
for local_id, content, state in self._db_exec(
|
||||
'select local_id, content, state from message'
|
||||
for uuid, content, state in self._db_exec(
|
||||
'select uuid, content, state from message'
|
||||
):
|
||||
yield (local_id,
|
||||
yield (uuid,
|
||||
self._make_spooledfile_object(
|
||||
local_id = local_id,
|
||||
uuid = uuid,
|
||||
message = content,
|
||||
state = state,
|
||||
))
|
||||
|
@ -126,9 +129,9 @@ class SpooledFile:
|
|||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, str):
|
||||
return self._local_id == other
|
||||
return self._uuid == other
|
||||
elif isinstance(other, SpooledFile):
|
||||
return self._local_id == other._local_id
|
||||
return self._uuid == other._uuid
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -146,8 +149,8 @@ class SpooledFile:
|
|||
@property
|
||||
def state(self):
|
||||
found = self._spool._db_exec(
|
||||
'select state from message where local_id=?',
|
||||
(self._local_id,),
|
||||
'select state from message where uuid=?',
|
||||
(self._uuid,),
|
||||
).fetchone()
|
||||
return found[0]
|
||||
|
||||
|
@ -157,13 +160,13 @@ class SpooledFile:
|
|||
raise ValueError(f"{v} is not a state (they are {STATES})")
|
||||
assert v in STATES
|
||||
self._spool._db_exec(
|
||||
'update message set state=? where local_id=?',
|
||||
(v, self._local_id,),
|
||||
'update message set state=? where uuid=?',
|
||||
(v, self._uuid,),
|
||||
)
|
||||
|
||||
@property
|
||||
def local_id(self):
|
||||
return self._local_id
|
||||
def uuid(self):
|
||||
return self._uuid
|
||||
|
||||
def __repr__(self):
|
||||
return f'[spooled file {self.local_id}]'
|
||||
return f'[spooled file {self.uuid}]'
|
||||
|
|
|
@ -3,6 +3,7 @@ wheel
|
|||
django
|
||||
requests
|
||||
requests-http-signature
|
||||
wrapt>=1.14.0
|
||||
cryptography
|
||||
pillow
|
||||
celery>4.0.0
|
||||
|
|
|
@ -25,7 +25,7 @@ def test_spool_add_incoming():
|
|||
)
|
||||
assert f.spool==ts
|
||||
assert f.message == TEST_STRING
|
||||
assert f.state == 'unverified'
|
||||
assert f.state == 'U'
|
||||
|
||||
assert len(list(ts.items()))==1
|
||||
|
||||
|
@ -42,7 +42,7 @@ def test_spool_add_incoming():
|
|||
found.spool = None
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
found.local_id = None
|
||||
found.uuid = None
|
||||
|
||||
with pytest.raises(AttributeError):
|
||||
found.message = None
|
||||
|
@ -56,11 +56,11 @@ def test_spool_change_state():
|
|||
retrieved_id, retrieved = list(ts.items())[0]
|
||||
|
||||
assert retrieved==stored
|
||||
assert retrieved_id == retrieved.local_id
|
||||
assert retrieved.state == 'unverified'
|
||||
assert retrieved_id == retrieved.uuid
|
||||
assert retrieved.state == 'U'
|
||||
|
||||
retrieved.state = 'inbox'
|
||||
assert retrieved.state == 'inbox'
|
||||
retrieved.state = 'I'
|
||||
assert retrieved.state == 'I'
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
retrieved.state = 'wombat'
|
||||
|
|
Ładowanie…
Reference in New Issue