__filename__ = "webapp.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.1.0" __maintainer__ = "Bob Mottram" __email__ = "bob@freedombone.net" __status__ = "Production" import os from shutil import copyfile from utils import getCSS from utils import getNicknameFromActor from utils import getDomainFromActor from utils import locatePost from utils import loadJson from shares import getValidSharedItemID from webapp_utils import getAltPath from webapp_utils import getIconsDir from webapp_utils import htmlHeader from webapp_utils import htmlFooter from webapp_post import individualPostAsHtml def htmlFollowingList(cssCache: {}, baseDir: str, followingFilename: str) -> str: """Returns a list of handles being followed """ with open(followingFilename, 'r') as followingFile: msg = followingFile.read() followingList = msg.split('\n') followingList.sort() if followingList: cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.css' profileCSS = getCSS(baseDir, cssFilename, cssCache) if profileCSS: followingListHtml = htmlHeader(cssFilename, profileCSS) for followingAddress in followingList: if followingAddress: followingListHtml += \ '

@' + followingAddress + '

' followingListHtml += htmlFooter() msg = followingListHtml return msg return '' def htmlHashtagBlocked(cssCache: {}, baseDir: str, translate: {}) -> str: """Show the screen for a blocked hashtag """ blockedHashtagForm = '' cssFilename = baseDir + '/epicyon-suspended.css' if os.path.isfile(baseDir + '/suspended.css'): cssFilename = baseDir + '/suspended.css' blockedHashtagCSS = getCSS(baseDir, cssFilename, cssCache) if blockedHashtagCSS: blockedHashtagForm = htmlHeader(cssFilename, blockedHashtagCSS) blockedHashtagForm += '
\n' blockedHashtagForm += \ '

' + \ translate['Hashtag Blocked'] + '

\n' blockedHashtagForm += \ '

See ' + \ translate['Terms of Service'] + '

\n' blockedHashtagForm += '
\n' blockedHashtagForm += htmlFooter() return blockedHashtagForm def htmlRemoveSharedItem(cssCache: {}, translate: {}, baseDir: str, actor: str, shareName: str, callingDomain: str) -> str: """Shows a screen asking to confirm the removal of a shared item """ itemID = getValidSharedItemID(shareName) nickname = getNicknameFromActor(actor) domain, port = getDomainFromActor(actor) domainFull = domain if port: if port != 80 and port != 443: domainFull = domain + ':' + str(port) sharesFile = baseDir + '/accounts/' + \ nickname + '@' + domain + '/shares.json' if not os.path.isfile(sharesFile): print('ERROR: no shares file ' + sharesFile) return None sharesJson = loadJson(sharesFile) if not sharesJson: print('ERROR: unable to load shares.json') return None if not sharesJson.get(itemID): print('ERROR: share named "' + itemID + '" is not in ' + sharesFile) return None sharedItemDisplayName = sharesJson[itemID]['displayName'] sharedItemImageUrl = None if sharesJson[itemID].get('imageUrl'): sharedItemImageUrl = sharesJson[itemID]['imageUrl'] if os.path.isfile(baseDir + '/img/shares-background.png'): if not os.path.isfile(baseDir + '/accounts/shares-background.png'): copyfile(baseDir + '/img/shares-background.png', baseDir + '/accounts/shares-background.png') cssFilename = baseDir + '/epicyon-follow.css' if os.path.isfile(baseDir + '/follow.css'): cssFilename = baseDir + '/follow.css' profileStyle = getCSS(baseDir, cssFilename, cssCache) sharesStr = htmlHeader(cssFilename, profileStyle) sharesStr += '
\n' sharesStr += '
\n' sharesStr += '
\n' if sharedItemImageUrl: sharesStr += ' \n' sharesStr += \ '

' + translate['Remove'] + \ ' ' + sharedItemDisplayName + ' ?

\n' postActor = getAltPath(actor, domainFull, callingDomain) sharesStr += '
\n' sharesStr += \ ' \n' sharesStr += ' \n' sharesStr += \ ' \n' sharesStr += \ ' \n' sharesStr += '
\n' sharesStr += '
\n' sharesStr += '
\n' sharesStr += '
\n' sharesStr += htmlFooter() return sharesStr def htmlDeletePost(cssCache: {}, recentPostsCache: {}, maxRecentPosts: int, translate, pageNumber: int, session, baseDir: str, messageId: str, httpPrefix: str, projectVersion: str, wfRequest: {}, personCache: {}, callingDomain: str, YTReplacementDomain: str, showPublishedDateOnly: bool) -> str: """Shows a screen asking to confirm the deletion of a post """ if '/statuses/' not in messageId: return None iconsDir = getIconsDir(baseDir) actor = messageId.split('/statuses/')[0] nickname = getNicknameFromActor(actor) domain, port = getDomainFromActor(actor) domainFull = domain if port: if port != 80 and port != 443: domainFull = domain + ':' + str(port) postFilename = locatePost(baseDir, nickname, domain, messageId) if not postFilename: return None postJsonObject = loadJson(postFilename) if not postJsonObject: return None if os.path.isfile(baseDir + '/img/delete-background.png'): if not os.path.isfile(baseDir + '/accounts/delete-background.png'): copyfile(baseDir + '/img/delete-background.png', baseDir + '/accounts/delete-background.png') deletePostStr = None cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.css' profileStyle = getCSS(baseDir, cssFilename, cssCache) if profileStyle: if httpPrefix != 'https': profileStyle = profileStyle.replace('https://', httpPrefix + '://') deletePostStr = htmlHeader(cssFilename, profileStyle) deletePostStr += \ individualPostAsHtml(True, recentPostsCache, maxRecentPosts, iconsDir, translate, pageNumber, baseDir, session, wfRequest, personCache, nickname, domain, port, postJsonObject, None, True, False, httpPrefix, projectVersion, 'outbox', YTReplacementDomain, showPublishedDateOnly, False, False, False, False, False) deletePostStr += '
' deletePostStr += \ '

