__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 follow import followerApprovalActive from person import isPersonSnoozed from webapp_utils import htmlPostSeparator from webapp_utils import getBannerFile from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import 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() # directory where icons are found # This changes depending upon theme iconsDir = getIconsDir(baseDir) separatorStr = '' if boxName != 'tlmedia': separatorStr = htmlPostSeparator(baseDir, None) # the css filename cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.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)) tlStr = htmlHeaderWithExternalStyle(cssFilename, profileStyle) _logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '4') # if this is a news instance and we are viewing the news timeline newsHeader = False if defaultTimeline == 'tlfeatures' and boxName == 'tlfeatures': newsHeader = True # Banner and "profile toggle" link # TODO: This CSS should be moved out of the code # Items like this that can be different per user should be kept # in the user's folder and loaded as final CSS, to allow overwrite(s) tlStr += (f"\t" f"{translate['Switch to profile view']}\n") # Full Row of Buttons if fullWidthTimelineButtonHeader: tlStr += \ headerButtonsTimeline(defaultTimeline, boxName, pageNumber, translate, usersPath, minimal, moderator, manuallyApproveFollowers, baseDir, nickname, domain, timelineStartTime, iconsAsButtons) # start the timeline tlStr += '
' + item['summary'] + '
\n' profileStr += \ '' + translate['Type'] + ': ' + item['itemType'] + ' ' profileStr += \ '' + translate['Category'] + ': ' + item['category'] + ' ' profileStr += \ '' + translate['Location'] + ': ' + item['location'] + '
\n' sharedesc = item['displayName'] if '<' not in sharedesc and '?' not in sharedesc: if showContact: contactActor = item['actor'] profileStr += \ '