forked from indymedia/epicyon
905 lines
40 KiB
Python
905 lines
40 KiB
Python
__filename__ = "webapp_timeline.py"
|
|
__author__ = "Bob Mottram"
|
|
__license__ = "AGPL3+"
|
|
__version__ = "1.1.0"
|
|
__maintainer__ = "Bob Mottram"
|
|
__email__ = "bob@freedombone.net"
|
|
__status__ = "Production"
|
|
|
|
import os
|
|
import time
|
|
from utils import getFullDomain
|
|
from utils import isEditor
|
|
from utils import removeIdEnding
|
|
from utils import getConfigParam
|
|
from follow import followerApprovalActive
|
|
from person import isPersonSnoozed
|
|
from webapp_utils import htmlPostSeparator
|
|
from webapp_utils import getBannerFile
|
|
from webapp_utils import htmlHeaderWithExternalStyle, htmlHeaderWithExternalStyles
|
|
from webapp_utils import htmlHeaderBanner, htmlFooter
|
|
from webapp_utils import sharesTimelineJson
|
|
from webapp_utils import htmlHighlightLabel
|
|
from webapp_post import preparePostFromHtmlCache
|
|
from webapp_post import individualPostAsHtml
|
|
from webapp_column_left import getLeftColumnContent
|
|
from webapp_column_right import getRightColumnContent
|
|
from webapp_headerbuttons import headerButtonsTimeline
|
|
from posts import isModerator
|
|
|
|
|
|
def _logTimelineTiming(enableTimingLog: bool, timelineStartTime,
|
|
boxName: str, debugId: str) -> None:
|
|
"""Create a log of timings for performance tuning
|
|
"""
|
|
if not enableTimingLog:
|
|
return
|
|
timeDiff = int((time.time() - timelineStartTime) * 1000)
|
|
if timeDiff > 100:
|
|
print('TIMELINE TIMING ' +
|
|
boxName + ' ' + debugId + ' = ' + str(timeDiff))
|
|
|
|
|
|
def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int,
|
|
itemsPerPage: int, session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, timelineJson: {},
|
|
boxName: str, allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
manuallyApproveFollowers: bool,
|
|
minimal: bool,
|
|
YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, moderator: bool,
|
|
editor: bool,
|
|
positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool,
|
|
moderationActionStr: str,
|
|
theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the timeline as html
|
|
"""
|
|
enableTimingLog = False
|
|
|
|
timelineStartTime = time.time()
|
|
|
|
separatorStr = ''
|
|
if boxName != 'tlmedia':
|
|
separatorStr = htmlPostSeparator(baseDir, None)
|
|
|
|
cssFiles = []
|
|
|
|
# TODO: Clean up - default load only one base css file
|
|
# default css
|
|
cssFiles.append(baseDir + '/epicyon-profile.css')
|
|
if os.path.isfile(baseDir + '/epicyon.css'):
|
|
cssFiles[0] = baseDir + '/epicyon.css'
|
|
|
|
# TODO: Clean up and remove this override
|
|
cssFiles[0] = 'base.css'
|
|
|
|
# Get theme-specific css if exists - must be named '<theme-name>.css'
|
|
themeName = getConfigParam(baseDir, 'theme')
|
|
|
|
themePath = f'{baseDir}/theme/{themeName}.css'
|
|
if os.path.isfile(themePath):
|
|
cssFiles.append('theme/' + themeName + '.css')
|
|
|
|
# filename of the banner shown at the top
|
|
bannerFile, bannerFilename = \
|
|
getBannerFile(baseDir, nickname, domain, theme)
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '1')
|
|
|
|
# is the user a moderator?
|
|
if not moderator:
|
|
moderator = isModerator(baseDir, nickname)
|
|
|
|
# is the user a site editor?
|
|
if not editor:
|
|
editor = isEditor(baseDir, nickname)
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '2')
|
|
|
|
# get the full domain, including any port number
|
|
fullDomain = getFullDomain(domain, port)
|
|
|
|
usersPath = '/users/' + nickname
|
|
actor = httpPrefix + '://' + fullDomain + usersPath
|
|
|
|
showIndividualPostIcons = True
|
|
|
|
# benchmark 3
|
|
timeDiff = int((time.time() - timelineStartTime) * 1000)
|
|
if timeDiff > 100:
|
|
print('TIMELINE TIMING ' + boxName + ' 3 = ' + str(timeDiff))
|
|
|
|
# NOTE: This uses a variant function for multiple CSS files
|
|
# TODO: Figure out a better approach
|
|
tlStr = htmlHeaderWithExternalStyles(cssFiles)
|
|
|
|
# benchmark 4
|
|
timeDiff = int((time.time() - timelineStartTime) * 1000)
|
|
if timeDiff > 100:
|
|
print('TIMELINE TIMING ' + boxName + ' 4 = ' + str(timeDiff))
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '4')
|
|
|
|
# if this is a 'News' instance and we are viewing the features timeline
|
|
newsHeader = False
|
|
if defaultTimeline == 'tlfeatures':# and boxName == 'tlfeatures':
|
|
newsHeader = True
|
|
|
|
# Certain Epciyon pages should only be accessible via the 'User' page for News instances
|
|
# TODO: The 'new...' pages appear to require handling elsewhere
|
|
userPages = ['inbox', 'outbox', 'dm', 'tlreplies', 'tlblogs', 'tlmedia', 'tlshares', \
|
|
'tlsaves', 'tlevents', 'tlbookmarks', 'moderation', 'search', \
|
|
'followers', 'newfollowers', 'newdm', 'newpost', 'newblog', 'newevent', 'editprofile']
|
|
|
|
# Banner and "profile toggle" link
|
|
|
|
tlStr += htmlHeaderBanner(defaultTimeline, boxName, baseDir, usersPath,
|
|
authorized, translate, userPages, bannerFile);
|
|
|
|
if not newsHeader and fullWidthTimelineButtonHeader:
|
|
tlStr += \
|
|
headerButtonsTimeline(defaultTimeline, boxName, pageNumber,
|
|
translate, usersPath,
|
|
minimal, moderator,
|
|
manuallyApproveFollowers,
|
|
baseDir, nickname,
|
|
domain, timelineStartTime,
|
|
iconsAsButtons, userPages)
|
|
|
|
# TODO: Should probably use a more generic class, easier to re-use and help simplify CSS
|
|
# NOTE: Related also to class "page" added to 'webapp_create_post.py'
|
|
# start the timeline
|
|
tlStr += '<div class="timeline">\n'
|
|
|
|
domainFull = domain
|
|
if port:
|
|
if port != 80 and port != 443:
|
|
domainFull = domain + ':' + str(port)
|
|
|
|
# For 'News' instances, only show standard "buttons" on "user" pages
|
|
if defaultTimeline == 'tlfeatures' and boxName in userPages:
|
|
tlStr += \
|
|
headerButtonsTimeline(defaultTimeline, boxName, pageNumber,
|
|
translate, usersPath,
|
|
minimal, moderator,
|
|
manuallyApproveFollowers,
|
|
baseDir, nickname,
|
|
domain, timelineStartTime,
|
|
iconsAsButtons, userPages)
|
|
|
|
else:
|
|
# left column
|
|
leftColumnStr = \
|
|
getLeftColumnContent(baseDir, nickname, domainFull,
|
|
httpPrefix, translate,
|
|
editor, False, None, rssIconAtTop,
|
|
True, False, theme)
|
|
tlStr += ' <div class="section links">\n' + \
|
|
leftColumnStr + ' </div>\n'
|
|
|
|
# center column containing posts
|
|
tlStr += ' <div class="section main">\n'
|
|
|
|
if not defaultTimeline == 'tlfeatures' and not fullWidthTimelineButtonHeader:
|
|
tlStr += \
|
|
headerButtonsTimeline(defaultTimeline, boxName, pageNumber,
|
|
translate, usersPath,
|
|
minimal, moderator,
|
|
manuallyApproveFollowers,
|
|
baseDir, nickname,
|
|
domain, timelineStartTime,
|
|
iconsAsButtons, userPages)
|
|
|
|
# second row of buttons for moderator actions
|
|
if moderator and boxName == 'moderation':
|
|
tlStr += \
|
|
'<form method="POST" action="/users/' + \
|
|
nickname + '/moderationaction">'
|
|
tlStr += '<div class="container">\n'
|
|
idx = 'Nickname or URL. Block using *@domain or nickname@domain'
|
|
tlStr += \
|
|
' <b>' + translate[idx] + '</b><br>\n'
|
|
if moderationActionStr:
|
|
tlStr += ' <input type="text" ' + \
|
|
'name="moderationAction" value="' + \
|
|
moderationActionStr + '" autofocus><br>\n'
|
|
else:
|
|
tlStr += ' <input type="text" ' + \
|
|
'name="moderationAction" value="" autofocus><br>\n'
|
|
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Information about current blocks/suspensions'] + \
|
|
'" name="submitInfo" value="' + translate['Info'] + '">\n'
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Remove the above item'] + \
|
|
'" name="submitRemove" value="' + \
|
|
translate['Remove'] + '">\n'
|
|
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Suspend the above account nickname'] + \
|
|
'" name="submitSuspend" value="' + translate['Suspend'] + '">\n'
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Remove a suspension for an account nickname'] + \
|
|
'" name="submitUnsuspend" value="' + \
|
|
translate['Unsuspend'] + '">\n'
|
|
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Block an account on another instance'] + \
|
|
'" name="submitBlock" value="' + translate['Block'] + '">\n'
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Unblock an account on another instance'] + \
|
|
'" name="submitUnblock" value="' + translate['Unblock'] + '">\n'
|
|
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Filter out words'] + \
|
|
'" name="submitFilter" value="' + translate['Filter'] + '">\n'
|
|
tlStr += \
|
|
' <input type="submit" title="' + \
|
|
translate['Unfilter words'] + \
|
|
'" name="submitUnfilter" value="' + translate['Unfilter'] + '">\n'
|
|
|
|
tlStr += '</div>\n</form>\n'
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '6')
|
|
|
|
if boxName == 'tlshares':
|
|
maxSharesPerAccount = itemsPerPage
|
|
return (tlStr +
|
|
_htmlSharesTimeline(translate, pageNumber, itemsPerPage,
|
|
baseDir, actor, nickname, domain, port,
|
|
maxSharesPerAccount, httpPrefix) +
|
|
htmlFooter())
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '7')
|
|
|
|
# page up arrow
|
|
if pageNumber > 1:
|
|
tlStr += \
|
|
' <center>\n' + \
|
|
' <a href="' + usersPath + '/' + boxName + \
|
|
'?page=' + str(pageNumber - 1) + \
|
|
'"><img loading="lazy" class="pageicon" src="/' + \
|
|
'icons/pageup.png" title="' + \
|
|
translate['Page up'] + '" alt="' + \
|
|
translate['Page up'] + '"></a>\n' + \
|
|
' </center>\n'
|
|
|
|
# show the posts
|
|
itemCtr = 0
|
|
if timelineJson:
|
|
# if this is the media timeline then add an extra gallery container
|
|
if boxName == 'tlmedia':
|
|
if pageNumber > 1:
|
|
tlStr += '<br>'
|
|
tlStr += '<div class="galleryContainer">\n'
|
|
|
|
# show each post in the timeline
|
|
for item in timelineJson['orderedItems']:
|
|
if item['type'] == 'Create' or \
|
|
item['type'] == 'Announce' or \
|
|
item['type'] == 'Update':
|
|
# is the actor who sent this post snoozed?
|
|
if isPersonSnoozed(baseDir, nickname, domain, item['actor']):
|
|
continue
|
|
|
|
# is the post in the memory cache of recent ones?
|
|
currTlStr = None
|
|
if boxName != 'tlmedia' and \
|
|
recentPostsCache.get('index'):
|
|
postId = \
|
|
removeIdEnding(item['id']).replace('/', '#')
|
|
if postId in recentPostsCache['index']:
|
|
if not item.get('muted'):
|
|
if recentPostsCache['html'].get(postId):
|
|
currTlStr = recentPostsCache['html'][postId]
|
|
currTlStr = \
|
|
preparePostFromHtmlCache(currTlStr,
|
|
boxName,
|
|
pageNumber)
|
|
_logTimelineTiming(enableTimingLog,
|
|
timelineStartTime,
|
|
boxName, '10')
|
|
|
|
if not currTlStr:
|
|
_logTimelineTiming(enableTimingLog,
|
|
timelineStartTime,
|
|
boxName, '11')
|
|
|
|
# read the post from disk
|
|
currTlStr = \
|
|
individualPostAsHtml(False, recentPostsCache,
|
|
maxRecentPosts,
|
|
translate, pageNumber,
|
|
baseDir, session,
|
|
cachedWebfingers,
|
|
personCache,
|
|
nickname, domain, port,
|
|
item, None, True,
|
|
allowDeletion,
|
|
httpPrefix, projectVersion,
|
|
boxName,
|
|
YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
peertubeInstances,
|
|
boxName != 'dm',
|
|
showIndividualPostIcons,
|
|
manuallyApproveFollowers,
|
|
False, True)
|
|
_logTimelineTiming(enableTimingLog,
|
|
timelineStartTime, boxName, '12')
|
|
|
|
if currTlStr:
|
|
itemCtr += 1
|
|
tlStr += currTlStr
|
|
if separatorStr:
|
|
tlStr += separatorStr
|
|
if boxName == 'tlmedia':
|
|
# Close galleryContainer
|
|
tlStr += '</div>\n'
|
|
|
|
# page down arrow
|
|
if itemCtr > 2:
|
|
tlStr += \
|
|
' <center>\n' + \
|
|
' <a href="' + usersPath + '/' + boxName + '?page=' + \
|
|
str(pageNumber + 1) + \
|
|
'"><img loading="lazy" class="pageicon" src="/' + \
|
|
'icons/pagedown.png" title="' + \
|
|
translate['Page down'] + '" alt="' + \
|
|
translate['Page down'] + '"></a>\n' + \
|
|
' </center>\n'
|
|
|
|
# end of 'section main'
|
|
tlStr += ' </div>\n'
|
|
|
|
if defaultTimeline == 'tlfeatures' and boxName not in userPages:
|
|
# right column
|
|
rightColumnStr = getRightColumnContent(baseDir, nickname, domainFull,
|
|
httpPrefix, translate,
|
|
moderator, editor,
|
|
newswire, positiveVoting,
|
|
False, None, True,
|
|
showPublishAsIcon,
|
|
rssIconAtTop, publishButtonAtTop,
|
|
authorized, True, theme)
|
|
tlStr += ' <div class="section newswire">' + \
|
|
rightColumnStr + ' </div>\n'
|
|
|
|
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '9')
|
|
|
|
# end of timeline
|
|
tlStr += '</div>\n'
|
|
|
|
tlStr += htmlFooter()
|
|
return tlStr
|
|
|
|
|
|
def htmlIndividualShare(actor: str, item: {}, translate: {},
|
|
showContact: bool, removeButton: bool) -> str:
|
|
"""Returns an individual shared item as html
|
|
"""
|
|
profileStr = '<div class="container">\n'
|
|
profileStr += '<p class="share-title">' + item['displayName'] + '</p>\n'
|
|
if item.get('imageUrl'):
|
|
profileStr += '<a href="' + item['imageUrl'] + '">\n'
|
|
profileStr += \
|
|
'<img loading="lazy" src="' + item['imageUrl'] + \
|
|
'" alt="' + translate['Item image'] + '">\n</a>\n'
|
|
profileStr += '<p>' + item['summary'] + '</p>\n'
|
|
profileStr += \
|
|
'<p><b>' + translate['Type'] + ':</b> ' + item['itemType'] + ' '
|
|
profileStr += \
|
|
'<b>' + translate['Category'] + ':</b> ' + item['category'] + ' '
|
|
profileStr += \
|
|
'<b>' + translate['Location'] + ':</b> ' + item['location'] + '</p>\n'
|
|
sharedesc = item['displayName']
|
|
if '<' not in sharedesc and '?' not in sharedesc:
|
|
if showContact:
|
|
contactActor = item['actor']
|
|
profileStr += \
|
|
'<p><a href="' + actor + \
|
|
'?replydm=sharedesc:' + sharedesc + \
|
|
'?mention=' + contactActor + '"><button class="button">' + \
|
|
translate['Contact'] + '</button></a>\n'
|
|
if removeButton:
|
|
profileStr += \
|
|
' <a href="' + actor + '?rmshare=' + sharedesc + \
|
|
'"><button class="button">' + \
|
|
translate['Remove'] + '</button></a>\n'
|
|
profileStr += '</div>\n'
|
|
return profileStr
|
|
|
|
|
|
def _htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
|
|
baseDir: str, actor: str,
|
|
nickname: str, domain: str, port: int,
|
|
maxSharesPerAccount: int, httpPrefix: str) -> str:
|
|
"""Show shared items timeline as html
|
|
"""
|
|
sharesJson, lastPage = \
|
|
sharesTimelineJson(actor, pageNumber, itemsPerPage,
|
|
baseDir, maxSharesPerAccount)
|
|
domainFull = getFullDomain(domain, port)
|
|
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
|
|
timelineStr = ''
|
|
|
|
if pageNumber > 1:
|
|
timelineStr += \
|
|
' <center>\n' + \
|
|
' <a href="' + actor + '/tlshares?page=' + \
|
|
str(pageNumber - 1) + \
|
|
'"><img loading="lazy" class="pageicon" src="/' + \
|
|
'icons/pageup.png" title="' + translate['Page up'] + \
|
|
'" alt="' + translate['Page up'] + '"></a>\n' + \
|
|
' </center>\n'
|
|
|
|
separatorStr = htmlPostSeparator(baseDir, None)
|
|
for published, item in sharesJson.items():
|
|
showContactButton = False
|
|
if item['actor'] != actor:
|
|
showContactButton = True
|
|
showRemoveButton = False
|
|
if item['actor'] == actor:
|
|
showRemoveButton = True
|
|
timelineStr += \
|
|
htmlIndividualShare(actor, item, translate,
|
|
showContactButton, showRemoveButton)
|
|
timelineStr += separatorStr
|
|
|
|
if not lastPage:
|
|
timelineStr += \
|
|
' <center>\n' + \
|
|
' <a href="' + actor + '/tlshares?page=' + \
|
|
str(pageNumber + 1) + \
|
|
'"><img loading="lazy" class="pageicon" src="/' + \
|
|
'icons/pagedown.png" title="' + translate['Page down'] + \
|
|
'" alt="' + translate['Page down'] + '"></a>\n' + \
|
|
' </center>\n'
|
|
|
|
return timelineStr
|
|
|
|
|
|
# TODO: Can this be re-implemented as injecting an additional CSS class ?
|
|
# Would allow for much more opportunity to style
|
|
def htmlHighlightLabel(label: str, highlight: bool) -> str:
|
|
"""If the give text should be highlighted then return
|
|
the appropriate markup.
|
|
This is so that in shell browsers, like lynx, it's possible
|
|
to see if the replies or DM button are highlighted.
|
|
"""
|
|
if not highlight:
|
|
return label
|
|
return '*' + str(label) + '*'
|
|
|
|
|
|
def htmlShares(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int,
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the shares timeline as html
|
|
"""
|
|
manuallyApproveFollowers = \
|
|
followerApprovalActive(baseDir, nickname, domain)
|
|
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, None,
|
|
'tlshares', allowDeletion,
|
|
httpPrefix, projectVersion, manuallyApproveFollowers,
|
|
False, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the inbox as html
|
|
"""
|
|
manuallyApproveFollowers = \
|
|
followerApprovalActive(baseDir, nickname, domain)
|
|
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson,
|
|
'inbox', allowDeletion,
|
|
httpPrefix, projectVersion, manuallyApproveFollowers,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, bookmarksJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the bookmarks as html
|
|
"""
|
|
manuallyApproveFollowers = \
|
|
followerApprovalActive(baseDir, nickname, domain)
|
|
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, bookmarksJson,
|
|
'tlbookmarks', allowDeletion,
|
|
httpPrefix, projectVersion, manuallyApproveFollowers,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlEvents(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, bookmarksJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the events as html
|
|
"""
|
|
manuallyApproveFollowers = \
|
|
followerApprovalActive(baseDir, nickname, domain)
|
|
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, bookmarksJson,
|
|
'tlevents', allowDeletion,
|
|
httpPrefix, projectVersion, manuallyApproveFollowers,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the DM timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'dm', allowDeletion,
|
|
httpPrefix, projectVersion, False, minimal,
|
|
YTReplacementDomain, showPublishedDateOnly,
|
|
newswire, False, False, positiveVoting,
|
|
showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the replies timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'tlreplies',
|
|
allowDeletion, httpPrefix, projectVersion, False,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the media timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'tlmedia',
|
|
allowDeletion, httpPrefix, projectVersion, False,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the blogs timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'tlblogs',
|
|
allowDeletion, httpPrefix, projectVersion, False,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool,
|
|
theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the features timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'tlfeatures',
|
|
allowDeletion, httpPrefix, projectVersion, False,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, False, False,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, inboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, moderator: bool, editor: bool,
|
|
positiveVoting: bool, showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the news timeline as html
|
|
"""
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, inboxJson, 'tlnews',
|
|
allowDeletion, httpPrefix, projectVersion, False,
|
|
minimal, YTReplacementDomain,
|
|
showPublishedDateOnly,
|
|
newswire, moderator, editor,
|
|
positiveVoting, showPublishAsIcon,
|
|
fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|
|
|
|
|
|
def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
translate: {}, pageNumber: int, itemsPerPage: int,
|
|
session, baseDir: str,
|
|
cachedWebfingers: {}, personCache: {},
|
|
nickname: str, domain: str, port: int, outboxJson: {},
|
|
allowDeletion: bool,
|
|
httpPrefix: str, projectVersion: str,
|
|
minimal: bool, YTReplacementDomain: str,
|
|
showPublishedDateOnly: bool,
|
|
newswire: {}, positiveVoting: bool,
|
|
showPublishAsIcon: bool,
|
|
fullWidthTimelineButtonHeader: bool,
|
|
iconsAsButtons: bool,
|
|
rssIconAtTop: bool,
|
|
publishButtonAtTop: bool,
|
|
authorized: bool, theme: str,
|
|
peertubeInstances: []) -> str:
|
|
"""Show the Outbox as html
|
|
"""
|
|
manuallyApproveFollowers = \
|
|
followerApprovalActive(baseDir, nickname, domain)
|
|
return htmlTimeline(cssCache, defaultTimeline,
|
|
recentPostsCache, maxRecentPosts,
|
|
translate, pageNumber,
|
|
itemsPerPage, session, baseDir,
|
|
cachedWebfingers, personCache,
|
|
nickname, domain, port, outboxJson, 'outbox',
|
|
allowDeletion, httpPrefix, projectVersion,
|
|
manuallyApproveFollowers, minimal,
|
|
YTReplacementDomain, showPublishedDateOnly,
|
|
newswire, False, False, positiveVoting,
|
|
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
|
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
|
authorized, None, theme, peertubeInstances)
|