forked from indymedia/epicyon
Timeline for DMs
parent
1b66aa0077
commit
97487eeb54
67
daemon.py
67
daemon.py
|
@ -1377,7 +1377,72 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.end_headers()
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
|
||||
# get the inbox for a given person
|
||||
if self.path.endswith('/dm') or '/dm?page=' in self.path:
|
||||
if '/users/' in self.path:
|
||||
if authorized:
|
||||
inboxDMFeed=personBoxJson(self.server.baseDir, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
self.path, \
|
||||
self.server.httpPrefix, \
|
||||
maxPostsInFeed, 'dm', \
|
||||
True,self.server.ocapAlways)
|
||||
if inboxDMFeed:
|
||||
if self._requestHTTP():
|
||||
nickname=self.path.replace('/users/','').replace('/dm','')
|
||||
pageNumber=1
|
||||
if '?page=' in nickname:
|
||||
pageNumber=nickname.split('?page=')[1]
|
||||
nickname=nickname.split('?page=')[0]
|
||||
if pageNumber.isdigit():
|
||||
pageNumber=int(pageNumber)
|
||||
else:
|
||||
pageNumber=1
|
||||
if 'page=' not in self.path:
|
||||
# if no page was specified then show the first
|
||||
inboxDMFeed=personBoxJson(self.server.baseDir, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
self.path+'?page=1', \
|
||||
self.server.httpPrefix, \
|
||||
maxPostsInFeed, 'dm', \
|
||||
True,self.server.ocapAlways)
|
||||
msg=htmlInbox(pageNumber,maxPostsInFeed, \
|
||||
self.server.session, \
|
||||
self.server.baseDir, \
|
||||
self.server.cachedWebfingers, \
|
||||
self.server.personCache, \
|
||||
nickname, \
|
||||
self.server.domain, \
|
||||
self.server.port, \
|
||||
inboxDMFeed, \
|
||||
self.server.allowDeletion, \
|
||||
self.server.httpPrefix, \
|
||||
self.server.projectVersion).encode('utf-8')
|
||||
self._set_headers('text/html',len(msg),cookie)
|
||||
self.wfile.write(msg)
|
||||
else:
|
||||
msg=json.dumps(inboxDMFeed).encode('utf-8')
|
||||
self._set_headers('application/json',len(msg),None)
|
||||
self.wfile.write(msg)
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
else:
|
||||
if self.server.debug:
|
||||
nickname=self.path.replace('/users/','').replace('/dm','')
|
||||
print('DEBUG: '+nickname+ \
|
||||
' was not authorized to access '+self.path)
|
||||
if self.path!='/dm':
|
||||
# not the DM inbox
|
||||
if self.server.debug:
|
||||
print('DEBUG: GET access to inbox is unauthorized')
|
||||
self.send_response(405)
|
||||
self.end_headers()
|
||||
self.server.GETbusy=False
|
||||
return
|
||||
|
||||
# get outbox feed for a person
|
||||
outboxFeed=personBoxJson(self.server.baseDir,self.server.domain, \
|
||||
self.server.port,self.path, \
|
||||
|
|
|
@ -18,6 +18,7 @@ from Crypto.PublicKey import RSA
|
|||
from shutil import copyfile
|
||||
from webfinger import createWebfingerEndpoint
|
||||
from webfinger import storeWebfingerEndpoint
|
||||
from posts import createDMTimeline
|
||||
from posts import createInbox
|
||||
from posts import createOutbox
|
||||
from posts import createModeration
|
||||
|
@ -387,7 +388,8 @@ def personBoxJson(baseDir: str,domain: str,port: int,path: str, \
|
|||
authorized: bool,ocapAlways: bool) -> []:
|
||||
"""Obtain the inbox/outbox/moderation feed for the given person
|
||||
"""
|
||||
if boxname!='inbox' and boxname!='outbox' and boxname!='moderation':
|
||||
if boxname!='inbox' and boxname!='dm' and \
|
||||
boxname!='outbox' and boxname!='moderation':
|
||||
return None
|
||||
|
||||
if not '/'+boxname in path:
|
||||
|
@ -424,6 +426,9 @@ def personBoxJson(baseDir: str,domain: str,port: int,path: str, \
|
|||
if boxname=='inbox':
|
||||
return createInbox(baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||
if boxname=='dm':
|
||||
return createDMTimeline(baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||
elif boxname=='outbox':
|
||||
return createOutbox(baseDir,nickname,domain,port,httpPrefix, \
|
||||
noOfItems,headerOnly,authorized,pageNumber)
|
||||
|
|
87
posts.py
87
posts.py
|
@ -1508,6 +1508,11 @@ def createInbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str
|
|||
return createBoxBase(baseDir,'inbox',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createDMTimeline(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
return createBoxBase(baseDir,'dm',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createOutbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,authorized: bool,pageNumber=None) -> {}:
|
||||
return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \
|
||||
|
@ -1581,15 +1586,41 @@ def getStatusNumberFromPostFilename(filename) -> int:
|
|||
return None
|
||||
return int(filename.split('#')[-1].replace('.json',''))
|
||||
|
||||
def isDM(postJsonObject: {}) -> bool:
|
||||
"""Returns true if the given post is a DM
|
||||
"""
|
||||
if postJsonObject['type']!='Create':
|
||||
return False
|
||||
if not postJsonObject.get('object'):
|
||||
return False
|
||||
if not isinstance(postJsonObject['object'], dict):
|
||||
return False
|
||||
if postJsonObject['object']['type']!='Note':
|
||||
return False
|
||||
fields=['to','cc']
|
||||
for f in fields:
|
||||
if not postJsonObject['object'].get(f):
|
||||
continue
|
||||
for toAddress in postJsonObject['object'][f]:
|
||||
if toAddress.endswith('#Public'):
|
||||
return False
|
||||
if toAddress.endswith('followers'):
|
||||
return False
|
||||
return True
|
||||
|
||||
def createBoxBase(baseDir: str,boxname: str, \
|
||||
nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,authorized :bool, \
|
||||
ocapAlways: bool,pageNumber=None) -> {}:
|
||||
"""Constructs the box feed for a person with the given nickname
|
||||
"""
|
||||
if boxname!='inbox' and boxname!='outbox':
|
||||
if boxname!='inbox' and boxname!='dm' and boxname!='outbox':
|
||||
return None
|
||||
boxDir = createPersonDir(nickname,domain,baseDir,boxname)
|
||||
if boxname!='dm':
|
||||
boxDir = createPersonDir(nickname,domain,baseDir,boxname)
|
||||
else:
|
||||
# extract DMs from the inbox
|
||||
boxDir = createPersonDir(nickname,domain,baseDir,'inbox')
|
||||
sharedBoxDir=None
|
||||
if boxname=='inbox':
|
||||
sharedBoxDir = createPersonDir('inbox',domain,baseDir,boxname)
|
||||
|
@ -1708,31 +1739,33 @@ def createBoxBase(baseDir: str,boxname: str, \
|
|||
# get the post as json
|
||||
with open(filePath, 'r') as fp:
|
||||
p=commentjson.load(fp)
|
||||
|
||||
# remove any capability so that it's not displayed
|
||||
if p.get('capability'):
|
||||
del p['capability']
|
||||
# Don't show likes or replies to unauthorized viewers
|
||||
if not authorized:
|
||||
if p.get('object'):
|
||||
if isinstance(p['object'], dict):
|
||||
if p['object'].get('likes'):
|
||||
p['likes']={}
|
||||
if p['object'].get('replies'):
|
||||
p['replies']={}
|
||||
# insert it into the box feed
|
||||
if postsOnPageCtr < itemsPerPage:
|
||||
if not headerOnly:
|
||||
boxItems['orderedItems'].append(p)
|
||||
postsOnPageCtr += 1
|
||||
elif postsOnPageCtr == itemsPerPage:
|
||||
# if this is the last post update the next message ID
|
||||
if '/statuses/' in p['id']:
|
||||
postId = p['id'].split('/statuses/')[1].replace('/activity','')
|
||||
boxHeader['next']= \
|
||||
httpPrefix+'://'+domain+'/users/'+ \
|
||||
nickname+'/'+boxname+'?max_id='+ \
|
||||
postId+'&page=true'
|
||||
|
||||
if boxname!='dm' or \
|
||||
(boxname=='dm' and isDM(p))
|
||||
# remove any capability so that it's not displayed
|
||||
if p.get('capability'):
|
||||
del p['capability']
|
||||
# Don't show likes or replies to unauthorized viewers
|
||||
if not authorized:
|
||||
if p.get('object'):
|
||||
if isinstance(p['object'], dict):
|
||||
if p['object'].get('likes'):
|
||||
p['likes']={}
|
||||
if p['object'].get('replies'):
|
||||
p['replies']={}
|
||||
# insert it into the box feed
|
||||
if postsOnPageCtr < itemsPerPage:
|
||||
if not headerOnly:
|
||||
boxItems['orderedItems'].append(p)
|
||||
postsOnPageCtr += 1
|
||||
elif postsOnPageCtr == itemsPerPage:
|
||||
# if this is the last post update the next message ID
|
||||
if '/statuses/' in p['id']:
|
||||
postId = p['id'].split('/statuses/')[1].replace('/activity','')
|
||||
boxHeader['next']= \
|
||||
httpPrefix+'://'+domain+'/users/'+ \
|
||||
nickname+'/'+boxname+'?max_id='+ \
|
||||
postId+'&page=true'
|
||||
# remember the last post filename for use with prev
|
||||
prevPostFilename = postFilename
|
||||
if postsOnPageCtr >= itemsPerPage:
|
||||
|
|
2
utils.py
2
utils.py
|
@ -271,7 +271,7 @@ def validNickname(domain: str,nickname: str) -> bool:
|
|||
return False
|
||||
if nickname==domain:
|
||||
return False
|
||||
reservedNames=['inbox','outbox','following','followers','capabilities']
|
||||
reservedNames=['inbox','dm','outbox','following','public','followers','capabilities']
|
||||
if nickname in reservedNames:
|
||||
return False
|
||||
return True
|
||||
|
|
Loading…
Reference in New Issue