' + \ translate['Delete this post?'] + '

' postActor = getAltPath(actor, domainFull, callingDomain) deletePostStr += \ '
\n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' deletePostStr += \ ' \n' deletePostStr += '
\n' deletePostStr += '
\n' deletePostStr += htmlFooter() return deletePostStr def htmlFollowConfirm(cssCache: {}, translate: {}, baseDir: str, originPathStr: str, followActor: str, followProfileUrl: str) -> str: """Asks to confirm a follow """ followDomain, port = getDomainFromActor(followActor) if os.path.isfile(baseDir + '/accounts/follow-background-custom.jpg'): if not os.path.isfile(baseDir + '/accounts/follow-background.jpg'): copyfile(baseDir + '/accounts/follow-background-custom.jpg', baseDir + '/accounts/follow-background.jpg') cssFilename = baseDir + '/epicyon-follow.css' if os.path.isfile(baseDir + '/follow.css'): cssFilename = baseDir + '/follow.css' profileStyle = getCSS(baseDir, cssFilename, cssCache) followStr = htmlHeader(cssFilename, profileStyle) followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += ' \n' followStr += ' \n' followStr += \ '

' + translate['Follow'] + ' ' + \ getNicknameFromActor(followActor) + '@' + followDomain + ' ?

\n' followStr += '
\n' followStr += ' \n' followStr += \ ' \n' followStr += \ ' \n' followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += htmlFooter() return followStr def htmlUnfollowConfirm(cssCache: {}, translate: {}, baseDir: str, originPathStr: str, followActor: str, followProfileUrl: str) -> str: """Asks to confirm unfollowing an actor """ followDomain, port = getDomainFromActor(followActor) if os.path.isfile(baseDir + '/accounts/follow-background-custom.jpg'): if not os.path.isfile(baseDir + '/accounts/follow-background.jpg'): copyfile(baseDir + '/accounts/follow-background-custom.jpg', baseDir + '/accounts/follow-background.jpg') cssFilename = baseDir + '/epicyon-follow.css' if os.path.isfile(baseDir + '/follow.css'): cssFilename = baseDir + '/follow.css' profileStyle = getCSS(baseDir, cssFilename, cssCache) followStr = htmlHeader(cssFilename, profileStyle) followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += ' \n' followStr += ' \n' followStr += \ '

' + translate['Stop following'] + \ ' ' + getNicknameFromActor(followActor) + \ '@' + followDomain + ' ?

\n' followStr += '
\n' followStr += ' \n' followStr += \ ' \n' followStr += \ ' \n' followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += '
\n' followStr += htmlFooter() return followStr def htmlUnblockConfirm(cssCache: {}, translate: {}, baseDir: str, originPathStr: str, blockActor: str, blockProfileUrl: str) -> str: """Asks to confirm unblocking an actor """ blockDomain, port = getDomainFromActor(blockActor) if os.path.isfile(baseDir + '/img/block-background.png'): if not os.path.isfile(baseDir + '/accounts/block-background.png'): copyfile(baseDir + '/img/block-background.png', baseDir + '/accounts/block-background.png') cssFilename = baseDir + '/epicyon-follow.css' if os.path.isfile(baseDir + '/follow.css'): cssFilename = baseDir + '/follow.css' profileStyle = getCSS(baseDir, cssFilename, cssCache) blockStr = htmlHeader(cssFilename, profileStyle) blockStr += '
\n' blockStr += '
\n' blockStr += '
\n' blockStr += ' \n' blockStr += ' \n' blockStr += \ '

' + translate['Stop blocking'] + ' ' + \ getNicknameFromActor(blockActor) + '@' + blockDomain + ' ?

\n' blockStr += '
\n' blockStr += ' \n' blockStr += \ ' \n' blockStr += \ ' \n' blockStr += '
\n' blockStr += '
\n' blockStr += '
\n' blockStr += '
\n' blockStr += htmlFooter() return blockStr