forked from indymedia/epicyon
Report post type
parent
bbffb6f935
commit
9938be63bf
47
daemon.py
47
daemon.py
|
@ -32,6 +32,7 @@ from posts import sendToFollowers
|
||||||
from posts import postIsAddressedToPublic
|
from posts import postIsAddressedToPublic
|
||||||
from posts import sendToNamedAddresses
|
from posts import sendToNamedAddresses
|
||||||
from posts import createPublicPost
|
from posts import createPublicPost
|
||||||
|
from posts import createReportPost
|
||||||
from posts import createUnlistedPost
|
from posts import createUnlistedPost
|
||||||
from posts import createFollowersOnlyPost
|
from posts import createFollowersOnlyPost
|
||||||
from posts import createDirectMessagePost
|
from posts import createDirectMessagePost
|
||||||
|
@ -948,6 +949,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.path.endswith('/newunlisted') or \
|
self.path.endswith('/newunlisted') or \
|
||||||
self.path.endswith('/newfollowers') or \
|
self.path.endswith('/newfollowers') or \
|
||||||
self.path.endswith('/newdm') or \
|
self.path.endswith('/newdm') or \
|
||||||
|
self.path.endswith('/newreport') or \
|
||||||
self.path.endswith('/newshare')):
|
self.path.endswith('/newshare')):
|
||||||
self._set_headers('text/html',cookie)
|
self._set_headers('text/html',cookie)
|
||||||
self.wfile.write(htmlNewPost(self.server.baseDir,self.path,inReplyToUrl,replyToList).encode())
|
self.wfile.write(htmlNewPost(self.server.baseDir,self.path,inReplyToUrl,replyToList).encode())
|
||||||
|
@ -1616,14 +1618,16 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
if postType=='newdm':
|
if postType=='newdm':
|
||||||
messageJson= \
|
messageJson=None
|
||||||
createDirectMessagePost(self.server.baseDir, \
|
if '@' in fields['message']:
|
||||||
nickname, \
|
messageJson= \
|
||||||
self.server.domain,self.server.port, \
|
createDirectMessagePost(self.server.baseDir, \
|
||||||
self.server.httpPrefix, \
|
nickname, \
|
||||||
fields['message'],True,False,False, \
|
self.server.domain,self.server.port, \
|
||||||
filename,fields['imageDescription'],True, \
|
self.server.httpPrefix, \
|
||||||
fields['replyTo'],fields['replyTo'],fields['subject'])
|
fields['message'],True,False,False, \
|
||||||
|
filename,fields['imageDescription'],True, \
|
||||||
|
fields['replyTo'],fields['replyTo'],fields['subject'])
|
||||||
if messageJson:
|
if messageJson:
|
||||||
self.postToNickname=nickname
|
self.postToNickname=nickname
|
||||||
if self._postToOutbox(messageJson):
|
if self._postToOutbox(messageJson):
|
||||||
|
@ -1637,6 +1641,26 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
if postType=='newreport':
|
||||||
|
# So as to be sure that this only goes to moderators
|
||||||
|
# and not accounts being reported we disable any
|
||||||
|
# included fediverse addresses by replacing '@' with '-at-'
|
||||||
|
fields['message']=fields['message'].replace('@','-at-')
|
||||||
|
messageJson= \
|
||||||
|
createReportPost(self.server.baseDir, \
|
||||||
|
nickname, \
|
||||||
|
self.server.domain,self.server.port, \
|
||||||
|
self.server.httpPrefix, \
|
||||||
|
fields['message'],True,False,False, \
|
||||||
|
filename,fields['imageDescription'],True, \
|
||||||
|
self.server.debug,fields['subject'])
|
||||||
|
if messageJson:
|
||||||
|
self.postToNickname=nickname
|
||||||
|
if self._postToOutbox(messageJson):
|
||||||
|
return 1
|
||||||
|
else:
|
||||||
|
return -1
|
||||||
|
|
||||||
if postType=='newshare':
|
if postType=='newshare':
|
||||||
if not fields.get('itemType'):
|
if not fields.get('itemType'):
|
||||||
return False
|
return False
|
||||||
|
@ -2164,6 +2188,13 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.POSTbusy=False
|
self.server.POSTbusy=False
|
||||||
return
|
return
|
||||||
postState=self._receiveNewPost(authorized,'newdm')
|
postState=self._receiveNewPost(authorized,'newdm')
|
||||||
|
if postState!=0:
|
||||||
|
if '/' in nickname:
|
||||||
|
nickname=nickname.split('/')[0]
|
||||||
|
self._redirect_headers('/users/'+self.postToNickname+'/outbox',cookie)
|
||||||
|
self.server.POSTbusy=False
|
||||||
|
return
|
||||||
|
postState=self._receiveNewPost(authorized,'newreport')
|
||||||
if postState!=0:
|
if postState!=0:
|
||||||
if '/' in nickname:
|
if '/' in nickname:
|
||||||
nickname=nickname.split('/')[0]
|
nickname=nickname.split('/')[0]
|
||||||
|
|
|
@ -92,6 +92,11 @@ a:link {
|
||||||
padding: 4px 0;
|
padding: 4px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.new-post-subtext {
|
||||||
|
font-size: 18px;
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.highlight {
|
.highlight {
|
||||||
width: 2%;
|
width: 2%;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
61
posts.py
61
posts.py
|
@ -41,6 +41,7 @@ from capabilities import capabilitiesUpdate
|
||||||
from media import attachImage
|
from media import attachImage
|
||||||
from content import addHtmlTags
|
from content import addHtmlTags
|
||||||
from auth import createBasicAuthHeader
|
from auth import createBasicAuthHeader
|
||||||
|
from config import getConfigParam
|
||||||
try:
|
try:
|
||||||
from BeautifulSoup import BeautifulSoup
|
from BeautifulSoup import BeautifulSoup
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -748,6 +749,66 @@ def createDirectMessagePost(baseDir: str,
|
||||||
attachImageFilename,imageDescription,useBlurhash, \
|
attachImageFilename,imageDescription,useBlurhash, \
|
||||||
inReplyTo, inReplyToAtomUri, subject)
|
inReplyTo, inReplyToAtomUri, subject)
|
||||||
|
|
||||||
|
def createReportPost(baseDir: str,
|
||||||
|
nickname: str, domain: str, port: int,httpPrefix: str, \
|
||||||
|
content: str, followersOnly: bool, saveToFile: bool,
|
||||||
|
clientToServer: bool,\
|
||||||
|
attachImageFilename: str,imageDescription: str,useBlurhash: bool, \
|
||||||
|
debug: bool,subject=None) -> {}:
|
||||||
|
"""Send a report to moderators
|
||||||
|
"""
|
||||||
|
domainFull=domain
|
||||||
|
if port:
|
||||||
|
if port!=80 and port!=443:
|
||||||
|
domainFull=domain+':'+str(port)
|
||||||
|
|
||||||
|
# create the list of moderators from teh moderators file
|
||||||
|
moderatorsList=[]
|
||||||
|
moderatorsFile=baseDir+'/accounts/moderators.txt'
|
||||||
|
if os.path.isfile(moderatorsFile):
|
||||||
|
with open (moderatorsFile, "r") as fileHandler:
|
||||||
|
for line in fileHandler:
|
||||||
|
line=line.strip('\n')
|
||||||
|
if line.startswith('#'):
|
||||||
|
continue
|
||||||
|
if line.startswith('/users/'):
|
||||||
|
line=line.replace('users','')
|
||||||
|
if line.startswith('@'):
|
||||||
|
line=line[1:]
|
||||||
|
if '@' in line:
|
||||||
|
moderatorActor=httpPrefix+'://'+domainFull+'/users/'+line.split('@')[0]
|
||||||
|
if moderatorActor not in moderatorList:
|
||||||
|
moderatorsList.append(moderatorActor)
|
||||||
|
continue
|
||||||
|
if line.startswith('http') or line.startswith('dat'):
|
||||||
|
# must be a local address - no remote moderators
|
||||||
|
if '://'+domainFull+'/' in line:
|
||||||
|
if line not in moderatorsList:
|
||||||
|
moderatorsList.append(line)
|
||||||
|
else:
|
||||||
|
if '/' not in line:
|
||||||
|
moderatorActor=httpPrefix+'://'+domainFull+'/users/'+line
|
||||||
|
if moderatorActor not in moderatorsList:
|
||||||
|
moderatorsList.append(moderatorActor)
|
||||||
|
if len(moderatorsList)==0:
|
||||||
|
# if there are no moderators then the admin becomes the moderator
|
||||||
|
adminNickname=getConfigParam(baseDir,'admin')
|
||||||
|
if adminNickname:
|
||||||
|
moderatorsList.append(httpPrefix+'://'+domainFull+'/users/'+adminNickname)
|
||||||
|
if not moderatorsList:
|
||||||
|
return None
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: Sending report to moderators')
|
||||||
|
print(str(moderatorsList))
|
||||||
|
postTo=moderatorsList
|
||||||
|
postCc=None
|
||||||
|
return createPostBase(baseDir,nickname, domain, port, \
|
||||||
|
postTo,postCc, \
|
||||||
|
httpPrefix, content, followersOnly, saveToFile, \
|
||||||
|
clientToServer, \
|
||||||
|
attachImageFilename,imageDescription,useBlurhash, \
|
||||||
|
None, None, subject)
|
||||||
|
|
||||||
def threadSendPost(session,postJsonObject: {},federationList: [],\
|
def threadSendPost(session,postJsonObject: {},federationList: [],\
|
||||||
inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: [],
|
inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: [],
|
||||||
debug :bool) -> None:
|
debug :bool) -> None:
|
||||||
|
|
39
roles.py
39
roles.py
|
@ -16,6 +16,39 @@ from session import postJson
|
||||||
from utils import getNicknameFromActor
|
from utils import getNicknameFromActor
|
||||||
from utils import getDomainFromActor
|
from utils import getDomainFromActor
|
||||||
|
|
||||||
|
def addModerator(baseDir: str,nickname: str):
|
||||||
|
"""Adds a moderator nickname to the file
|
||||||
|
"""
|
||||||
|
moderatorsFile=baseDir+'/accounts/moderators.txt'
|
||||||
|
if os.path.isfile(moderatorsFile):
|
||||||
|
# is this nickname already in the file?
|
||||||
|
with open(moderatorsFile, "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
for moderator in lines:
|
||||||
|
moderator=moderator.strip('\n')
|
||||||
|
if line==nickname:
|
||||||
|
return
|
||||||
|
lines.append(nickname)
|
||||||
|
with open(moderatorsFile, "w") as f:
|
||||||
|
for moderator in lines:
|
||||||
|
moderator=moderator.strip('\n')
|
||||||
|
if len(moderator)>1:
|
||||||
|
f.write(moderator+'\n')
|
||||||
|
|
||||||
|
def removeModerator(baseDir: str,nickname: str):
|
||||||
|
"""Removes a moderator nickname from the file
|
||||||
|
"""
|
||||||
|
moderatorsFile=baseDir+'/accounts/moderators.txt'
|
||||||
|
if not os.path.isfile(moderatorsFile):
|
||||||
|
return
|
||||||
|
with open(moderatorsFile, "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
with open(moderatorsFile, "w") as f:
|
||||||
|
for moderator in lines:
|
||||||
|
moderator=moderator.strip('\n')
|
||||||
|
if len(moderator)>1 and moderator!=nickname:
|
||||||
|
f.write(moderator+'\n')
|
||||||
|
|
||||||
def setRole(baseDir: str,nickname: str,domain: str, \
|
def setRole(baseDir: str,nickname: str,domain: str, \
|
||||||
project: str,role: str) -> bool:
|
project: str,role: str) -> bool:
|
||||||
"""Set a person's role within a project
|
"""Set a person's role within a project
|
||||||
|
@ -30,12 +63,18 @@ def setRole(baseDir: str,nickname: str,domain: str, \
|
||||||
with open(actorFilename, 'r') as fp:
|
with open(actorFilename, 'r') as fp:
|
||||||
actorJson=commentjson.load(fp)
|
actorJson=commentjson.load(fp)
|
||||||
if role:
|
if role:
|
||||||
|
# add the role
|
||||||
|
if project=='instance' and 'role'=='moderator':
|
||||||
|
addModerator(baseDir,nickname)
|
||||||
if actorJson['roles'].get(project):
|
if actorJson['roles'].get(project):
|
||||||
if role not in actorJson['roles'][project]:
|
if role not in actorJson['roles'][project]:
|
||||||
actorJson['roles'][project].append(role)
|
actorJson['roles'][project].append(role)
|
||||||
else:
|
else:
|
||||||
actorJson['roles'][project]=[role]
|
actorJson['roles'][project]=[role]
|
||||||
else:
|
else:
|
||||||
|
# remove the role
|
||||||
|
if project=='instance':
|
||||||
|
removeModerator(baseDir,nickname)
|
||||||
if actorJson['roles'].get(project):
|
if actorJson['roles'].get(project):
|
||||||
actorJson['roles'][project].remove(role)
|
actorJson['roles'][project].remove(role)
|
||||||
# if the project contains no roles then remove it
|
# if the project contains no roles then remove it
|
||||||
|
|
|
@ -319,11 +319,16 @@ def htmlTermsOfService(baseDir: str,httpPrefix: str,domainFull: str) -> str:
|
||||||
def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
||||||
replyStr=''
|
replyStr=''
|
||||||
if not path.endswith('/newshare'):
|
if not path.endswith('/newshare'):
|
||||||
if not inReplyTo:
|
if not path.endswith('/newreport'):
|
||||||
newPostText='<p class="new-post-text">Enter your post text below.</p>'
|
if not inReplyTo:
|
||||||
|
newPostText='<p class="new-post-text">Enter your post text below.</p>'
|
||||||
|
else:
|
||||||
|
newPostText='<p class="new-post-text">Enter your reply to <a href="'+inReplyTo+'">this post</a> below.</p>'
|
||||||
|
replyStr='<input type="hidden" name="replyTo" value="'+inReplyTo+'">'
|
||||||
else:
|
else:
|
||||||
newPostText='<p class="new-post-text">Enter your reply to <a href="'+inReplyTo+'">this post</a> below.</p>'
|
newPostText= \
|
||||||
replyStr='<input type="hidden" name="replyTo" value="'+inReplyTo+'">'
|
'<p class="new-post-text">Enter your report below.</p>' \
|
||||||
|
'<p class="new-post-subtext">This message <i>only goes to moderators</i>, even if it mentions other fediverse addresses.</p>'
|
||||||
else:
|
else:
|
||||||
newPostText='<p class="new-post-text">Enter the details for your shared item below.</p>'
|
newPostText='<p class="new-post-text">Enter the details for your shared item below.</p>'
|
||||||
|
|
||||||
|
@ -334,7 +339,7 @@ def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
||||||
with open(baseDir+'/epicyon-profile.css', 'r') as cssFile:
|
with open(baseDir+'/epicyon-profile.css', 'r') as cssFile:
|
||||||
newPostCSS = cssFile.read()
|
newPostCSS = cssFile.read()
|
||||||
|
|
||||||
pathBase=path.replace('/newpost','').replace('/newshare','').replace('/newunlisted','').replace('/newfollowers','').replace('/newdm','')
|
pathBase=path.replace('/newreport','').replace('/newpost','').replace('/newshare','').replace('/newunlisted','').replace('/newfollowers','').replace('/newdm','')
|
||||||
|
|
||||||
scopeIcon='scope_public.png'
|
scopeIcon='scope_public.png'
|
||||||
scopeDescription='Public'
|
scopeDescription='Public'
|
||||||
|
@ -354,6 +359,10 @@ def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
||||||
scopeIcon='scope_dm.png'
|
scopeIcon='scope_dm.png'
|
||||||
scopeDescription='Direct Message'
|
scopeDescription='Direct Message'
|
||||||
endpoint='newdm'
|
endpoint='newdm'
|
||||||
|
if path.endswith('/newreport'):
|
||||||
|
scopeIcon='scope_report.png'
|
||||||
|
scopeDescription='Report'
|
||||||
|
endpoint='newreport'
|
||||||
if path.endswith('/newshare'):
|
if path.endswith('/newshare'):
|
||||||
scopeIcon='scope_share.png'
|
scopeIcon='scope_share.png'
|
||||||
scopeDescription='Shared Item'
|
scopeDescription='Shared Item'
|
||||||
|
@ -399,7 +408,8 @@ def htmlNewPost(baseDir: str,path: str,inReplyTo: str,mentions: []) -> str:
|
||||||
' <a href="'+pathBase+'/newpost"><img src="/icons/scope_public.png"/><b>Public</b><br>Visible to anyone</a>' \
|
' <a href="'+pathBase+'/newpost"><img src="/icons/scope_public.png"/><b>Public</b><br>Visible to anyone</a>' \
|
||||||
' <a href="'+pathBase+'/newunlisted"><img src="/icons/scope_unlisted.png"/><b>Unlisted</b><br>Not on public timeline</a>' \
|
' <a href="'+pathBase+'/newunlisted"><img src="/icons/scope_unlisted.png"/><b>Unlisted</b><br>Not on public timeline</a>' \
|
||||||
' <a href="'+pathBase+'/newfollowers"><img src="/icons/scope_followers.png"/><b>Followers Only</b><br>Only to followers</a>' \
|
' <a href="'+pathBase+'/newfollowers"><img src="/icons/scope_followers.png"/><b>Followers Only</b><br>Only to followers</a>' \
|
||||||
' <a href="'+pathBase+'/newdm"><img src="/icons/scope_dm.png"/><b>Direct Message</b><br>Only to mentioned people</a>'+ \
|
' <a href="'+pathBase+'/newdm"><img src="/icons/scope_dm.png"/><b>Direct Message</b><br>Only to mentioned people</a>' \
|
||||||
|
' <a href="'+pathBase+'/newreport"><img src="/icons/scope_report.png"/><b>Report</b><br>Send to moderators</a>'+ \
|
||||||
shareOptionOnDropdown+ \
|
shareOptionOnDropdown+ \
|
||||||
' </div>' \
|
' </div>' \
|
||||||
' </div>' \
|
' </div>' \
|
||||||
|
|
Loading…
Reference in New Issue