merge-requests/20/merge
Bob Mottram 2021-07-05 21:24:43 +01:00
parent f6cbb6c340
commit 5de4310b8c
5 changed files with 81 additions and 156 deletions

View File

@ -253,8 +253,7 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
if faviconUrl:
faviconLink = \
'<img loading="lazy" src="' + faviconUrl + '" ' + \
'alt="" ' + \
_getBrokenFavSubstitute() + '/>'
'alt="" ' + _getBrokenFavSubstitute() + '/>'
moderatedItem = item[5]
htmlStr += separatorStr
if moderatedItem and 'vote:' + nickname in item[2]:
@ -270,8 +269,7 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
'<a href="' + url + '" target="_blank" ' + \
'rel="nofollow noopener noreferrer">' + \
'<span class="newswireItemVotedOn">' + \
faviconLink + title + \
'</span></a>' + totalVotesStr
faviconLink + title + '</span></a>' + totalVotesStr
if moderator:
htmlStr += \
' ' + dateShown + '<a href="/users/' + nickname + \
@ -312,8 +310,7 @@ def _htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
htmlStr += '<p class="newswireItem">' + \
'<a href="' + url + '" target="_blank" ' + \
'rel="nofollow noopener noreferrer">' + \
faviconLink + title + '</a>' + \
totalVotesStr
faviconLink + title + '</a>' + totalVotesStr
htmlStr += ' <span class="newswireDate">'
htmlStr += dateShown + '</span></p>\n'

View File

