diff --git a/webapp_frontscreen.py b/webapp_frontscreen.py new file mode 100644 index 000000000..a4e7b1b22 --- /dev/null +++ b/webapp_frontscreen.py @@ -0,0 +1,243 @@ +__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 person import personBoxJson +from webapp_utils import htmlHeaderWithExternalStyle +from webapp_utils import htmlFooter +from webapp_utils import getIconsWebPath +from webapp_utils import getBannerFile +from webapp_utils import htmlPostSeparator +from webapp_column_left import getLeftColumnContent +from webapp_column_right import getRightColumnContent +from webapp_post import individualPostAsHtml + + +def headerButtonsFrontScreen(translate: {}, + nickname: str, boxName: str, + authorized: bool, + iconsAsButtons: bool, + iconsPath: bool) -> str: + """Returns the header buttons for the front page of a news instance + """ + headerStr = '' + if nickname == 'news': + buttonFeatures = 'buttonMobile' + buttonNewswire = 'buttonMobile' + buttonLinks = 'buttonMobile' + if boxName == 'features': + buttonFeatures = 'buttonselected' + elif boxName == 'newswire': + buttonNewswire = 'buttonselected' + elif boxName == 'links': + buttonLinks = 'buttonselected' + + headerStr += \ + ' ' + \ + '' + if not authorized: + headerStr += \ + ' ' + \ + '' + if iconsAsButtons: + headerStr += \ + ' ' + \ + '' + headerStr += \ + ' ' + \ + '' + else: + headerStr += \ + ' ' + \ + '| ' + translate['Newswire'] + '\n' + headerStr += \ + ' ' + \ + '| ' + translate['Links'] + '\n' + else: + if not authorized: + headerStr += \ + ' ' + \ + '' + + if headerStr: + headerStr = \ + '\n
\n' + \ + headerStr + \ + '
\n' + return headerStr + + +def htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int, + translate: {}, + baseDir: str, httpPrefix: str, + nickname: str, domain: str, port: int, + session, wfRequest: {}, personCache: {}, + projectVersion: str, + YTReplacementDomain: str, + showPublishedDateOnly: bool) -> 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 + """ + iconsPath = getIconsWebPath(baseDir) + separatorStr = htmlPostSeparator(baseDir, None) + profileStr = '' + maxItems = 4 + ctr = 0 + currPage = 1 + boxName = 'tlfeatures' + authorized = True + while ctr < maxItems and currPage < 4: + outboxFeed = \ + personBoxJson({}, session, baseDir, domain, port, + '/users/' + nickname + '/' + boxName + + '?page=' + str(currPage), + 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, + iconsPath, translate, None, + baseDir, session, wfRequest, + personCache, + nickname, domain, port, item, + None, True, False, + httpPrefix, projectVersion, 'inbox', + YTReplacementDomain, + showPublishedDateOnly, + 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, wfRequest: {}, personCache: {}, + YTReplacementDomain: str, + showPublishedDateOnly: bool, + newswire: {}, 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) + + iconsPath = getIconsWebPath(baseDir) + loginButton = headerButtonsFrontScreen(translate, nickname, + 'features', authorized, + iconsAsButtons, iconsPath) + + # If this is the news account then show a different banner + bannerFile, bannerFilename = getBannerFile(baseDir, nickname, domain) + profileHeaderStr = \ + '\n' + if loginButton: + profileHeaderStr += '
' + loginButton + '
\n' + + profileHeaderStr += '\n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileHeaderStr += ' \n' + profileFooterStr += ' \n' + profileFooterStr += ' \n' + profileFooterStr += ' \n' + profileFooterStr += '
\n' + iconsPath = getIconsWebPath(baseDir) + profileHeaderStr += \ + getLeftColumnContent(baseDir, 'news', domainFull, + httpPrefix, translate, + iconsPath, False, + False, None, rssIconAtTop, True, + True) + profileHeaderStr += ' \n' + + profileStr = profileHeaderStr + + cssFilename = baseDir + '/epicyon-profile.css' + if os.path.isfile(baseDir + '/epicyon.css'): + cssFilename = baseDir + '/epicyon.css' + + licenseStr = '' + bannerFile, bannerFilename = \ + getBannerFile(baseDir, nickname, domain) + profileStr += \ + htmlFrontScreenPosts(recentPostsCache, maxRecentPosts, + translate, + baseDir, httpPrefix, + nickname, domain, port, + session, wfRequest, personCache, + projectVersion, + YTReplacementDomain, + showPublishedDateOnly) + licenseStr + + # Footer which is only used for system accounts + profileFooterStr = ' \n' + iconsPath = getIconsWebPath(baseDir) + profileFooterStr += \ + getRightColumnContent(baseDir, 'news', domainFull, + httpPrefix, translate, + iconsPath, False, False, + newswire, False, + False, None, False, False, + False, True, authorized, True) + profileFooterStr += '
\n' + + profileStr = \ + htmlHeaderWithExternalStyle(cssFilename) + \ + profileStr + profileFooterStr + htmlFooter() + return profileStr diff --git a/webapp_profile.py b/webapp_profile.py index 0dcbabc54..8d8b7005f 100644 --- a/webapp_profile.py +++ b/webapp_profile.py @@ -31,19 +31,17 @@ from pgp import getEmailAddress from pgp import getPGPfingerprint from pgp import getPGPpubKey from tox import getToxAddress +from webapp_frontscreen import htmlFrontScreen from webapp_utils import scheduledPostsExist from webapp_utils import getPersonAvatarUrl from webapp_utils import getIconsWebPath from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlFooter from webapp_utils import addEmojiToDisplayName -from webapp_utils import headerButtonsFrontScreen from webapp_utils import getBannerFile from webapp_utils import htmlPostSeparator from webapp_utils import getBlogAddress from webapp_post import individualPostAsHtml -from webapp_column_left import getLeftColumnContent -from webapp_column_right import getRightColumnContent from webapp_timeline import htmlIndividualShare @@ -374,6 +372,20 @@ def htmlProfile(rssIconAtTop: bool, nickname = profileJson['preferredUsername'] if not nickname: return "" + if isSystemAccount(nickname): + return htmlFrontScreen(rssIconAtTop, + cssCache, iconsAsButtons, + defaultTimeline, + recentPostsCache, maxRecentPosts, + translate, projectVersion, + baseDir, httpPrefix, authorized, + profileJson, selected, + session, wfRequest, personCache, + YTReplacementDomain, + showPublishedDateOnly, + newswire, extraJson, + pageNumber, maxItemsPerPage) + domain, port = getDomainFromActor(profileJson['id']) if not domain: return "" @@ -464,11 +476,7 @@ def htmlProfile(rssIconAtTop: bool, donateSection += '\n' iconsPath = getIconsWebPath(baseDir) - if not authorized: - loginButton = headerButtonsFrontScreen(translate, nickname, - 'features', authorized, - iconsAsButtons, iconsPath) - else: + if authorized: editProfileStr = \ '' + \ '\n' - if loginButton: - profileHeaderStr += '
' + loginButton + '
\n' - - profileHeaderStr += '\n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileHeaderStr += ' \n' - profileFooterStr += ' \n' - profileFooterStr += ' \n' - profileFooterStr += ' \n' - profileFooterStr += '
\n' - iconsPath = getIconsWebPath(baseDir) - profileHeaderStr += \ - getLeftColumnContent(baseDir, 'news', domainFull, - httpPrefix, translate, - iconsPath, False, - False, None, rssIconAtTop, True, - True) - profileHeaderStr += ' \n' - else: - avatarUrl = profileJson['icon']['url'] - profileHeaderStr = \ - getProfileHeader(baseDir, nickname, domain, - domainFull, translate, iconsPath, - defaultTimeline, displayName, - avatarDescription, - profileDescriptionShort, - loginButton, avatarUrl) + avatarUrl = profileJson['icon']['url'] + profileHeaderStr = \ + getProfileHeader(baseDir, nickname, domain, + domainFull, translate, iconsPath, + defaultTimeline, displayName, + avatarDescription, + profileDescriptionShort, + loginButton, avatarUrl) profileStr = profileHeaderStr + donateSection - if not isSystemAccount(nickname): - profileStr += '
\n' - profileStr += '
' - profileStr += \ - ' ' - profileStr += \ - ' ' + \ - '' - profileStr += \ - ' ' + \ - '' - profileStr += \ - ' ' + \ - '' - profileStr += \ - ' ' + \ - '' - profileStr += \ - ' ' + \ - '' - profileStr += logoutStr + editProfileStr - profileStr += '
' - profileStr += '
' + profileStr += '
\n' + profileStr += '
' + profileStr += \ + ' ' + profileStr += \ + ' ' + \ + '' + profileStr += \ + ' ' + \ + '' + profileStr += \ + ' ' + \ + '' + profileStr += \ + ' ' + \ + '' + profileStr += \ + ' ' + \ + '' + profileStr += logoutStr + editProfileStr + profileStr += '
' + profileStr += '
' profileStr += followApprovalsSection @@ -623,87 +602,55 @@ def htmlProfile(rssIconAtTop: bool, if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.css' - if isSystemAccount(nickname): - licenseStr = '' - bannerFile, bannerFilename = \ - getBannerFile(baseDir, nickname, domain) + licenseStr = \ + '' + \ + '' + \
+        translate['Get the source code'] + '' + + if selected == 'posts': profileStr += \ - htmlFrontScreenPosts(recentPostsCache, maxRecentPosts, - translate, - baseDir, httpPrefix, - nickname, domain, port, - session, wfRequest, personCache, - projectVersion, - YTReplacementDomain, - showPublishedDateOnly) + licenseStr - else: - licenseStr = \ - '' + \ - '' + \
-            translate['Get the source code'] + '' - - if selected == 'posts': - profileStr += \ - htmlProfilePosts(recentPostsCache, maxRecentPosts, - translate, - baseDir, httpPrefix, authorized, - nickname, domain, port, - session, wfRequest, personCache, - projectVersion, - YTReplacementDomain, - showPublishedDateOnly) + licenseStr - elif selected == 'following': - profileStr += \ - htmlProfileFollowing(translate, baseDir, httpPrefix, - authorized, nickname, - domain, port, session, - wfRequest, personCache, extraJson, - projectVersion, ["unfollow"], selected, - usersPath, pageNumber, maxItemsPerPage) - elif selected == 'followers': - profileStr += \ - htmlProfileFollowing(translate, baseDir, httpPrefix, - authorized, nickname, - domain, port, session, - wfRequest, personCache, extraJson, - projectVersion, ["block"], - selected, usersPath, pageNumber, - maxItemsPerPage) - elif selected == 'roles': - profileStr += \ - htmlProfileRoles(translate, nickname, domainFull, - extraJson) - elif selected == 'skills': - profileStr += \ - htmlProfileSkills(translate, nickname, domainFull, extraJson) - elif selected == 'shares': - profileStr += \ - htmlProfileShares(actor, translate, - nickname, domainFull, - extraJson) + licenseStr - - # Footer which is only used for system accounts - profileFooterStr = '' - if isSystemAccount(nickname): - profileFooterStr = '
\n' - iconsPath = getIconsWebPath(baseDir) - profileFooterStr += \ - getRightColumnContent(baseDir, 'news', domainFull, - httpPrefix, translate, - iconsPath, False, False, - newswire, False, - False, None, False, False, - False, True, authorized, True) - profileFooterStr += '
\n' + htmlProfilePosts(recentPostsCache, maxRecentPosts, + translate, + baseDir, httpPrefix, authorized, + nickname, domain, port, + session, wfRequest, personCache, + projectVersion, + YTReplacementDomain, + showPublishedDateOnly) + licenseStr + elif selected == 'following': + profileStr += \ + htmlProfileFollowing(translate, baseDir, httpPrefix, + authorized, nickname, + domain, port, session, + wfRequest, personCache, extraJson, + projectVersion, ["unfollow"], selected, + usersPath, pageNumber, maxItemsPerPage) + elif selected == 'followers': + profileStr += \ + htmlProfileFollowing(translate, baseDir, httpPrefix, + authorized, nickname, + domain, port, session, + wfRequest, personCache, extraJson, + projectVersion, ["block"], + selected, usersPath, pageNumber, + maxItemsPerPage) + elif selected == 'roles': + profileStr += \ + htmlProfileRoles(translate, nickname, domainFull, + extraJson) + elif selected == 'skills': + profileStr += \ + htmlProfileSkills(translate, nickname, domainFull, extraJson) + elif selected == 'shares': + profileStr += \ + htmlProfileShares(actor, translate, + nickname, domainFull, + extraJson) + licenseStr profileStr = \ htmlHeaderWithExternalStyle(cssFilename) + \ - profileStr + profileFooterStr + htmlFooter() + profileStr + htmlFooter() return profileStr @@ -762,60 +709,6 @@ def htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int, return profileStr -def htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int, - translate: {}, - baseDir: str, httpPrefix: str, - nickname: str, domain: str, port: int, - session, wfRequest: {}, personCache: {}, - projectVersion: str, - YTReplacementDomain: str, - showPublishedDateOnly: bool) -> 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 - """ - iconsPath = getIconsWebPath(baseDir) - separatorStr = htmlPostSeparator(baseDir, None) - profileStr = '' - maxItems = 4 - ctr = 0 - currPage = 1 - boxName = 'tlfeatures' - authorized = True - while ctr < maxItems and currPage < 4: - outboxFeed = \ - personBoxJson({}, session, baseDir, domain, port, - '/users/' + nickname + '/' + boxName + - '?page=' + str(currPage), - 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, - iconsPath, translate, None, - baseDir, session, wfRequest, - personCache, - nickname, domain, port, item, - None, True, False, - httpPrefix, projectVersion, 'inbox', - YTReplacementDomain, - showPublishedDateOnly, - False, False, False, True, False) - if postStr: - profileStr += postStr + separatorStr - ctr += 1 - if ctr >= maxItems: - break - currPage += 1 - return profileStr - - def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str, authorized: bool, nickname: str, domain: str, port: int, diff --git a/webapp_utils.py b/webapp_utils.py index 9736aaaa2..0c8698231 100644 --- a/webapp_utils.py +++ b/webapp_utils.py @@ -737,76 +737,6 @@ def htmlPostSeparator(baseDir: str, column: str) -> str: return separatorStr -def headerButtonsFrontScreen(translate: {}, - nickname: str, boxName: str, - authorized: bool, - iconsAsButtons: bool, - iconsPath: bool) -> str: - """Returns the header buttons for the front page of a news instance - """ - headerStr = '' - if nickname == 'news': - buttonFeatures = 'buttonMobile' - buttonNewswire = 'buttonMobile' - buttonLinks = 'buttonMobile' - if boxName == 'features': - buttonFeatures = 'buttonselected' - elif boxName == 'newswire': - buttonNewswire = 'buttonselected' - elif boxName == 'links': - buttonLinks = 'buttonselected' - - headerStr += \ - '
' + \ - '' - if not authorized: - headerStr += \ - ' ' + \ - '' - if iconsAsButtons: - headerStr += \ - ' ' + \ - '' - headerStr += \ - ' ' + \ - '' - else: - headerStr += \ - ' ' + \ - '| ' + translate['Newswire'] + '\n' - headerStr += \ - ' ' + \ - '| ' + translate['Links'] + '\n' - else: - if not authorized: - headerStr += \ - ' ' + \ - '' - - if headerStr: - headerStr = \ - '\n
\n' + \ - headerStr + \ - '
\n' - return headerStr - - def htmlHighlightLabel(label: str, highlight: bool) -> str: """If the given text should be highlighted then return the appropriate markup.