forked from indymedia/epicyon
Timeline for DMs
parent
1b66aa0077
commit
97487eeb54
65
daemon.py
65
daemon.py
|
@ -1378,6 +1378,71 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.GETbusy=False
|
self.server.GETbusy=False
|
||||||
return
|
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
|
# get outbox feed for a person
|
||||||
outboxFeed=personBoxJson(self.server.baseDir,self.server.domain, \
|
outboxFeed=personBoxJson(self.server.baseDir,self.server.domain, \
|
||||||
self.server.port,self.path, \
|
self.server.port,self.path, \
|
||||||
|
|
|
@ -18,6 +18,7 @@ from Crypto.PublicKey import RSA
|
||||||
from shutil import copyfile
|
from shutil import copyfile
|
||||||
from webfinger import createWebfingerEndpoint
|
from webfinger import createWebfingerEndpoint
|
||||||
from webfinger import storeWebfingerEndpoint
|
from webfinger import storeWebfingerEndpoint
|
||||||
|
from posts import createDMTimeline
|
||||||
from posts import createInbox
|
from posts import createInbox
|
||||||
from posts import createOutbox
|
from posts import createOutbox
|
||||||
from posts import createModeration
|
from posts import createModeration
|
||||||
|
@ -387,7 +388,8 @@ def personBoxJson(baseDir: str,domain: str,port: int,path: str, \
|
||||||
authorized: bool,ocapAlways: bool) -> []:
|
authorized: bool,ocapAlways: bool) -> []:
|
||||||
"""Obtain the inbox/outbox/moderation feed for the given person
|
"""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
|
return None
|
||||||
|
|
||||||
if not '/'+boxname in path:
|
if not '/'+boxname in path:
|
||||||
|
@ -424,6 +426,9 @@ def personBoxJson(baseDir: str,domain: str,port: int,path: str, \
|
||||||
if boxname=='inbox':
|
if boxname=='inbox':
|
||||||
return createInbox(baseDir,nickname,domain,port,httpPrefix, \
|
return createInbox(baseDir,nickname,domain,port,httpPrefix, \
|
||||||
noOfItems,headerOnly,ocapAlways,pageNumber)
|
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||||
|
if boxname=='dm':
|
||||||
|
return createDMTimeline(baseDir,nickname,domain,port,httpPrefix, \
|
||||||
|
noOfItems,headerOnly,ocapAlways,pageNumber)
|
||||||
elif boxname=='outbox':
|
elif boxname=='outbox':
|
||||||
return createOutbox(baseDir,nickname,domain,port,httpPrefix, \
|
return createOutbox(baseDir,nickname,domain,port,httpPrefix, \
|
||||||
noOfItems,headerOnly,authorized,pageNumber)
|
noOfItems,headerOnly,authorized,pageNumber)
|
||||||
|
|
85
posts.py
85
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, \
|
return createBoxBase(baseDir,'inbox',nickname,domain,port,httpPrefix, \
|
||||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
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, \
|
def createOutbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||||
itemsPerPage: int,headerOnly: bool,authorized: bool,pageNumber=None) -> {}:
|
itemsPerPage: int,headerOnly: bool,authorized: bool,pageNumber=None) -> {}:
|
||||||
return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \
|
return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \
|
||||||
|
@ -1581,15 +1586,41 @@ def getStatusNumberFromPostFilename(filename) -> int:
|
||||||
return None
|
return None
|
||||||
return int(filename.split('#')[-1].replace('.json',''))
|
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, \
|
def createBoxBase(baseDir: str,boxname: str, \
|
||||||
nickname: str,domain: str,port: int,httpPrefix: str, \
|
nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||||
itemsPerPage: int,headerOnly: bool,authorized :bool, \
|
itemsPerPage: int,headerOnly: bool,authorized :bool, \
|
||||||
ocapAlways: bool,pageNumber=None) -> {}:
|
ocapAlways: bool,pageNumber=None) -> {}:
|
||||||
"""Constructs the box feed for a person with the given nickname
|
"""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
|
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
|
sharedBoxDir=None
|
||||||
if boxname=='inbox':
|
if boxname=='inbox':
|
||||||
sharedBoxDir = createPersonDir('inbox',domain,baseDir,boxname)
|
sharedBoxDir = createPersonDir('inbox',domain,baseDir,boxname)
|
||||||
|
@ -1709,30 +1740,32 @@ def createBoxBase(baseDir: str,boxname: str, \
|
||||||
with open(filePath, 'r') as fp:
|
with open(filePath, 'r') as fp:
|
||||||
p=commentjson.load(fp)
|
p=commentjson.load(fp)
|
||||||
|
|
||||||
# remove any capability so that it's not displayed
|
if boxname!='dm' or \
|
||||||
if p.get('capability'):
|
(boxname=='dm' and isDM(p))
|
||||||
del p['capability']
|
# remove any capability so that it's not displayed
|
||||||
# Don't show likes or replies to unauthorized viewers
|
if p.get('capability'):
|
||||||
if not authorized:
|
del p['capability']
|
||||||
if p.get('object'):
|
# Don't show likes or replies to unauthorized viewers
|
||||||
if isinstance(p['object'], dict):
|
if not authorized:
|
||||||
if p['object'].get('likes'):
|
if p.get('object'):
|
||||||
p['likes']={}
|
if isinstance(p['object'], dict):
|
||||||
if p['object'].get('replies'):
|
if p['object'].get('likes'):
|
||||||
p['replies']={}
|
p['likes']={}
|
||||||
# insert it into the box feed
|
if p['object'].get('replies'):
|
||||||
if postsOnPageCtr < itemsPerPage:
|
p['replies']={}
|
||||||
if not headerOnly:
|
# insert it into the box feed
|
||||||
boxItems['orderedItems'].append(p)
|
if postsOnPageCtr < itemsPerPage:
|
||||||
postsOnPageCtr += 1
|
if not headerOnly:
|
||||||
elif postsOnPageCtr == itemsPerPage:
|
boxItems['orderedItems'].append(p)
|
||||||
# if this is the last post update the next message ID
|
postsOnPageCtr += 1
|
||||||
if '/statuses/' in p['id']:
|
elif postsOnPageCtr == itemsPerPage:
|
||||||
postId = p['id'].split('/statuses/')[1].replace('/activity','')
|
# if this is the last post update the next message ID
|
||||||
boxHeader['next']= \
|
if '/statuses/' in p['id']:
|
||||||
httpPrefix+'://'+domain+'/users/'+ \
|
postId = p['id'].split('/statuses/')[1].replace('/activity','')
|
||||||
nickname+'/'+boxname+'?max_id='+ \
|
boxHeader['next']= \
|
||||||
postId+'&page=true'
|
httpPrefix+'://'+domain+'/users/'+ \
|
||||||
|
nickname+'/'+boxname+'?max_id='+ \
|
||||||
|
postId+'&page=true'
|
||||||
# remember the last post filename for use with prev
|
# remember the last post filename for use with prev
|
||||||
prevPostFilename = postFilename
|
prevPostFilename = postFilename
|
||||||
if postsOnPageCtr >= itemsPerPage:
|
if postsOnPageCtr >= itemsPerPage:
|
||||||
|
|
2
utils.py
2
utils.py
|
@ -271,7 +271,7 @@ def validNickname(domain: str,nickname: str) -> bool:
|
||||||
return False
|
return False
|
||||||
if nickname==domain:
|
if nickname==domain:
|
||||||
return False
|
return False
|
||||||
reservedNames=['inbox','outbox','following','followers','capabilities']
|
reservedNames=['inbox','dm','outbox','following','public','followers','capabilities']
|
||||||
if nickname in reservedNames:
|
if nickname in reservedNames:
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
Loading…
Reference in New Issue