2020-11-28 10:11:36 +00:00
|
|
|
__filename__ = "webapp_frontscreen.py"
|
|
|
|
__author__ = "Bob Mottram"
|
|
|
|
__license__ = "AGPL3+"
|
2021-01-26 10:07:42 +00:00
|
|
|
__version__ = "1.2.0"
|
2020-11-28 10:11:36 +00:00
|
|
|
__maintainer__ = "Bob Mottram"
|
2021-09-10 16:14:50 +00:00
|
|
|
__email__ = "bob@libreserver.org"
|
2020-11-28 10:11:36 +00:00
|
|
|
__status__ = "Production"
|
2021-06-26 11:27:14 +00:00
|
|
|
__module_group__ = "Timeline"
|
2020-11-28 10:11:36 +00:00
|
|
|
|
|
|
|
import os
|
|
|
|
from utils import isSystemAccount
|
|
|
|
from utils import getDomainFromActor
|
2021-01-11 19:46:21 +00:00
|
|
|
from utils import getConfigParam
|
2020-11-28 10:11:36 +00:00
|
|
|
from person import personBoxJson
|
|
|
|
from webapp_utils import htmlHeaderWithExternalStyle
|
|
|
|
from webapp_utils import htmlFooter
|
|
|
|
from webapp_utils import getBannerFile
|
|
|
|
from webapp_utils import htmlPostSeparator
|
2020-11-28 10:19:59 +00:00
|
|
|
from webapp_utils import headerButtonsFrontScreen
|
2020-11-28 10:11:36 +00:00
|
|
|
from webapp_column_left import getLeftColumnContent
|
|
|
|
from webapp_column_right import getRightColumnContent
|
|
|
|
from webapp_post import individualPostAsHtml
|
|
|
|
|
|
|
|
|
2020-12-22 18:06:23 +00:00
|
|
|
def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
|
|
|
translate: {},
|
|
|
|
baseDir: str, httpPrefix: str,
|
|
|
|
nickname: str, domain: str, port: int,
|
2020-12-31 12:46:35 +00:00
|
|
|
session, cachedWebfingers: {}, personCache: {},
|
2020-12-22 18:06:23 +00:00
|
|
|
projectVersion: str,
|
|
|
|
YTReplacementDomain: str,
|
2020-12-23 23:59:49 +00:00
|
|
|
showPublishedDateOnly: bool,
|
2021-01-30 11:47:09 +00:00
|
|
|
peertubeInstances: [],
|
2021-03-09 19:52:10 +00:00
|
|
|
allowLocalNetworkAccess: bool,
|
2021-08-03 10:04:45 +00:00
|
|
|
themeName: str, systemLanguage: str,
|
2021-08-31 14:17:11 +00:00
|
|
|
maxLikeCount: int,
|
|
|
|
signingPrivateKeyPem: str) -> str:
|
2020-11-28 10:11:36 +00:00
|
|
|
"""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:
|
2020-12-22 21:24:46 +00:00
|
|
|
outboxFeedPathStr = \
|
|
|
|
'/users/' + nickname + '/' + boxName + \
|
|
|
|
'?page=' + str(currPage)
|
2020-11-28 10:11:36 +00:00
|
|
|
outboxFeed = \
|
|
|
|
personBoxJson({}, session, baseDir, domain, port,
|
2020-12-22 21:24:46 +00:00
|
|
|
outboxFeedPathStr,
|
2020-11-28 10:11:36 +00:00
|
|
|
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 = \
|
2021-08-31 14:17:11 +00:00
|
|
|
individualPostAsHtml(signingPrivateKeyPem,
|
|
|
|
True, recentPostsCache,
|
2020-11-28 10:11:36 +00:00
|
|
|
maxRecentPosts,
|
2020-12-09 13:31:54 +00:00
|
|
|
translate, None,
|
2020-12-31 12:46:35 +00:00
|
|
|
baseDir, session,
|
|
|
|
cachedWebfingers,
|
2020-11-28 10:11:36 +00:00
|
|
|
personCache,
|
|
|
|
nickname, domain, port, item,
|
|
|
|
None, True, False,
|
|
|
|
httpPrefix, projectVersion, 'inbox',
|
|
|
|
YTReplacementDomain,
|
|
|
|
showPublishedDateOnly,
|
2020-12-23 23:59:49 +00:00
|
|
|
peertubeInstances,
|
2021-01-30 11:47:09 +00:00
|
|
|
allowLocalNetworkAccess,
|
2021-07-18 11:48:29 +00:00
|
|
|
themeName, systemLanguage,
|
2021-08-03 10:04:45 +00:00
|
|
|
maxLikeCount,
|
2020-11-28 10:11:36 +00:00
|
|
|
False, False, False, True, False)
|
|
|
|
if postStr:
|
|
|
|
profileStr += postStr + separatorStr
|
|
|
|
ctr += 1
|
|
|
|
if ctr >= maxItems:
|
|
|
|
break
|
|
|
|
currPage += 1
|
|
|
|
return profileStr
|
|
|
|
|
|
|
|
|
2021-08-31 14:17:11 +00:00
|
|
|
def htmlFrontScreen(signingPrivateKeyPem: str,
|
|
|
|
rssIconAtTop: bool,
|
2020-11-28 10:11:36 +00:00
|
|
|
cssCache: {}, iconsAsButtons: bool,
|
|
|
|
defaultTimeline: str,
|
|
|
|
recentPostsCache: {}, maxRecentPosts: int,
|
|
|
|
translate: {}, projectVersion: str,
|
|
|
|
baseDir: str, httpPrefix: str, authorized: bool,
|
|
|
|
profileJson: {}, selected: str,
|
2020-12-31 12:46:35 +00:00
|
|
|
session, cachedWebfingers: {}, personCache: {},
|
2020-11-28 10:11:36 +00:00
|
|
|
YTReplacementDomain: str,
|
|
|
|
showPublishedDateOnly: bool,
|
2020-12-23 23:59:49 +00:00
|
|
|
newswire: {}, theme: str,
|
|
|
|
peertubeInstances: [],
|
2021-01-30 11:47:09 +00:00
|
|
|
allowLocalNetworkAccess: bool,
|
2021-04-23 16:29:03 +00:00
|
|
|
accessKeys: {},
|
2021-08-03 10:04:45 +00:00
|
|
|
systemLanguage: str, maxLikeCount: int,
|
2021-07-27 14:06:14 +00:00
|
|
|
sharedItemsFederatedDomains: [],
|
2021-06-20 11:28:35 +00:00
|
|
|
extraJson: {} = None,
|
|
|
|
pageNumber: int = None,
|
|
|
|
maxItemsPerPage: int = None) -> str:
|
2020-11-28 10:11:36 +00:00
|
|
|
"""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)
|
|
|
|
|
|
|
|
loginButton = headerButtonsFrontScreen(translate, nickname,
|
|
|
|
'features', authorized,
|
2020-12-09 13:31:54 +00:00
|
|
|
iconsAsButtons)
|
2020-11-28 10:11:36 +00:00
|
|
|
|
|
|
|
# If this is the news account then show a different banner
|
2020-12-20 18:16:53 +00:00
|
|
|
bannerFile, bannerFilename = \
|
|
|
|
getBannerFile(baseDir, nickname, domain, theme)
|
2020-11-28 10:11:36 +00:00
|
|
|
profileHeaderStr = \
|
|
|
|
'<img loading="lazy" class="timeline-banner" ' + \
|
|
|
|
'src="/users/' + nickname + '/' + bannerFile + '" />\n'
|
|
|
|
if loginButton:
|
|
|
|
profileHeaderStr += '<center>' + loginButton + '</center>\n'
|
|
|
|
|
2021-07-05 20:24:43 +00:00
|
|
|
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'
|
2020-11-28 10:11:36 +00:00
|
|
|
profileHeaderStr += \
|
|
|
|
getLeftColumnContent(baseDir, 'news', domainFull,
|
|
|
|
httpPrefix, translate,
|
2020-12-09 13:31:54 +00:00
|
|
|
False, False, None, rssIconAtTop, True,
|
2021-07-27 14:06:14 +00:00
|
|
|
True, theme, accessKeys,
|
|
|
|
sharedItemsFederatedDomains)
|
2021-07-05 20:24:43 +00:00
|
|
|
profileHeaderStr += \
|
|
|
|
' </td>\n' + \
|
|
|
|
' <td valign="top" class="col-center">\n'
|
2020-11-28 10:11:36 +00:00
|
|
|
|
|
|
|
profileStr = profileHeaderStr
|
|
|
|
|
|
|
|
cssFilename = baseDir + '/epicyon-profile.css'
|
|
|
|
if os.path.isfile(baseDir + '/epicyon.css'):
|
|
|
|
cssFilename = baseDir + '/epicyon.css'
|
|
|
|
|
|
|
|
licenseStr = ''
|
|
|
|
bannerFile, bannerFilename = \
|
2020-12-20 18:16:53 +00:00
|
|
|
getBannerFile(baseDir, nickname, domain, theme)
|
2020-11-28 10:11:36 +00:00
|
|
|
profileStr += \
|
2020-12-22 18:06:23 +00:00
|
|
|
_htmlFrontScreenPosts(recentPostsCache, maxRecentPosts,
|
|
|
|
translate,
|
|
|
|
baseDir, httpPrefix,
|
|
|
|
nickname, domain, port,
|
2020-12-31 12:46:35 +00:00
|
|
|
session, cachedWebfingers, personCache,
|
2020-12-22 18:06:23 +00:00
|
|
|
projectVersion,
|
|
|
|
YTReplacementDomain,
|
2020-12-23 23:59:49 +00:00
|
|
|
showPublishedDateOnly,
|
2021-01-30 11:47:09 +00:00
|
|
|
peertubeInstances,
|
2021-03-09 19:52:10 +00:00
|
|
|
allowLocalNetworkAccess,
|
2021-08-03 10:04:45 +00:00
|
|
|
theme, systemLanguage,
|
2021-08-31 14:17:11 +00:00
|
|
|
maxLikeCount,
|
|
|
|
signingPrivateKeyPem) + licenseStr
|
2020-11-28 10:11:36 +00:00
|
|
|
|
|
|
|
# Footer which is only used for system accounts
|
|
|
|
profileFooterStr = ' </td>\n'
|
|
|
|
profileFooterStr += ' <td valign="top" class="col-right">\n'
|
|
|
|
profileFooterStr += \
|
|
|
|
getRightColumnContent(baseDir, 'news', domainFull,
|
|
|
|
httpPrefix, translate,
|
2020-12-09 13:31:54 +00:00
|
|
|
False, False, newswire, False,
|
2020-11-28 10:11:36 +00:00
|
|
|
False, None, False, False,
|
2021-02-05 11:41:45 +00:00
|
|
|
False, True, authorized, True, theme,
|
2021-04-23 19:06:34 +00:00
|
|
|
defaultTimeline, accessKeys)
|
2021-07-05 20:24:43 +00:00
|
|
|
profileFooterStr += \
|
|
|
|
' </td>\n' + \
|
|
|
|
' </tr>\n' + \
|
|
|
|
' </tbody>\n' + \
|
|
|
|
'</table>\n'
|
2020-11-28 10:11:36 +00:00
|
|
|
|
2021-01-11 19:46:21 +00:00
|
|
|
instanceTitle = \
|
|
|
|
getConfigParam(baseDir, 'instanceTitle')
|
2020-11-28 10:11:36 +00:00
|
|
|
profileStr = \
|
2021-01-11 19:46:21 +00:00
|
|
|
htmlHeaderWithExternalStyle(cssFilename, instanceTitle) + \
|
2020-11-28 10:11:36 +00:00
|
|
|
profileStr + profileFooterStr + htmlFooter()
|
|
|
|
return profileStr
|