epicyon/webapp_frontscreen.py

192 lines
7.3 KiB
Python

__filename__ = "webapp_frontscreen.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import os
from utils import isSystemAccount
from utils import getDomainFromActor
from utils import getConfigParam
from person import personBoxJson
from webapp_utils import htmlHeaderWithExternalStyles
from webapp_utils import htmlHeaderBanner, htmlFooter
from webapp_utils import getBannerFile
from webapp_utils import htmlPostSeparator
from webapp_utils import headerButtonsFrontScreen
from webapp_column_left import getLeftColumnContent
from webapp_column_right import getRightColumnContent
from webapp_post import individualPostAsHtml
def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
translate: {},
baseDir: str, httpPrefix: str,
nickname: str, domain: str, port: int,
session, cachedWebfingers: {}, personCache: {},
projectVersion: str,
YTReplacementDomain: str,
showPublishedDateOnly: bool,
peertubeInstances: []) -> str:
"""Shows posts on the front screen of a news instance
These should only be public blog posts from the features timeline
which is the blog timeline of the news actor
"""
separatorStr = htmlPostSeparator(baseDir, None)
profileStr = ''
maxItems = 4
ctr = 0
currPage = 1
boxName = 'tlfeatures'
authorized = True
while ctr < maxItems and currPage < 4:
outboxFeedPathStr = \
'/users/' + nickname + '/' + boxName + \
'?page=' + str(currPage)
outboxFeed = \
personBoxJson({}, session, baseDir, domain, port,
outboxFeedPathStr,
httpPrefix, 10, boxName,
authorized, 0, False, 0)
if not outboxFeed:
break
if len(outboxFeed['orderedItems']) == 0:
break
for item in outboxFeed['orderedItems']:
if item['type'] == 'Create':
postStr = \
individualPostAsHtml(True, recentPostsCache,
maxRecentPosts,
translate, None,
baseDir, session,
cachedWebfingers,
personCache,
nickname, domain, port, item,
None, True, False,
httpPrefix, projectVersion, 'inbox',
YTReplacementDomain,
showPublishedDateOnly,
peertubeInstances,
False, False, False, True, False)
if postStr:
profileStr += postStr + separatorStr
ctr += 1
if ctr >= maxItems:
break
currPage += 1
return profileStr
def htmlFrontScreen(rssIconAtTop: bool,
cssCache: {}, iconsAsButtons: bool,
defaultTimeline: str,
recentPostsCache: {}, maxRecentPosts: int,
translate: {}, projectVersion: str,
baseDir: str, httpPrefix: str, authorized: bool,
profileJson: {}, selected: str,
session, cachedWebfingers: {}, personCache: {},
YTReplacementDomain: str,
showPublishedDateOnly: bool,
newswire: {}, theme: str,
peertubeInstances: [],
extraJson=None,
pageNumber=None, maxItemsPerPage=None) -> str:
"""Show the news instance front screen
"""
nickname = profileJson['preferredUsername']
if not nickname:
return ""
if not isSystemAccount(nickname):
return ""
domain, port = getDomainFromActor(profileJson['id'])
if not domain:
return ""
domainFull = domain
if port:
domainFull = domain + ':' + str(port)
# If this is the news account then show a different banner
bannerFile, bannerFilename = getBannerFile(baseDir, nickname, domain, theme)
# NOTE: This currently more-or-less assumes being run only if 'news' instance
profileHeaderStr = htmlHeaderBanner(defaultTimeline, 'frontpage', baseDir, '/users/news',
authorized, translate, None, bannerFile);
# 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'
profileHeaderStr += '<div class="timeline">\n'
leftColumnStr = \
getLeftColumnContent(baseDir, 'news', domainFull,
httpPrefix, translate,
False, False, None, rssIconAtTop, True,
True, theme)
profileHeaderStr += ' <div class="section links">\n' + \
leftColumnStr + ' </div>\n'
profileStr = profileHeaderStr
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')
# center column containing posts
profileStr += ' <div class="section main">\n'
licenseStr = ''
# NOTE: Redundant
# bannerFile, bannerFilename = \
# getBannerFile(baseDir, nickname, domain, theme)
profileStr += \
_htmlFrontScreenPosts(recentPostsCache, maxRecentPosts,
translate,
baseDir, httpPrefix,
nickname, domain, port,
session, cachedWebfingers, personCache,
projectVersion,
YTReplacementDomain,
showPublishedDateOnly,
peertubeInstances) + licenseStr
# end of div main
profileStr += ' </div>\n'
# Footer which is only used for system accounts
rightColumnStr = \
getRightColumnContent(baseDir, 'news', domainFull,
httpPrefix, translate,
False, False, newswire, False,
False, None, False, False,
False, True, authorized, True, theme)
profileFooterStr = ' <div class="section newswire">' + \
rightColumnStr + ' </div>\n'
# Close div page
profileFooterStr += '</div>\n'
profileStr = \
htmlHeaderWithExternalStyles(cssFiles) + \
profileStr + profileFooterStr + htmlFooter()
return profileStr