@ -137,8 +137,7 @@ def htmlConfirmRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str,
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
sharesStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
sharesStr += '<div class="follow">\n'
sharesStr += ' <div class="followAvatar">\n'
@ -186,8 +185,7 @@ def htmlConfirmFollow(cssCache: {}, translate: {}, baseDir: str,
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
followStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
followStr += '<div class="follow">\n'
followStr += ' <div class="followAvatar">\n'
@ -232,8 +230,7 @@ def htmlConfirmUnfollow(cssCache: {}, translate: {}, baseDir: str,
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
followStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
followStr += '<div class="follow">\n'
followStr += ' <div class="followAvatar">\n'
@ -279,8 +276,7 @@ def htmlConfirmUnblock(cssCache: {}, translate: {}, baseDir: str,
if os.path.isfile(baseDir + '/follow.css'):
cssFilename = baseDir + '/follow.css'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
blockStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
blockStr += '<div class="block">\n'
blockStr += ' <div class="blockAvatar">\n'

View File

@ -26,35 +26,35 @@ def _htmlFollowingDataList(baseDir: str, nickname: str,
listStr = '<datalist id="followingHandles">\n'
followingFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/following.txt'
msg = None
if os.path.isfile(followingFilename):
with open(followingFilename, 'r') as followingFile:
msg = followingFile.read()
# add your own handle, so that you can send DMs
# to yourself as reminders
msg += nickname + '@' + domainFull + '\n'
# include petnames
petnamesFilename = \
baseDir + '/accounts/' + \
nickname + '@' + domain + '/petnames.txt'
if os.path.isfile(petnamesFilename):
followingList = []
with open(petnamesFilename, 'r') as petnamesFile:
petStr = petnamesFile.read()
# extract each petname and append it
petnamesList = petStr.split('\n')
for pet in petnamesList:
followingList.append(pet.split(' ')[0])
# add the following.txt entries
followingList += msg.split('\n')
else:
# no petnames list exists - just use following.txt
followingList = msg.split('\n')
followingList.sort()
if followingList:
for followingAddress in followingList:
if followingAddress:
listStr += \
'<option>@' + followingAddress + '</option>\n'
if msg:
# include petnames
petnamesFilename = \
baseDir + '/accounts/' + nickname + '@' + domain + '/petnames.txt'
if os.path.isfile(petnamesFilename):
followingList = []
with open(petnamesFilename, 'r') as petnamesFile:
petStr = petnamesFile.read()
# extract each petname and append it
petnamesList = petStr.split('\n')
for pet in petnamesList:
followingList.append(pet.split(' ')[0])
# add the following.txt entries
followingList += msg.split('\n')
else:
# no petnames list exists - just use following.txt
followingList = msg.split('\n')
followingList.sort()
if followingList:
for followingAddress in followingList:
if followingAddress:
listStr += '<option>@' + followingAddress + '</option>\n'
listStr += '</datalist>\n'
return listStr
@ -84,8 +84,7 @@ def _htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
dropDownContent += ' <label for="my-newPostDropdown"\n'
dropDownContent += ' data-toggle="newPostDropdown">\n'
dropDownContent += ' <img loading="lazy" alt="" title="" src="/' + \
'icons/' + scopeIcon + '"/><b>' + \
scopeDescription + '</b></label>\n'
'icons/' + scopeIcon + '"/><b>' + scopeDescription + '</b></label>\n'
if noDropDown:
dropDownContent += '</div></nav>\n'
@ -144,12 +143,6 @@ def _htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
'icons/scope_reminder.png"/><b>' + \
translate['Reminder'] + '</b><br>' + \
translate['Scheduled note to yourself'] + '</a></li>\n'
# dropDownContent += \
# '<li><a href="' + pathBase + dropdownEventSuffix + \
# '"><img loading="lazy" alt="" title="" src="/' + \
# 'icons/scope_event.png"/><b>' + \
# translate['Event'] + '</b><br>' + \
# translate['Create an event'] + '</a></li>\n'
dropDownContent += \
'<li><a href="' + pathBase + dropdownReportSuffix + \
'" accesskey="' + accessKeys['reportButton'] + '">' + \
@ -230,8 +223,7 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
showPublicOnDropdown = False
else:
newPostText = \
'<h1>' + \
translate['Write your report below.'] + '</h1>\n'
'<h1>' + translate['Write your report below.'] + '</h1>\n'
# custom report header with any additional instructions
if os.path.isfile(baseDir + '/accounts/report.txt'):
@ -319,7 +311,6 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
translate['Subject or Content Warning (optional)'] + '...'
placeholderMentions = ''
if inReplyTo:
# mentionsAndContent = getMentionsString(content)
placeholderMentions = \
translate['Replying to'] + '...'
placeholderMessage = translate['Write something'] + '...'
@ -582,8 +573,7 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
dateAndLocation += '<input type="text" name="category">\n'
dateAndLocation += '</div>\n'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
newPostForm = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
newPostForm += \
@ -711,17 +701,11 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
submitText + '" ' + \
'accesskey="' + accessKeys['submitButton'] + '"></td>\n'
newPostForm += ' </tr>\n'
newPostForm += '</table>\n'
newPostForm += ' </tr>\n</table>\n'
newPostForm += ' </div>\n'
newPostForm += ' <div class="containerSubmitNewPost"><center>\n'
# newPostForm += \
# ' <a href="' + pathBase + \
# '/inbox"><button class="cancelbtn">' + \
# translate['Go Back'] + '</button></a>\n'
newPostForm += ' </center></div>\n'
newPostForm += replyStr
@ -777,14 +761,13 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
if not mediaInstance or replyStr:
newPostForm += newPostImageSection
newPostForm += ' <div class="container">\n'
newPostForm += \
' <div class="container">\n' + \
' <input type="submit" name="submitPost" value="' + \
submitText + '">\n'
newPostForm += ' </div>\n'
newPostForm += ' </div>\n'
newPostForm += '</form>\n'
submitText + '">\n' + \
' </div>\n' + \
' </div>\n' + \
'</form>\n'
if not reportUrl:
newPostForm = \

View File

@ -128,22 +128,24 @@ def htmlFrontScreen(rssIconAtTop: bool,
if loginButton:
profileHeaderStr += '<center>' + loginButton + '</center>\n'
profileHeaderStr += '<table class="timeline">\n'
profileHeaderStr += ' <colgroup>\n'
profileHeaderStr += ' <col span="1" class="column-left">\n'
profileHeaderStr += ' <col span="1" class="column-center">\n'
profileHeaderStr += ' <col span="1" class="column-right">\n'
profileHeaderStr += ' </colgroup>\n'
profileHeaderStr += ' <tbody>\n'
profileHeaderStr += ' <tr>\n'
profileHeaderStr += ' <td valign="top" class="col-left">\n'
profileHeaderStr += \
'<table class="timeline">\n' + \
' <colgroup>\n' + \
' <col span="1" class="column-left">\n' + \
' <col span="1" class="column-center">\n' + \
' <col span="1" class="column-right">\n' + \
' </colgroup>\n' + \
' <tbody>\n' + \
' <tr>\n' + \
' <td valign="top" class="col-left">\n'
profileHeaderStr += \
getLeftColumnContent(baseDir, 'news', domainFull,
httpPrefix, translate,
False, False, None, rssIconAtTop, True,
True, theme, accessKeys)
profileHeaderStr += ' </td>\n'
profileHeaderStr += ' <td valign="top" class="col-center">\n'
profileHeaderStr += \
' </td>\n' + \
' <td valign="top" class="col-center">\n'
profileStr = profileHeaderStr
@ -177,10 +179,11 @@ def htmlFrontScreen(rssIconAtTop: bool,
False, None, False, False,
False, True, authorized, True, theme,
defaultTimeline, accessKeys)
profileFooterStr += ' </td>\n'
profileFooterStr += ' </tr>\n'
profileFooterStr += ' </tbody>\n'
profileFooterStr += '</table>\n'
profileFooterStr += \
' </td>\n' + \
' </tr>\n' + \
' </tbody>\n' + \
'</table>\n'
instanceTitle = \
getConfigParam(baseDir, 'instanceTitle')

View File

@ -29,17 +29,19 @@ def getHashtagCategoriesFeed(baseDir: str,
if not hashtagCategories:
return None
rssStr = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
rssStr += "<rss version=\"2.0\">\n"
rssStr += '<channel>\n'
rssStr += ' <title>#categories</title>\n'
rssStr = \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n" + \
"<rss version=\"2.0\">\n" + \
'<channel>\n' + \
' <title>#categories</title>\n'
rssDateStr = \
datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S UT")
for categoryStr, hashtagList in hashtagCategories.items():
rssStr += '<item>\n'
rssStr += ' <title>' + categoryStr + '</title>\n'
rssStr += \
'<item>\n' + \
' <title>' + categoryStr + '</title>\n'
listStr = ''
for hashtag in hashtagList:
if ':' in hashtag:
@ -47,75 +49,18 @@ def getHashtagCategoriesFeed(baseDir: str,
if '&' in hashtag:
continue
listStr += hashtag + ' '
rssStr += ' <description>' + listStr.strip() + '</description>\n'
rssStr += ' <link/>\n'
rssStr += ' <pubDate>' + rssDateStr + '</pubDate>\n'
rssStr += '</item>\n'
rssStr += \
' <description>' + listStr.strip() + '</description>\n' + \
' <link/>\n' + \
' <pubDate>' + rssDateStr + '</pubDate>\n' + \
'</item>\n'
rssStr += '</channel>\n'
rssStr += '</rss>\n'
rssStr += \
'</channel>\n' + \
'</rss>\n'
return rssStr
def _getHashtagDomainMax(domainHistogram: {}) -> str:
"""Returns the domain with the maximum number of hashtags
"""
maxCount = 1
maxDomain = None
for domain, count in domainHistogram.items():
if count > maxCount:
maxDomain = domain
maxCount = count
return maxDomain
def _getHashtagDomainHistogram(domainHistogram: {}, translate: {}) -> str:
"""Returns the html for a histogram of domains
from which hashtags are coming
"""
totalCount = 0
for domain, count in domainHistogram.items():
totalCount += count
if totalCount == 0:
return ''
htmlStr = ''
histogramHeaderStr = '<br><br><center>\n'
histogramHeaderStr += ' <h1>' + translate['Hashtag origins'] + '</h1>\n'
histogramHeaderStr += ' <table class="domainHistogram">\n'
histogramHeaderStr += ' <colgroup>\n'
histogramHeaderStr += ' <col span="1" class="domainHistogramLeft">\n'
histogramHeaderStr += ' <col span="1" class="domainHistogramRight">\n'
histogramHeaderStr += ' </colgroup>\n'
histogramHeaderStr += ' <tbody>\n'
histogramHeaderStr += ' <tr>\n'
leftColStr = ''
rightColStr = ''
for i in range(len(domainHistogram)):
domain = _getHashtagDomainMax(domainHistogram)
if not domain:
break
percent = int(domainHistogram[domain] * 100 / totalCount)
if histogramHeaderStr:
htmlStr += histogramHeaderStr
histogramHeaderStr = None
leftColStr += str(percent) + '%<br>'
rightColStr += domain + '<br>'
del domainHistogram[domain]
if htmlStr:
htmlStr += ' <td>' + leftColStr + '</td>\n'
htmlStr += ' <td>' + rightColStr + '</td>\n'
htmlStr += ' </tr>\n'
htmlStr += ' </tbody>\n'
htmlStr += ' </table>\n'
htmlStr += '</center>\n'
return htmlStr
def htmlHashTagSwarm(baseDir: str, actor: str, translate: {}) -> str:
"""Returns a tag swarm of today's hashtags
"""
@ -244,7 +189,6 @@ def htmlHashTagSwarm(baseDir: str, actor: str, translate: {}) -> str:
getContentWarningButton('alltags', translate, tagSwarmStr)
tagSwarmHtml = categorySwarmStr + tagSwarmStr.strip() + '\n'
# tagSwarmHtml += _getHashtagDomainHistogram(domainHistogram, translate)
return tagSwarmHtml
@ -279,10 +223,11 @@ def htmlSearchHashtagCategory(cssCache: {}, translate: {},
htmlStr += '<img loading="lazy" class="timeline-banner" src="' + \
actor + '/' + searchBannerFile + '" alt="" /></a>\n'
htmlStr += '<div class="follow">'
htmlStr += '<center><br><br><br>'
htmlStr += '<h1><a href="' + actor + '/search"><b>'
htmlStr += translate['Category'] + ': ' + categoryStr + '</b></a></h1>'
htmlStr += \
'<div class="follow">' + \
'<center><br><br><br>' + \
'<h1><a href="' + actor + '/search"><b>' + \
translate['Category'] + ': ' + categoryStr + '</b></a></h1>'
hashtagsDict = getHashtagCategories(baseDir, True, categoryStr)
if hashtagsDict:
@ -293,7 +238,8 @@ def htmlSearchHashtagCategory(cssCache: {}, translate: {},
'<a href="' + actor + '/tags/' + tagName + \
'" class="hashtagswarm">' + tagName + '</a>\n'
htmlStr += '</center>'
htmlStr += '</div>'
htmlStr += \
'</center>' + \
'</div>'
htmlStr += htmlFooter()
return htmlStr