__filename__ = "webapp_person_options.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.2.0" __maintainer__ = "Bob Mottram" __email__ = "bob@libreserver.org" __status__ = "Production" __module_group__ = "Web Interface" import os from shutil import copyfile from petnames import getPetName from person import isPersonSnoozed from posts import isModerator from utils import getFullDomain from utils import getConfigParam from utils import isDormant from utils import removeHtml from utils import getDomainFromActor from utils import getNicknameFromActor from utils import isFeaturedWriter from utils import acctDir from blocking import isBlocked from follow import isFollowerOfPerson from follow import isFollowingActor from followingCalendar import receivingCalendarEvents from notifyOnPost import notifyWhenPersonPosts from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlFooter from webapp_utils import getBrokenLinkSubstitute from webapp_utils import htmlKeyboardNavigation def htmlPersonOptions(defaultTimeline: str, cssCache: {}, translate: {}, baseDir: str, domain: str, domainFull: str, originPathStr: str, optionsActor: str, optionsProfileUrl: str, optionsLink: str, pageNumber: int, donateUrl: str, webAddress: str, xmppAddress: str, matrixAddress: str, ssbAddress: str, blogAddress: str, toxAddress: str, briarAddress: str, jamiAddress: str, cwtchAddress: str, PGPpubKey: str, PGPfingerprint: str, emailAddress: str, dormantMonths: int, backToPath: str, lockedAccount: bool, movedTo: str, alsoKnownAs: [], textModeBanner: str, newsInstance: bool, authorized: bool, accessKeys: {}, isGroup: bool) -> str: """Show options for a person: view/follow/block/report """ optionsDomain, optionsPort = getDomainFromActor(optionsActor) optionsDomainFull = getFullDomain(optionsDomain, optionsPort) if os.path.isfile(baseDir + '/accounts/options-background-custom.jpg'): if not os.path.isfile(baseDir + '/accounts/options-background.jpg'): copyfile(baseDir + '/accounts/options-background.jpg', baseDir + '/accounts/options-background.jpg') dormant = False followStr = 'Follow' if isGroup: followStr = 'Join' blockStr = 'Block' nickname = None optionsNickname = None followsYou = False if originPathStr.startswith('/users/'): nickname = originPathStr.split('/users/')[1] if '/' in nickname: nickname = nickname.split('/')[0] if '?' in nickname: nickname = nickname.split('?')[0] followerDomain, followerPort = getDomainFromActor(optionsActor) if isFollowingActor(baseDir, nickname, domain, optionsActor): followStr = 'Unfollow' if isGroup: followStr = 'Leave' dormant = \ isDormant(baseDir, nickname, domain, optionsActor, dormantMonths) optionsNickname = getNicknameFromActor(optionsActor) optionsDomainFull = getFullDomain(optionsDomain, optionsPort) followsYou = \ isFollowerOfPerson(baseDir, nickname, domain, optionsNickname, optionsDomainFull) if isBlocked(baseDir, nickname, domain, optionsNickname, optionsDomainFull): blockStr = 'Block' optionsLinkStr = '' if optionsLink: optionsLinkStr = \ ' \n' cssFilename = baseDir + '/epicyon-options.css' if os.path.isfile(baseDir + '/options.css'): cssFilename = baseDir + '/options.css' # To snooze, or not to snooze? That is the question snoozeButtonStr = 'Snooze' if nickname: if isPersonSnoozed(baseDir, nickname, domain, optionsActor): snoozeButtonStr = 'Unsnooze' donateStr = '' if donateUrl: donateStr = \ ' \n' instanceTitle = \ getConfigParam(baseDir, 'instanceTitle') optionsStr = htmlHeaderWithExternalStyle(cssFilename, instanceTitle, None) optionsStr += htmlKeyboardNavigation(textModeBanner, {}, {}) optionsStr += '

\n' optionsStr += '
\n' optionsStr += '
\n' optionsStr += '
\n' optionsStr += ' \n' optionsStr += ' \n' handle = getNicknameFromActor(optionsActor) + '@' + optionsDomain handleShown = handle if lockedAccount: handleShown += '🔒' if movedTo: handleShown += ' ⌂' if dormant: handleShown += ' 💤' optionsStr += \ '

' + translate['Options for'] + \ ' @' + handleShown + '

\n' if followsYou: optionsStr += \ '

' + translate['Follows you'] + '

\n' if movedTo: newNickname = getNicknameFromActor(movedTo) newDomain, newPort = getDomainFromActor(movedTo) if newNickname and newDomain: newHandle = newNickname + '@' + newDomain optionsStr += \ '

' + \ translate['New account'] + \ ': @' + newHandle + '

\n' elif alsoKnownAs: otherAccountsHtml = \ '

' + \ translate['Other accounts'] + ': ' ctr = 0 if isinstance(alsoKnownAs, list): for altActor in alsoKnownAs: if altActor == optionsActor: continue if ctr > 0: otherAccountsHtml += ' ' ctr += 1 altDomain, altPort = getDomainFromActor(altActor) otherAccountsHtml += \ '' + altDomain + '' elif isinstance(alsoKnownAs, str): if alsoKnownAs != optionsActor: ctr += 1 altDomain, altPort = getDomainFromActor(alsoKnownAs) otherAccountsHtml += \ '' + altDomain + '' otherAccountsHtml += '

\n' if ctr > 0: optionsStr += otherAccountsHtml if emailAddress: optionsStr += \ '

