When manual follower approval is active replies default to followers only

master
Bob Mottram 2019-09-02 11:51:49 +01:00
parent 8f346fffef
commit 26468d5380
2 changed files with 105 additions and 67 deletions

107
daemon.py
View File

@ -1100,55 +1100,70 @@ class PubServer(BaseHTTPRequestHandler):
inReplyToUrl=None inReplyToUrl=None
replyWithDM=False replyWithDM=False
replyToList=[] replyToList=[]
if htmlGET and '?replyto=' in self.path:
inReplyToUrl=self.path.split('?replyto=')[1]
if '?' in inReplyToUrl:
mentionsList=inReplyToUrl.split('?')
for m in mentionsList:
if m.startswith('mention='):
replyToList.append(m.replace('mention=',''))
inReplyToUrl=mentionsList[0]
self.path=self.path.split('?replyto=')[0]+'/newpost'
if self.server.debug:
print('DEBUG: replyto path '+self.path)
# replying as a direct message, for moderation posts
shareDescription=None shareDescription=None
if htmlGET and '?replydm=' in self.path: if htmlGET:
inReplyToUrl=self.path.split('?replydm=')[1] # public reply
if '?' in inReplyToUrl: if '?replyto=' in self.path:
mentionsList=inReplyToUrl.split('?') inReplyToUrl=self.path.split('?replyto=')[1]
for m in mentionsList: if '?' in inReplyToUrl:
if m.startswith('mention='): mentionsList=inReplyToUrl.split('?')
replyToList.append(m.replace('mention=','')) for m in mentionsList:
inReplyToUrl=mentionsList[0] if m.startswith('mention='):
if inReplyToUrl.startswith('sharedesc:'): replyToList.append(m.replace('mention=',''))
shareDescription=inReplyToUrl.replace('sharedesc:','').replace('%20',' ').replace('%40','@').replace('%3A',':').replace('%23','#') inReplyToUrl=mentionsList[0]
self.path=self.path.split('?replydm=')[0]+'/newdm' self.path=self.path.split('?replyto=')[0]+'/newpost'
if self.server.debug: if self.server.debug:
print('DEBUG: replydm path '+self.path) print('DEBUG: replyto path '+self.path)
# edit profile in web interface # reply to followers
if htmlGET and '/users/' in self.path and self.path.endswith('/editprofile'): if '?replyfollowers=' in self.path:
msg=htmlEditProfile(self.server.baseDir,self.path,self.server.domain,self.server.port).encode() inReplyToUrl=self.path.split('?replyfollowers=')[1]
self._set_headers('text/html',len(msg),cookie) if '?' in inReplyToUrl:
self.wfile.write(msg) mentionsList=inReplyToUrl.split('?')
self.server.GETbusy=False for m in mentionsList:
return if m.startswith('mention='):
replyToList.append(m.replace('mention=',''))
inReplyToUrl=mentionsList[0]
self.path=self.path.split('?replyfollowers=')[0]+'/newfollowers'
if self.server.debug:
print('DEBUG: replyfollowers path '+self.path)
# Various types of new post in the web interface # replying as a direct message, for moderation posts or the dm timeline
if htmlGET and '/users/' in self.path and \ if '?replydm=' in self.path:
(self.path.endswith('/newpost') or \ inReplyToUrl=self.path.split('?replydm=')[1]
self.path.endswith('/newunlisted') or \ if '?' in inReplyToUrl:
self.path.endswith('/newfollowers') or \ mentionsList=inReplyToUrl.split('?')
self.path.endswith('/newdm') or \ for m in mentionsList:
self.path.endswith('/newreport') or \ if m.startswith('mention='):
self.path.endswith('/newshare')): replyToList.append(m.replace('mention=',''))
msg=htmlNewPost(self.server.baseDir,self.path,inReplyToUrl,replyToList,shareDescription).encode() inReplyToUrl=mentionsList[0]
self._set_headers('text/html',len(msg),cookie) if inReplyToUrl.startswith('sharedesc:'):
self.wfile.write(msg) shareDescription=inReplyToUrl.replace('sharedesc:','').replace('%20',' ').replace('%40','@').replace('%3A',':').replace('%23','#')
self.server.GETbusy=False self.path=self.path.split('?replydm=')[0]+'/newdm'
return if self.server.debug:
print('DEBUG: replydm path '+self.path)
# edit profile in web interface
if '/users/' in self.path and self.path.endswith('/editprofile'):
msg=htmlEditProfile(self.server.baseDir,self.path,self.server.domain,self.server.port).encode()
self._set_headers('text/html',len(msg),cookie)
self.wfile.write(msg)
self.server.GETbusy=False
return
# Various types of new post in the web interface
if '/users/' in self.path and \
(self.path.endswith('/newpost') or \
self.path.endswith('/newunlisted') or \
self.path.endswith('/newfollowers') or \
self.path.endswith('/newdm') or \
self.path.endswith('/newreport') or \
self.path.endswith('/newshare')):
msg=htmlNewPost(self.server.baseDir,self.path,inReplyToUrl,replyToList,shareDescription).encode()
self._set_headers('text/html',len(msg),cookie)
self.wfile.write(msg)
self.server.GETbusy=False
return
# get an individual post from the path /@nickname/statusnumber # get an individual post from the path /@nickname/statusnumber
if '/@' in self.path: if '/@' in self.path:

