Edit screen for newswire

main
Bob Mottram 2020-10-04 10:22:27 +01:00
parent a6209907ff
commit bf04691ba2
17 changed files with 255 additions and 17 deletions

159
daemon.py
View File

@ -61,6 +61,7 @@ from person import removeAccount
from person import canRemovePost from person import canRemovePost
from person import personSnooze from person import personSnooze
from person import personUnsnooze from person import personUnsnooze
from posts import isModerator
from posts import mutePost from posts import mutePost
from posts import unmutePost from posts import unmutePost
from posts import createQuestionPost from posts import createQuestionPost
@ -145,6 +146,7 @@ from webinterface import htmlUnfollowConfirm
from webinterface import htmlProfileAfterSearch from webinterface import htmlProfileAfterSearch
from webinterface import htmlEditProfile from webinterface import htmlEditProfile
from webinterface import htmlEditLinks from webinterface import htmlEditLinks
from webinterface import htmlEditNewswire
from webinterface import htmlTermsOfService from webinterface import htmlTermsOfService
from webinterface import htmlSkillsSearch from webinterface import htmlSkillsSearch
from webinterface import htmlHistorySearch from webinterface import htmlHistorySearch
@ -2708,7 +2710,10 @@ class PubServer(BaseHTTPRequestHandler):
# get the nickname # get the nickname
nickname = getNicknameFromActor(actorStr) nickname = getNicknameFromActor(actorStr)
if not nickname: moderator = None
if nickname:
moderator = isModerator(baseDir, nickname)
if not nickname or not moderator:
if callingDomain.endswith('.onion') and \ if callingDomain.endswith('.onion') and \
onionDomain: onionDomain:
actorStr = \ actorStr = \
@ -2717,7 +2722,10 @@ class PubServer(BaseHTTPRequestHandler):
i2pDomain): i2pDomain):
actorStr = \ actorStr = \
'http://' + i2pDomain + usersPath 'http://' + i2pDomain + usersPath
print('WARN: nickname not found in ' + actorStr) if not nickname:
print('WARN: nickname not found in ' + actorStr)
else:
print('WARN: nickname is not a moderator' + actorStr)
self._redirect_headers(actorStr, cookie, callingDomain) self._redirect_headers(actorStr, cookie, callingDomain)
self.server.POSTbusy = False self.server.POSTbusy = False
return return
@ -2789,6 +2797,111 @@ class PubServer(BaseHTTPRequestHandler):
cookie, callingDomain) cookie, callingDomain)
self.server.POSTbusy = False self.server.POSTbusy = False
def _newswireUpdate(self, callingDomain: str, cookie: str,
authorized: bool, path: str,
baseDir: str, httpPrefix: str,
domain: str, domainFull: str,
onionDomain: str, i2pDomain: str, debug: bool,
defaultTimeline: str):
"""Updates the right newswire column of the timeline
"""
usersPath = path.replace('/newswiredata', '')
usersPath = usersPath.replace('/editnewswire', '')
actorStr = httpPrefix + '://' + domainFull + usersPath
if ' boundary=' in self.headers['Content-type']:
boundary = self.headers['Content-type'].split('boundary=')[1]
if ';' in boundary:
boundary = boundary.split(';')[0]
# get the nickname
nickname = getNicknameFromActor(actorStr)
moderator = None
if nickname:
moderator = isModerator(baseDir, nickname)
if not nickname or not moderator:
if callingDomain.endswith('.onion') and \
onionDomain:
actorStr = \
'http://' + onionDomain + usersPath
elif (callingDomain.endswith('.i2p') and
i2pDomain):
actorStr = \
'http://' + i2pDomain + usersPath
if not nickname:
print('WARN: nickname not found in ' + actorStr)
else:
print('WARN: nickname is not a moderator' + actorStr)
self._redirect_headers(actorStr, cookie, callingDomain)
self.server.POSTbusy = False
return
length = int(self.headers['Content-length'])
# check that the POST isn't too large
if length > self.server.maxPostLength:
if callingDomain.endswith('.onion') and \
onionDomain:
actorStr = \
'http://' + onionDomain + usersPath
elif (callingDomain.endswith('.i2p') and
i2pDomain):
actorStr = \
'http://' + i2pDomain + usersPath
print('Maximum newswire data length exceeded ' + str(length))
self._redirect_headers(actorStr, cookie, callingDomain)
self.server.POSTbusy = False
return
try:
# read the bytes of the http form POST
postBytes = self.rfile.read(length)
except SocketError as e:
if e.errno == errno.ECONNRESET:
print('WARN: connection was reset while ' +
'reading bytes from http form POST')
else:
print('WARN: error while reading bytes ' +
'from http form POST')
self.send_response(400)
self.end_headers()
self.server.POSTbusy = False
return
except ValueError as e:
print('ERROR: failed to read bytes for POST')
print(e)
self.send_response(400)
self.end_headers()
self.server.POSTbusy = False
return
newswireFilename = baseDir + '/accounts/newswire.txt'
# extract all of the text fields into a dict
fields = \
extractTextFieldsInPOST(postBytes, boundary, debug)
if fields.get('editedNewswire'):
newswireStr = fields['editedNewswire']
newswireFile = open(newswireFilename, "w+")
if newswireFile:
newswireFile.write(newswireStr)
newswireFile.close()
else:
if os.path.isfile(newswireFilename):
os.remove(newswireFilename)
# redirect back to the default timeline
if callingDomain.endswith('.onion') and \
onionDomain:
actorStr = \
'http://' + onionDomain + usersPath
elif (callingDomain.endswith('.i2p') and
i2pDomain):
actorStr = \
'http://' + i2pDomain + usersPath
self._redirect_headers(actorStr + '/' + defaultTimeline,
cookie, callingDomain)
self.server.POSTbusy = False
def _profileUpdate(self, callingDomain: str, cookie: str, def _profileUpdate(self, callingDomain: str, cookie: str,
authorized: bool, path: str, authorized: bool, path: str,
baseDir: str, httpPrefix: str, baseDir: str, httpPrefix: str,
@ -7478,6 +7591,28 @@ class PubServer(BaseHTTPRequestHandler):
return True return True
return False return False
def _editNewswire(self, callingDomain: str, path: str,
translate: {}, baseDir: str,
httpPrefix: str, domain: str, port: int,
cookie: str) -> bool:
"""Show the newswire from the right column
"""
if '/users/' in path and path.endswith('/editnewswire'):
msg = htmlEditNewswire(translate,
baseDir,
path, domain,
port,
httpPrefix).encode('utf-8')
if msg:
self._set_headers('text/html', len(msg),
cookie, callingDomain)
self._write(msg)
else:
self._404()
self.server.GETbusy = False
return True
return False
def _editEvent(self, callingDomain: str, path: str, def _editEvent(self, callingDomain: str, path: str,
httpPrefix: str, domain: str, domainFull: str, httpPrefix: str, domain: str, domainFull: str,
baseDir: str, translate: {}, baseDir: str, translate: {},
@ -8798,6 +8933,16 @@ class PubServer(BaseHTTPRequestHandler):
cookie): cookie):
return return
# edit newswire from the right column of the timeline
if self._editNewswire(callingDomain, self.path,
self.server.translate,
self.server.baseDir,
self.server.httpPrefix,
self.server.domain,
self.server.port,
cookie):
return
if self._showNewPost(callingDomain, self.path, if self._showNewPost(callingDomain, self.path,
self.server.mediaInstance, self.server.mediaInstance,
self.server.translate, self.server.translate,
@ -10256,6 +10401,16 @@ class PubServer(BaseHTTPRequestHandler):
self.server.defaultTimeline) self.server.defaultTimeline)
return return
if authorized and self.path.endswith('/newswiredata'):
self._newswireUpdate(callingDomain, cookie, authorized, self.path,
self.server.baseDir, self.server.httpPrefix,
self.server.domain,
self.server.domainFull,
self.server.onionDomain,
self.server.i2pDomain, self.server.debug,
self.server.defaultTimeline)
return
self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 3) self._benchmarkPOSTtimings(POSTstartTime, POSTtimings, 3)
# moderator action buttons # moderator action buttons

View File

@ -294,5 +294,6 @@
"Left column image": "صورة العمود الأيسر", "Left column image": "صورة العمود الأيسر",
"Right column image": "صورة العمود الأيمن", "Right column image": "صورة العمود الأيمن",
"RSS feed for this site": "تغذية RSS لهذا الموقع", "RSS feed for this site": "تغذية RSS لهذا الموقع",
"Edit newswire": "" "Edit newswire": "تحرير الأخبار",
"Add RSS feed links below.": "إضافة روابط تغذية RSS أدناه."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Imatge de la columna esquerra", "Left column image": "Imatge de la columna esquerra",
"Right column image": "Imatge de la columna dreta", "Right column image": "Imatge de la columna dreta",
"RSS feed for this site": "Feed RSS per a aquest lloc", "RSS feed for this site": "Feed RSS per a aquest lloc",
"Edit newswire": "" "Edit newswire": "Editeu newswire",
"Add RSS feed links below.": "Afegiu enllaços de canals RSS a continuació."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Delwedd colofn chwith", "Left column image": "Delwedd colofn chwith",
"Right column image": "Delwedd colofn dde", "Right column image": "Delwedd colofn dde",
"RSS feed for this site": "Porthiant RSS ar gyfer y wefan hon", "RSS feed for this site": "Porthiant RSS ar gyfer y wefan hon",
"Edit newswire": "" "Edit newswire": "Golygu newyddion",
"Add RSS feed links below.": "Ychwanegwch ddolenni porthiant RSS isod."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Bild in der linken Spalte", "Left column image": "Bild in der linken Spalte",
"Right column image": "Bild in der rechten Spalte", "Right column image": "Bild in der rechten Spalte",
"RSS feed for this site": "RSS-Feed für diese Site", "RSS feed for this site": "RSS-Feed für diese Site",
"Edit newswire": "" "Edit newswire": "Newswire bearbeiten",
"Add RSS feed links below.": "Fügen Sie unten RSS-Feed-Links hinzu."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Left column image", "Left column image": "Left column image",
"Right column image": "Right column image", "Right column image": "Right column image",
"RSS feed for this site": "RSS feed for this site", "RSS feed for this site": "RSS feed for this site",
"Edit newswire": "Edit newswire" "Edit newswire": "Edit newswire",
"Add RSS feed links below.": "Add RSS feed links below."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Imagen de la columna izquierda", "Left column image": "Imagen de la columna izquierda",
"Right column image": "Imagen de la columna derecha", "Right column image": "Imagen de la columna derecha",
"RSS feed for this site": "Fuente RSS para este sitio", "RSS feed for this site": "Fuente RSS para este sitio",
"Edit newswire": "" "Edit newswire": "Editar newswire",
"Add RSS feed links below.": "Agregue los enlaces de fuentes RSS a continuación."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Image de la colonne de gauche", "Left column image": "Image de la colonne de gauche",
"Right column image": "Image de la colonne de droite", "Right column image": "Image de la colonne de droite",
"RSS feed for this site": "Flux RSS de ce site", "RSS feed for this site": "Flux RSS de ce site",
"Edit newswire": "" "Edit newswire": "Modifier le fil d'actualité",
"Add RSS feed links below.": "Ajoutez des liens de flux RSS ci-dessous."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Íomhá colún ar chlé", "Left column image": "Íomhá colún ar chlé",
"Right column image": "Íomhá colún ar dheis", "Right column image": "Íomhá colún ar dheis",
"RSS feed for this site": "Fotha RSS don láithreán seo", "RSS feed for this site": "Fotha RSS don láithreán seo",
"Edit newswire": "" "Edit newswire": "Cuir sreang nuachta in eagar",
"Add RSS feed links below.": "Cuir naisc beatha RSS thíos."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "बाएं स्तंभ की छवि", "Left column image": "बाएं स्तंभ की छवि",
"Right column image": "राइट कॉलम छवि", "Right column image": "राइट कॉलम छवि",
"RSS feed for this site": "इस साइट के लिए आरएसएस फ़ीड", "RSS feed for this site": "इस साइट के लिए आरएसएस फ़ीड",
"Edit newswire": "" "Edit newswire": "नवांश संपादित करें",
"Add RSS feed links below.": "नीचे आरएसएस फ़ीड लिंक जोड़ें।"
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Immagine della colonna di sinistra", "Left column image": "Immagine della colonna di sinistra",
"Right column image": "Immagine della colonna di destra", "Right column image": "Immagine della colonna di destra",
"RSS feed for this site": "Feed RSS per questo sito", "RSS feed for this site": "Feed RSS per questo sito",
"Edit newswire": "" "Edit newswire": "Modifica newswire",
"Add RSS feed links below.": "Aggiungi i link ai feed RSS di seguito."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "左の列の画像", "Left column image": "左の列の画像",
"Right column image": "右の列の画像", "Right column image": "右の列の画像",
"RSS feed for this site": "このサイトのRSSフィード", "RSS feed for this site": "このサイトのRSSフィード",
"Edit newswire": "" "Edit newswire": "ニュースワイヤーを編集",
"Add RSS feed links below.": "以下にRSSフィードリンクを追加します。"
} }