' + translate['Email'] + \ ': ' + removeHtml(emailAddress) + '

\n' if xmppAddress: optionsStr += \ '

' + translate['XMPP'] + \ ': ' + \ xmppAddress + '

\n' if matrixAddress: optionsStr += \ '

' + translate['Matrix'] + ': ' + \ removeHtml(matrixAddress) + '

\n' if ssbAddress: optionsStr += \ '

SSB: ' + removeHtml(ssbAddress) + '

\n' if blogAddress: optionsStr += \ '

Blog: ' + \ removeHtml(blogAddress) + '

\n' if toxAddress: optionsStr += \ '

Tox: ' + removeHtml(toxAddress) + '

\n' if briarAddress: if briarAddress.startswith('briar://'): optionsStr += \ '

' + \ removeHtml(briarAddress) + '

\n' else: optionsStr += \ '

briar://' + \ removeHtml(briarAddress) + '

\n' if jamiAddress: optionsStr += \ '

Jami: ' + removeHtml(jamiAddress) + '

\n' if cwtchAddress: optionsStr += \ '

Cwtch: ' + removeHtml(cwtchAddress) + '

\n' if PGPfingerprint: optionsStr += '

PGP: ' + \ removeHtml(PGPfingerprint).replace('\n', '
') + '

\n' if PGPpubKey: optionsStr += '

' + \ removeHtml(PGPpubKey).replace('\n', '
') + '

\n' optionsStr += '
\n' optionsStr += ' \n' optionsStr += ' \n' optionsStr += ' \n' if authorized: if originPathStr == '/users/' + nickname: if optionsNickname: # handle = optionsNickname + '@' + optionsDomainFull petname = getPetName(baseDir, nickname, domain, handle) optionsStr += \ ' ' + translate['Petname'] + ': \n' + \ ' \n' \ '
\n' # Notify when a post arrives from this person if isFollowingActor(baseDir, nickname, domain, optionsActor): checkboxStr = \ ' 🔔' + \ translate['Notify me when this account posts'] + \ '\n
\n' if not notifyWhenPersonPosts(baseDir, nickname, domain, optionsNickname, optionsDomainFull): checkboxStr = checkboxStr.replace(' checked>', '>') optionsStr += checkboxStr checkboxStr = \ ' ' + \ translate['Receive calendar events from this account'] + \ '\n
\n' if not receivingCalendarEvents(baseDir, nickname, domain, optionsNickname, optionsDomainFull): checkboxStr = checkboxStr.replace(' checked>', '>') optionsStr += checkboxStr # checkbox for permission to post to newswire newswirePostsPermitted = False if optionsDomainFull == domainFull: adminNickname = getConfigParam(baseDir, 'admin') if (nickname == adminNickname or (isModerator(baseDir, nickname) and not isModerator(baseDir, optionsNickname))): newswireBlockedFilename = \ baseDir + '/accounts/' + \ optionsNickname + '@' + optionsDomain + '/.nonewswire' checkboxStr = \ ' ' + \ translate['Allow news posts'] + \ '\n
\n' if os.path.isfile(newswireBlockedFilename): checkboxStr = checkboxStr.replace(' checked>', '>') else: newswirePostsPermitted = True optionsStr += checkboxStr # whether blogs created by this account are moderated on # the newswire if newswirePostsPermitted: moderatedFilename = \ baseDir + '/accounts/' + \ optionsNickname + '@' + \ optionsDomain + '/.newswiremoderated' checkboxStr = \ ' ' + \ translate['News posts are moderated'] + \ '\n
\n' if not os.path.isfile(moderatedFilename): checkboxStr = checkboxStr.replace(' checked>', '>') optionsStr += checkboxStr # checkbox for permission to post to featured articles if newsInstance and optionsDomainFull == domainFull: adminNickname = getConfigParam(baseDir, 'admin') if (nickname == adminNickname or (isModerator(baseDir, nickname) and not isModerator(baseDir, optionsNickname))): checkboxStr = \ ' ' + \ translate['Featured writer'] + \ '\n
\n' if not isFeaturedWriter(baseDir, optionsNickname, optionsDomain): checkboxStr = checkboxStr.replace(' checked>', '>') optionsStr += checkboxStr optionsStr += optionsLinkStr backPath = '/' if nickname: backPath = '/users/' + nickname + '/' + defaultTimeline if 'moderation' in backToPath: backPath = '/users/' + nickname + '/moderation' if authorized and originPathStr == '/users/' + nickname: optionsStr += \ ' \n' else: optionsStr += \ ' \n' if authorized: optionsStr += \ ' \n' optionsStr += donateStr if authorized: optionsStr += \ ' \n' optionsStr += \ ' \n' optionsStr += \ ' \n' optionsStr += \ ' \n' optionsStr += \ ' \n' if isModerator(baseDir, nickname): optionsStr += \ ' \n' personNotes = '' if originPathStr == '/users/' + nickname: personNotesFilename = \ acctDir(baseDir, nickname, domain) + \ '/notes/' + handle + '.txt' if os.path.isfile(personNotesFilename): with open(personNotesFilename, 'r') as fp: personNotes = fp.read() optionsStr += \ '

' + translate['Notes'] + ': \n' optionsStr += '
\n' optionsStr += \ ' \n' optionsStr += \ '
\n' + \ '
\n' + \ '
\n' + \ '
\n' optionsStr += htmlFooter() return optionsStr