View File

@ -276,7 +276,7 @@ def htmlHashtagSearch(baseDir: str,hashtag: str,pageNumber: int,postsPerPage: in
nickname,domain,port,postJsonObject, \ nickname,domain,port,postJsonObject, \
None,True,False, \ None,True,False, \
httpPrefix,projectVersion, \ httpPrefix,projectVersion, \
False,False) False,False,False)
index-=1 index-=1
if endIndex>0: if endIndex>0:
@ -874,7 +874,7 @@ def htmlProfilePosts(baseDir: str,httpPrefix: str, \
individualPostAsHtml(baseDir,session,wfRequest,personCache, \ individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,item,None,True,False, \ nickname,domain,port,item,None,True,False, \
httpPrefix,projectVersion, \ httpPrefix,projectVersion, \
False,False) False,False,False)
return profileStr return profileStr
def htmlProfileFollowing(baseDir: str,httpPrefix: str, \ def htmlProfileFollowing(baseDir: str,httpPrefix: str, \
@ -1303,7 +1303,19 @@ def addEmbeddedElements(content: str) -> str:
content=addEmbeddedVideoFromSites(content) content=addEmbeddedVideoFromSites(content)
content=addEmbeddedAudio(content) content=addEmbeddedAudio(content)
return addEmbeddedVideo(content) return addEmbeddedVideo(content)
def followerApprovalActive(baseDir: str,nickname: str,domain: str) -> bool:
"""Returns true if the given account requires follower approval
"""
manuallyApprovesFollowers=False
actorFilename=baseDir+'/accounts/'+nickname+'@'+domain+'.json'
if os.path.isfile(actorFilename):
with open(actorFilename, 'r') as fp:
actorJson=commentjson.load(fp)
if actorJson.get('manuallyApprovesFollowers'):
manuallyApprovesFollowers=actorJson['manuallyApprovesFollowers']
return manuallyApprovesFollowers
def individualPostAsHtml(baseDir: str, \ def individualPostAsHtml(baseDir: str, \
session,wfRequest: {},personCache: {}, \ session,wfRequest: {},personCache: {}, \
nickname: str,domain: str,port: int, \ nickname: str,domain: str,port: int, \
@ -1311,8 +1323,9 @@ def individualPostAsHtml(baseDir: str, \
avatarUrl: str, showAvatarDropdown: bool, avatarUrl: str, showAvatarDropdown: bool,
allowDeletion: bool, \ allowDeletion: bool, \
httpPrefix: str, projectVersion: str, \ httpPrefix: str, projectVersion: str, \
showRepeats=True, showRepeats=True, \
showIcons=False) -> str: showIcons=False, \
manuallyApprovesFollowers=False) -> str:
""" Shows a single post as html """ Shows a single post as html
""" """
# If this is the inbox timeline then don't show the repeat icon on any DMs # If this is the inbox timeline then don't show the repeat icon on any DMs
@ -1593,10 +1606,13 @@ def individualPostAsHtml(baseDir: str, \
replyToLink+='?mention='+actorUrl replyToLink+='?mention='+actorUrl
if len(replyToLink)>500: if len(replyToLink)>500:
break break
footerStr='<div class="'+containerClassIcons+'">' footerStr='<div class="'+containerClassIcons+'">'
if not isModerationPost and showRepeatIcon: if not isModerationPost and showRepeatIcon:
footerStr+='<a href="/users/'+nickname+'?replyto='+replyToLink+'" title="Reply to this post">' if not manuallyApprovesFollowers:
footerStr+='<a href="/users/'+nickname+'?replyto='+replyToLink+'" title="Reply to this post">'
else:
footerStr+='<a href="/users/'+nickname+'?replyfollowers='+replyToLink+'" title="Reply to this post">'
else: else:
footerStr+='<a href="/users/'+nickname+'?replydm='+replyToLink+'" title="Reply to this post">' footerStr+='<a href="/users/'+nickname+'?replydm='+replyToLink+'" title="Reply to this post">'
footerStr+='<img src="/icons/reply.png"/></a>' footerStr+='<img src="/icons/reply.png"/></a>'
@ -1638,7 +1654,8 @@ def htmlTimeline(pageNumber: int,itemsPerPage: int,session,baseDir: str, \
wfRequest: {},personCache: {}, \ wfRequest: {},personCache: {}, \
nickname: str,domain: str,port: int,timelineJson: {}, \ nickname: str,domain: str,port: int,timelineJson: {}, \
boxName: str,allowDeletion: bool, \ boxName: str,allowDeletion: bool, \
httpPrefix: str,projectVersion: str) -> str: httpPrefix: str,projectVersion: str, \
manuallyApproveFollowers: bool) -> str:
"""Show the timeline as html """Show the timeline as html
""" """
with open(baseDir+'/epicyon-profile.css', 'r') as cssFile: with open(baseDir+'/epicyon-profile.css', 'r') as cssFile:
@ -1734,9 +1751,10 @@ def htmlTimeline(pageNumber: int,itemsPerPage: int,session,baseDir: str, \
tlStr+=individualPostAsHtml(baseDir,session,wfRequest,personCache, \ tlStr+=individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,item,avatarUrl,True, \ nickname,domain,port,item,avatarUrl,True, \
allowDeletion, \ allowDeletion, \
httpPrefix,projectVersion, httpPrefix,projectVersion, \
boxName!='dm', boxName!='dm', \
showIndividualPostIcons) showIndividualPostIcons, \
manuallyApproveFollowers)
# page down arrow # page down arrow
if itemCtr>=itemsPerPage: if itemCtr>=itemsPerPage:
@ -1751,9 +1769,12 @@ def htmlInbox(pageNumber: int,itemsPerPage: int, \
httpPrefix: str,projectVersion: str) -> str: httpPrefix: str,projectVersion: str) -> str:
"""Show the inbox as html """Show the inbox as html
""" """
manuallyApproveFollowers= \
followerApprovalActive(baseDir,nickname,domain)
return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \ return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \
nickname,domain,port,inboxJson,'inbox',allowDeletion, \ nickname,domain,port,inboxJson,'inbox',allowDeletion, \
httpPrefix,projectVersion) httpPrefix,projectVersion,manuallyApproveFollowers)
def htmlInboxDMs(pageNumber: int,itemsPerPage: int, \ def htmlInboxDMs(pageNumber: int,itemsPerPage: int, \
session,baseDir: str,wfRequest: {},personCache: {}, \ session,baseDir: str,wfRequest: {},personCache: {}, \
@ -1764,7 +1785,7 @@ def htmlInboxDMs(pageNumber: int,itemsPerPage: int, \
""" """
return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \ return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \
nickname,domain,port,inboxJson,'dm',allowDeletion, \ nickname,domain,port,inboxJson,'dm',allowDeletion, \
httpPrefix,projectVersion) httpPrefix,projectVersion,False)
def htmlModeration(pageNumber: int,itemsPerPage: int, \ def htmlModeration(pageNumber: int,itemsPerPage: int, \
session,baseDir: str,wfRequest: {},personCache: {}, \ session,baseDir: str,wfRequest: {},personCache: {}, \
@ -1775,7 +1796,7 @@ def htmlModeration(pageNumber: int,itemsPerPage: int, \
""" """
return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \ return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \
nickname,domain,port,inboxJson,'moderation',allowDeletion, \ nickname,domain,port,inboxJson,'moderation',allowDeletion, \
httpPrefix,projectVersion) httpPrefix,projectVersion,True)
def htmlOutbox(pageNumber: int,itemsPerPage: int, \ def htmlOutbox(pageNumber: int,itemsPerPage: int, \
session,baseDir: str,wfRequest: {},personCache: {}, \ session,baseDir: str,wfRequest: {},personCache: {}, \
@ -1784,9 +1805,11 @@ def htmlOutbox(pageNumber: int,itemsPerPage: int, \
httpPrefix: str,projectVersion: str) -> str: httpPrefix: str,projectVersion: str) -> str:
"""Show the Outbox as html """Show the Outbox as html
""" """
manuallyApproveFollowers= \
followerApprovalActive(baseDir,nickname,domain)
return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \ return htmlTimeline(pageNumber,itemsPerPage,session,baseDir,wfRequest,personCache, \
nickname,domain,port,outboxJson,'outbox',allowDeletion, \ nickname,domain,port,outboxJson,'outbox',allowDeletion, \
httpPrefix,projectVersion) httpPrefix,projectVersion,manuallyApproveFollowers)
def htmlIndividualPost(baseDir: str,session,wfRequest: {},personCache: {}, \ def htmlIndividualPost(baseDir: str,session,wfRequest: {},personCache: {}, \
nickname: str,domain: str,port: int,authorized: bool, \ nickname: str,domain: str,port: int,authorized: bool, \
@ -1797,7 +1820,7 @@ def htmlIndividualPost(baseDir: str,session,wfRequest: {},personCache: {}, \
postStr+= \ postStr+= \
individualPostAsHtml(baseDir,session,wfRequest,personCache, \ individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,postJsonObject,None,True,False, \ nickname,domain,port,postJsonObject,None,True,False, \
httpPrefix,projectVersion,False,False) httpPrefix,projectVersion,False,False,False)
messageId=postJsonObject['id'].replace('/activity','') messageId=postJsonObject['id'].replace('/activity','')
# show the previous posts # show the previous posts
@ -1812,7 +1835,7 @@ def htmlIndividualPost(baseDir: str,session,wfRequest: {},personCache: {}, \
nickname,domain,port,postJsonObject, \ nickname,domain,port,postJsonObject, \
None,True,False, \ None,True,False, \
httpPrefix,projectVersion, \ httpPrefix,projectVersion, \
False,False)+postStr False,False,False)+postStr
# show the following posts # show the following posts
postFilename=locatePost(baseDir,nickname,domain,messageId) postFilename=locatePost(baseDir,nickname,domain,messageId)
@ -1828,7 +1851,7 @@ def htmlIndividualPost(baseDir: str,session,wfRequest: {},personCache: {}, \
postStr+= \ postStr+= \
individualPostAsHtml(baseDir,session,wfRequest,personCache, \ individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,item,None,True,False, \ nickname,domain,port,item,None,True,False, \
httpPrefix,projectVersion,False,False) httpPrefix,projectVersion,False,False,False)
return htmlHeader()+postStr+htmlFooter() return htmlHeader()+postStr+htmlFooter()
def htmlPostReplies(baseDir: str,session,wfRequest: {},personCache: {}, \ def htmlPostReplies(baseDir: str,session,wfRequest: {},personCache: {}, \
@ -1841,7 +1864,7 @@ def htmlPostReplies(baseDir: str,session,wfRequest: {},personCache: {}, \
for item in repliesJson['orderedItems']: for item in repliesJson['orderedItems']:
repliesStr+=individualPostAsHtml(baseDir,session,wfRequest,personCache, \ repliesStr+=individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,item,None,True,False, \ nickname,domain,port,item,None,True,False, \
httpPrefix,projectVersion,False,False) httpPrefix,projectVersion,False,False,False)
return htmlHeader()+repliesStr+htmlFooter() return htmlHeader()+repliesStr+htmlFooter()
@ -1921,7 +1944,7 @@ def htmlDeletePost(session,baseDir: str,messageId: str, \
deletePostStr+= \ deletePostStr+= \
individualPostAsHtml(baseDir,session,wfRequest,personCache, \ individualPostAsHtml(baseDir,session,wfRequest,personCache, \
nickname,domain,port,postJsonObject,None,True,False, \ nickname,domain,port,postJsonObject,None,True,False, \
httpPrefix,projectVersion,False,False) httpPrefix,projectVersion,False,False,False)
deletePostStr+='<center>' deletePostStr+='<center>'
deletePostStr+=' <p class="followText">Delete this post?</p>' deletePostStr+=' <p class="followText">Delete this post?</p>'
deletePostStr+= \ deletePostStr+= \
@ -2299,7 +2322,7 @@ def htmlProfileAfterSearch(baseDir: str,path: str,httpPrefix: str, \
nickname,domain,port, \ nickname,domain,port, \
item,avatarUrl,False,False, \ item,avatarUrl,False,False, \
httpPrefix,projectVersion, \ httpPrefix,projectVersion, \
False,False) False,False,False)
i+=1 i+=1
if i>=20: if i>=20:
break break