View File

@ -290,5 +290,6 @@
"Left column image": "Left column image", "Left column image": "Left column image",
"Right column image": "Right column image", "Right column image": "Right column image",
"RSS feed for this site": "RSS feed for this site", "RSS feed for this site": "RSS feed for this site",
"Edit newswire": "Edit newswire" "Edit newswire": "Edit newswire",
"Add RSS feed links below.": "Add RSS feed links below."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Imagem da coluna esquerda", "Left column image": "Imagem da coluna esquerda",
"Right column image": "Imagem da coluna direita", "Right column image": "Imagem da coluna direita",
"RSS feed for this site": "Feed RSS para este site", "RSS feed for this site": "Feed RSS para este site",
"Edit newswire": "" "Edit newswire": "Editar notícias",
"Add RSS feed links below.": "Adicione links de feed RSS abaixo."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "Изображение в левом столбце", "Left column image": "Изображение в левом столбце",
"Right column image": "Изображение в правом столбце", "Right column image": "Изображение в правом столбце",
"RSS feed for this site": "RSS-канал для этого сайта", "RSS feed for this site": "RSS-канал для этого сайта",
"Edit newswire": "" "Edit newswire": "Редактировать ленту новостей",
"Add RSS feed links below.": "Добавьте ссылки на RSS-канал ниже."
} }

