forked from indymedia/epicyon
Save posts to inbox to a queue
parent
50a2f95c9c
commit
640cf71416
45
daemon.py
45
daemon.py
|
@ -107,12 +107,14 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery
|
https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery
|
||||||
"""
|
"""
|
||||||
if not messageJson.get('type'):
|
if not messageJson.get('type'):
|
||||||
|
if self.server.debug:
|
||||||
|
print('DEBUG: POST to outbox has no "type" parameter')
|
||||||
return False
|
return False
|
||||||
if not messageJson.get('object') and messageJson.get('content'):
|
if not messageJson.get('object') and messageJson.get('content'):
|
||||||
if messageJson['type']!='Create':
|
if messageJson['type']!='Create':
|
||||||
# https://www.w3.org/TR/activitypub/#object-without-create
|
# https://www.w3.org/TR/activitypub/#object-without-create
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG POST to outbox: Adding Create wrapper')
|
print('DEBUG: POST to outbox - adding Create wrapper')
|
||||||
messageJson= \
|
messageJson= \
|
||||||
outboxMessageCreateWrap(self.server.httpPrefix, \
|
outboxMessageCreateWrap(self.server.httpPrefix, \
|
||||||
self.postToNickname, \
|
self.postToNickname, \
|
||||||
|
@ -125,14 +127,14 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
messageJson.get('atomUri') and \
|
messageJson.get('atomUri') and \
|
||||||
messageJson.get('to')):
|
messageJson.get('to')):
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG POST to outbox: Create does not have the required parameters')
|
print('DEBUG: POST to outbox - Create does not have the required parameters')
|
||||||
return False
|
return False
|
||||||
# https://www.w3.org/TR/activitypub/#create-activity-outbox
|
# https://www.w3.org/TR/activitypub/#create-activity-outbox
|
||||||
messageJson['object']['attributedTo']=messageJson['actor']
|
messageJson['object']['attributedTo']=messageJson['actor']
|
||||||
permittedOutboxTypes=['Create','Announce','Like','Follow','Undo','Update','Add','Remove','Block','Delete']
|
permittedOutboxTypes=['Create','Announce','Like','Follow','Undo','Update','Add','Remove','Block','Delete']
|
||||||
if messageJson['type'] not in permittedOutboxTypes:
|
if messageJson['type'] not in permittedOutboxTypes:
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG POST to outbox: '+messageJson['type']+' is not a permitted activity type')
|
print('DEBUG: POST to outbox - '+messageJson['type']+' is not a permitted activity type')
|
||||||
return False
|
return False
|
||||||
if messageJson.get('id'):
|
if messageJson.get('id'):
|
||||||
postId=messageJson['id']
|
postId=messageJson['id']
|
||||||
|
@ -283,12 +285,14 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# if this is a POST to teh outbox then check authentication
|
# if this is a POST to teh outbox then check authentication
|
||||||
self.outboxAuthenticated=False
|
self.outboxAuthenticated=False
|
||||||
self.postToNickname=None
|
self.postToNickname=None
|
||||||
|
|
||||||
if self.path.endswith('/outbox'):
|
if self.path.endswith('/outbox'):
|
||||||
if '/users/' in self.path:
|
if '/users/' in self.path:
|
||||||
if self.headers.get('Authorization'):
|
if self.headers.get('Authorization'):
|
||||||
if authorize(self.server.baseDir,self.path,self.headers['Authorization'],self.server.debug):
|
if authorize(self.server.baseDir,self.path,self.headers['Authorization'],self.server.debug):
|
||||||
self.outboxAuthenticated=True
|
self.outboxAuthenticated=True
|
||||||
self.postToNickname=nickname
|
pathUsersSection=path.split('/users/')[1]
|
||||||
|
self.postToNickname=pathUsersSection.split('/')[0]
|
||||||
# TODO
|
# TODO
|
||||||
print('c2s posts not supported yet')
|
print('c2s posts not supported yet')
|
||||||
self.send_response(405)
|
self.send_response(405)
|
||||||
|
@ -360,9 +364,39 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
pprint(messageJson)
|
pprint(messageJson)
|
||||||
|
|
||||||
|
if not headers.get('keyId'):
|
||||||
|
if self.server.debug:
|
||||||
|
print('DEBUG: POST to inbox has no keyId in header')
|
||||||
|
return
|
||||||
|
|
||||||
if self.server.debug:
|
if self.server.debug:
|
||||||
print('DEBUG: POST create session')
|
print('DEBUG: POST saving to inbox cache')
|
||||||
|
if '/users/' in self.path:
|
||||||
|
pathUsersSection=self.path.split('/users/')[1]
|
||||||
|
if '/' not in pathUsersSection:
|
||||||
|
if self.server.debug:
|
||||||
|
print('DEBUG: This is not a users endpoint')
|
||||||
|
else:
|
||||||
|
self.postToNickname=pathUsersSection.split('/')[0]
|
||||||
|
if self.postToNickname:
|
||||||
|
cacheFilename = \
|
||||||
|
savePostToInboxQueue(self.server.baseDir, \
|
||||||
|
self.server.httpPrefix, \
|
||||||
|
headers['keyId'], \
|
||||||
|
self.postToNickname, \
|
||||||
|
self.server.domain, \
|
||||||
|
messageJson)
|
||||||
|
if cacheFilename:
|
||||||
|
if cacheFilename not in self.server.inboxQueue:
|
||||||
|
self.server.inboxQueue.append(cacheFilename)
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
print('DEBUG: POST to shared inbox')
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
currSessionTime=int(time.time())
|
currSessionTime=int(time.time())
|
||||||
if currSessionTime-self.server.sessionLastUpdate>1200:
|
if currSessionTime-self.server.sessionLastUpdate>1200:
|
||||||
self.server.sessionLastUpdate=currSessionTime
|
self.server.sessionLastUpdate=currSessionTime
|
||||||
|
@ -449,5 +483,6 @@ def runDaemon(domain: str,port=80,httpPrefix='https',fedList=[],useTor=False,deb
|
||||||
httpd.GETbusy=False
|
httpd.GETbusy=False
|
||||||
httpd.POSTbusy=False
|
httpd.POSTbusy=False
|
||||||
httpd.receivedMessage=False
|
httpd.receivedMessage=False
|
||||||
|
httpd.inboxQueue=[]
|
||||||
print('Running ActivityPub daemon on ' + domain + ' port ' + str(port))
|
print('Running ActivityPub daemon on ' + domain + ' port ' + str(port))
|
||||||
httpd.serve_forever()
|
httpd.serve_forever()
|
||||||
|
|
24
inbox.py
24
inbox.py
|
@ -10,6 +10,7 @@ import json
|
||||||
import os
|
import os
|
||||||
import datetime
|
import datetime
|
||||||
from utils import urlPermitted
|
from utils import urlPermitted
|
||||||
|
from utils import createInboxQueueDir
|
||||||
|
|
||||||
def inboxMessageHasParams(messageJson: {}) -> bool:
|
def inboxMessageHasParams(messageJson: {}) -> bool:
|
||||||
"""Checks whether an incoming message contains expected parameters
|
"""Checks whether an incoming message contains expected parameters
|
||||||
|
@ -49,3 +50,26 @@ def validPublishedDate(published) -> bool:
|
||||||
if daysSincePublished>30:
|
if daysSincePublished>30:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def savePostToInboxQueue(baseDir: str,httpPrefix: str,keyId: str,nickname: str, domain: str,postJson: {}) -> str:
|
||||||
|
"""Saves the give json to the inbox queue for the person
|
||||||
|
keyId specifies the actor sending the post
|
||||||
|
"""
|
||||||
|
if ':' in domain:
|
||||||
|
domain=domain.split(':')[0]
|
||||||
|
if not keyId:
|
||||||
|
return None
|
||||||
|
if not postJson.get('id'):
|
||||||
|
return None
|
||||||
|
postId=postJson['id'].replace('/activity','')
|
||||||
|
|
||||||
|
newBufferItem = {
|
||||||
|
'keyId': keyid,
|
||||||
|
'post': postJson
|
||||||
|
}
|
||||||
|
|
||||||
|
inboxQueueDir = createInboxQueueDir(nickname,domain,baseDir)
|
||||||
|
filename=inboxQueueDir+'/'+postId.replace('/','#')+'.json'
|
||||||
|
with open(filename, 'w') as fp:
|
||||||
|
commentjson.dump(newQueueItem, fp, indent=4, sort_keys=False)
|
||||||
|
return filename
|
||||||
|
|
22
utils.py
22
utils.py
|
@ -20,16 +20,26 @@ def getStatusNumber() -> (str,str):
|
||||||
conversationDate=currTime.strftime("%Y-%m-%d")
|
conversationDate=currTime.strftime("%Y-%m-%d")
|
||||||
return statusNumber,published
|
return statusNumber,published
|
||||||
|
|
||||||
def createOutboxDir(nickname: str,domain: str,baseDir: str) -> str:
|
def createPersonDir(nickname: str,domain: str,baseDir: str,dirname: str) -> str:
|
||||||
"""Create an outbox for a person and returns the feed filename and directory
|
"""Create a directory for a person
|
||||||
"""
|
"""
|
||||||
handle=nickname.lower()+'@'+domain.lower()
|
handle=nickname.lower()+'@'+domain.lower()
|
||||||
if not os.path.isdir(baseDir+'/accounts/'+handle):
|
if not os.path.isdir(baseDir+'/accounts/'+handle):
|
||||||
os.mkdir(baseDir+'/accounts/'+handle)
|
os.mkdir(baseDir+'/accounts/'+handle)
|
||||||
outboxDir=baseDir+'/accounts/'+handle+'/outbox'
|
boxDir=baseDir+'/accounts/'+handle+'/'+dirname
|
||||||
if not os.path.isdir(outboxDir):
|
if not os.path.isdir(boxDir):
|
||||||
os.mkdir(outboxDir)
|
os.mkdir(boxDir)
|
||||||
return outboxDir
|
return boxDir
|
||||||
|
|
||||||
|
def createOutboxDir(nickname: str,domain: str,baseDir: str) -> str:
|
||||||
|
"""Create an outbox for a person
|
||||||
|
"""
|
||||||
|
return createPersonDir(nickname,domain,baseDir,'outbox')
|
||||||
|
|
||||||
|
def createInboxQueueDir(nickname: str,domain: str,baseDir: str) -> str:
|
||||||
|
"""Create an inbox queue and returns the feed filename and directory
|
||||||
|
"""
|
||||||
|
return createPersonDir(nickname,domain,baseDir,'queue')
|
||||||
|
|
||||||
def domainPermitted(domain: str, federationList: []):
|
def domainPermitted(domain: str, federationList: []):
|
||||||
if len(federationList)==0:
|
if len(federationList)==0:
|
||||||
|
|
Loading…
Reference in New Issue