__filename__ = "webapp_moderation.py" __author__ = "Bob Mottram" __license__ = "AGPL3+" __version__ = "1.1.0" __maintainer__ = "Bob Mottram" __email__ = "bob@freedombone.net" __status__ = "Production" import os from utils import isEditor from utils import loadJson from utils import getNicknameFromActor from utils import getDomainFromActor from posts import getPublicPostInfo from posts import isModerator from webapp_timeline import htmlTimeline # from webapp_utils import getPersonAvatarUrl from webapp_utils import getContentWarningButton from webapp_utils import htmlHeaderWithExternalStyle from webapp_utils import htmlFooter from blocking import isBlockedDomain def htmlModeration(cssCache: {}, defaultTimeline: str, recentPostsCache: {}, maxRecentPosts: int, translate: {}, pageNumber: int, itemsPerPage: int, session, baseDir: str, wfRequest: {}, personCache: {}, nickname: str, domain: str, port: int, inboxJson: {}, allowDeletion: bool, httpPrefix: str, projectVersion: str, YTReplacementDomain: str, showPublishedDateOnly: bool, newswire: {}, positiveVoting: bool, showPublishAsIcon: bool, fullWidthTimelineButtonHeader: bool, iconsAsButtons: bool, rssIconAtTop: bool, publishButtonAtTop: bool, authorized: bool, moderationActionStr: str, theme: str, peertubeInstances: []) -> str: """Show the moderation feed as html This is what you see when selecting the "mod" timeline """ return htmlTimeline(cssCache, defaultTimeline, recentPostsCache, maxRecentPosts, translate, pageNumber, itemsPerPage, session, baseDir, wfRequest, personCache, nickname, domain, port, inboxJson, 'moderation', allowDeletion, httpPrefix, projectVersion, True, False, YTReplacementDomain, showPublishedDateOnly, newswire, False, False, positiveVoting, showPublishAsIcon, fullWidthTimelineButtonHeader, iconsAsButtons, rssIconAtTop, publishButtonAtTop, authorized, moderationActionStr, theme, peertubeInstances) def htmlAccountInfo(cssCache: {}, translate: {}, baseDir: str, httpPrefix: str, nickname: str, domain: str, port: int, searchHandle: str, debug: bool) -> str: """Shows which domains a search handle interacts with. This screen is shown if a moderator enters a handle and selects info on the moderation screen """ msgStr1 = 'This account interacts with the following instances' infoForm = '' cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.css' infoForm = htmlHeaderWithExternalStyle(cssFilename) searchNickname = getNicknameFromActor(searchHandle) searchDomain, searchPort = getDomainFromActor(searchHandle) searchHandle = searchNickname + '@' + searchDomain infoForm += \ '

' + \ translate['Account Information'] + ': ' + searchHandle + '


' infoForm += translate[msgStr1] + '


' proxyType = 'tor' if not os.path.isfile('/usr/bin/tor'): proxyType = None if domain.endswith('.i2p'): proxyType = None domainDict = getPublicPostInfo(None, baseDir, searchNickname, searchDomain, proxyType, searchPort, httpPrefix, debug, __version__) infoForm += '
' usersPath = '/users/' + nickname + '/accountinfo' ctr = 1 for postDomain, blockedPostUrls in domainDict.items(): infoForm += '' + postDomain + ' ' if isBlockedDomain(baseDir, postDomain): blockedPostsLinks = '' urlCtr = 0 for url in blockedPostUrls: if urlCtr > 0: blockedPostsLinks += '
' blockedPostsLinks += \ '' + url + '' urlCtr += 1 blockedPostsHtml = '' if blockedPostsLinks: blockNoStr = 'blockNumber' + str(ctr) blockedPostsHtml = \ getContentWarningButton(blockNoStr, translate, blockedPostsLinks) ctr += 1 infoForm += \ '' infoForm += ' ' + \ blockedPostsHtml else: infoForm += \ '' if postDomain != domain: infoForm += '' infoForm += '' infoForm += '
' infoForm += '
' infoForm += htmlFooter() return infoForm def htmlModerationInfo(cssCache: {}, translate: {}, baseDir: str, httpPrefix: str, nickname: str) -> str: msgStr1 = \ 'These are globally blocked for all accounts on this instance' msgStr2 = \ 'Any blocks or suspensions made by moderators will be shown here.' infoForm = '' cssFilename = baseDir + '/epicyon-profile.css' if os.path.isfile(baseDir + '/epicyon.css'): cssFilename = baseDir + '/epicyon.css' infoForm = htmlHeaderWithExternalStyle(cssFilename) infoForm += \ '

' + \ translate['Moderation Information'] + \ '


' infoShown = False accounts = [] for subdir, dirs, files in os.walk(baseDir + '/accounts'): for acct in dirs: if '@' not in acct: continue if 'inbox@' in acct or 'news@' in acct: continue accounts.append(acct) break accounts.sort() cols = 5 if len(accounts) > 10: infoForm += '
' + translate['Show Accounts'] infoForm += '\n' infoForm += '
\n' infoForm += '\n' infoForm += ' \n' for col in range(cols): infoForm += ' \n' infoForm += ' \n' infoForm += '\n' col = 0 for acct in accounts: acctNickname = acct.split('@')[0] accountDir = os.path.join(baseDir + '/accounts', acct) actorJson = loadJson(accountDir + '.json') if not actorJson: continue actor = actorJson['id'] avatarUrl = '' ext = '' if actorJson.get('icon'): if actorJson['icon'].get('url'): avatarUrl = actorJson['icon']['url'] if '.' in avatarUrl: ext = '.' + avatarUrl.split('.')[-1] acctUrl = \ '/users/' + nickname + '?options=' + actor + ';1;' + \ '/members/' + acctNickname + ext infoForm += '\n' col += 1 if col == cols: # new row of accounts infoForm += '\n\n' infoForm += '\n
\n' infoForm += '' infoForm += '
' if isModerator(baseDir, acctNickname): infoForm += '' + acctNickname + '' else: infoForm += acctNickname if isEditor(baseDir, acctNickname): infoForm += ' ✍' infoForm += '
\n
\n' infoForm += '
\n' if len(accounts) > 10: infoForm += '
\n' suspendedFilename = baseDir + '/accounts/suspended.txt' if os.path.isfile(suspendedFilename): with open(suspendedFilename, "r") as f: suspendedStr = f.read() infoForm += '
\n' infoForm += '
' + \ translate['Suspended accounts'] + '' infoForm += '
' + \ translate['These are currently suspended'] infoForm += \ ' \n' infoForm += '
\n' infoShown = True blockingFilename = baseDir + '/accounts/blocking.txt' if os.path.isfile(blockingFilename): with open(blockingFilename, "r") as f: blockedStr = f.read() infoForm += '
\n' infoForm += \ '
' + \ translate['Blocked accounts and hashtags'] + '' infoForm += \ '
' + \ translate[msgStr1] infoForm += \ ' \n' infoForm += '
\n' infoShown = True filtersFilename = baseDir + '/accounts/filters.txt' if os.path.isfile(filtersFilename): with open(filtersFilename, "r") as f: filteredStr = f.read() infoForm += '
\n' infoForm += \ '
' + \ translate['Filtered words'] + '' infoForm += \ ' \n' infoForm += '
\n' infoShown = True if not infoShown: infoForm += \ '

' + \ translate[msgStr2] + \ '

\n' infoForm += htmlFooter() return infoForm