View File

@ -294,5 +294,6 @@
"Left column image": "左栏图片", "Left column image": "左栏图片",
"Right column image": "右栏图片", "Right column image": "右栏图片",
"RSS feed for this site": "该站点的RSS feed", "RSS feed for this site": "该站点的RSS feed",
"Edit newswire": "" "Edit newswire": "编辑新闻专线",
"Add RSS feed links below.": "在下面添加RSS feed链接。"
} }

View File

@ -1274,6 +1274,74 @@ def htmlEditLinks(translate: {}, baseDir: str, path: str,
return editLinksForm return editLinksForm
def htmlEditNewswire(translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str) -> str:
"""Shows the edit newswire screen
"""
if '/users/' not in path:
return ''
pathOriginal = path
path = path.replace('/inbox', '').replace('/outbox', '')
path = path.replace('/shares', '')
nickname = getNicknameFromActor(path)
if not nickname:
return ''
# is the user a moderator?
if not isModerator(baseDir, nickname):
return ''
cssFilename = baseDir + '/epicyon-links.css'
if os.path.isfile(baseDir + '/links.css'):
cssFilename = baseDir + '/links.css'
with open(cssFilename, 'r') as cssFile:
editCSS = cssFile.read()
if httpPrefix != 'https':
editCSS = \
editCSS.replace('https://', httpPrefix + '://')
editNewswireForm = htmlHeader(cssFilename, editCSS)
editNewswireForm += \
'<form enctype="multipart/form-data" method="POST" ' + \
'accept-charset="UTF-8" action="' + path + '/newswiredata">\n'
editNewswireForm += \
' <div class="vertical-center">\n'
editNewswireForm += \
' <p class="new-post-text">' + translate['Edit newswire'] + '</p>'
editNewswireForm += \
' <div class="container">\n'
editNewswireForm += \
' <a href="' + pathOriginal + '"><button class="cancelbtn">' + \
translate['Go Back'] + '</button></a>\n'
editNewswireForm += \
' <input type="submit" name="submitNewswire" value="' + \
translate['Submit'] + '">\n'
editNewswireForm += \
' </div>\n'
newswireFilename = baseDir + '/accounts/newswire.txt'
newswireStr = ''
if os.path.isfile(newswireFilename):
with open(newswireFilename, 'r') as fp:
newswireStr = fp.read()
editNewswireForm += \
'<div class="container">'
editNewswireForm += \
' ' + \
translate['Add RSS feed links below.'] + \
'<br>'
editNewswireForm += \
' <textarea id="message" name="editedNewswire" ' + \
'style="height:500px">' + newswireStr + '</textarea>'
editNewswireForm += \
'</div>'
editNewswireForm += htmlFooter()
return editNewswireForm
def htmlEditProfile(translate: {}, baseDir: str, path: str, def htmlEditProfile(translate: {}, baseDir: str, path: str,
domain: str, port: int, httpPrefix: str) -> str: domain: str, port: int, httpPrefix: str) -> str:
"""Shows the edit profile screen """Shows the edit profile screen