str:
+
+def htmlLogin(translate: {}, baseDir: str, autocomplete=True) -> str:
"""Shows the login screen
"""
- accounts=noOfAccounts(baseDir)
+ accounts = noOfAccounts(baseDir)
- loginImage='login.png'
- loginImageFilename=None
- if os.path.isfile(baseDir+'/accounts/'+loginImage):
- loginImageFilename=baseDir+'/accounts/'+loginImage
- if os.path.isfile(baseDir+'/accounts/login.jpg'):
- loginImage='login.jpg'
- loginImageFilename=baseDir+'/accounts/'+loginImage
- if os.path.isfile(baseDir+'/accounts/login.jpeg'):
- loginImage='login.jpeg'
- loginImageFilename=baseDir+'/accounts/'+loginImage
- if os.path.isfile(baseDir+'/accounts/login.gif'):
- loginImage='login.gif'
- loginImageFilename=baseDir+'/accounts/'+loginImage
- if os.path.isfile(baseDir+'/accounts/login.webp'):
- loginImage='login.webp'
- loginImageFilename=baseDir+'/accounts/'+loginImage
+ loginImage = 'login.png'
+ loginImageFilename = None
+ if os.path.isfile(baseDir + '/accounts/' + loginImage):
+ loginImageFilename = baseDir + '/accounts/' + loginImage
+ if os.path.isfile(baseDir + '/accounts/login.jpg'):
+ loginImage = 'login.jpg'
+ loginImageFilename = baseDir + '/accounts/' + loginImage
+ if os.path.isfile(baseDir + '/accounts/login.jpeg'):
+ loginImage = 'login.jpeg'
+ loginImageFilename = baseDir + '/accounts/' + loginImage
+ if os.path.isfile(baseDir + '/accounts/login.gif'):
+ loginImage = 'login.gif'
+ loginImageFilename = baseDir + '/accounts/' + loginImage
+ if os.path.isfile(baseDir + '/accounts/login.webp'):
+ loginImage = 'login.webp'
+ loginImageFilename = baseDir + '/accounts/' + loginImage
if not loginImageFilename:
- loginImageFilename=baseDir+'/accounts/'+loginImage
- copyfile(baseDir+'/img/login.png',loginImageFilename)
- if os.path.isfile(baseDir+'/img/login-background.png'):
- if not os.path.isfile(baseDir+'/accounts/login-background.png'):
- copyfile(baseDir+'/img/login-background.png', \
- baseDir+'/accounts/login-background.png')
+ loginImageFilename = baseDir + '/accounts/' + loginImage
+ copyfile(baseDir + '/img/login.png', loginImageFilename)
+ if os.path.isfile(baseDir + '/img/login-background.png'):
+ if not os.path.isfile(baseDir + '/accounts/login-background.png'):
+ copyfile(baseDir + '/img/login-background.png',
+ baseDir + '/accounts/login-background.png')
- if accounts>0:
- loginText= \
- ''+ \
- translate['Welcome. Please enter your login details below.']+'
'
+ if accounts > 0:
+ loginText = \
+ '' + \
+ translate['Welcome. Please enter your login details below.'] + \
+ '
'
else:
- loginText= \
- ''+ \
- translate['Please enter some credentials']+'
'
- loginText+= \
- ''+ \
- translate['You will become the admin of this site.']+'
'
- if os.path.isfile(baseDir+'/accounts/login.txt'):
+ loginText = \
+ '' + \
+ translate['Please enter some credentials'] + '
'
+ loginText += \
+ '' + \
+ translate['You will become the admin of this site.'] + \
+ '
'
+ if os.path.isfile(baseDir + '/accounts/login.txt'):
# custom login message
- with open(baseDir+'/accounts/login.txt', 'r') as file:
- loginText=''+file.read()+'
'
+ with open(baseDir + '/accounts/login.txt', 'r') as file:
+ loginText = '' + file.read() + '
'
- cssFilename=baseDir+'/epicyon-login.css'
- if os.path.isfile(baseDir+'/login.css'):
- cssFilename=baseDir+'/login.css'
+ cssFilename = baseDir + '/epicyon-login.css'
+ if os.path.isfile(baseDir + '/login.css'):
+ cssFilename = baseDir + '/login.css'
with open(cssFilename, 'r') as cssFile:
- loginCSS=cssFile.read()
+ loginCSS = cssFile.read()
# show the register button
- registerButtonStr=''
- if getConfigParam(baseDir,'registration')=='open':
- if int(getConfigParam(baseDir,'registrationsRemaining'))>0:
- if accounts>0:
- loginText= \
- ''+ \
- translate['Welcome. Please login or register a new account.']+'
'
- registerButtonStr= \
+ registerButtonStr = ''
+ if getConfigParam(baseDir, 'registration') == 'open':
+ if int(getConfigParam(baseDir, 'registrationsRemaining')) > 0:
+ if accounts > 0:
+ idx = 'Welcome. Please login or register a new account.'
+ loginText = \
+ '' + \
+ translate[idx] + \
+ '
'
+ registerButtonStr = \
'Register '
- TOSstr= \
- ''+ \
- translate['Terms of Service']+'
'
- TOSstr+= \
- ''+ \
- translate['About this Instance']+'
'
+ TOSstr = \
+ '' + \
+ translate['Terms of Service'] + '
'
+ TOSstr += \
+ '' + \
+ translate['About this Instance'] + '
'
- loginButtonStr=''
- if accounts>0:
- loginButtonStr= \
- ''+ \
- translate['Login']+' '
+ loginButtonStr = ''
+ if accounts > 0:
+ loginButtonStr = \
+ '' + \
+ translate['Login'] + ' '
- autocompleteStr=''
+ autocompleteStr = ''
if not autocomplete:
- autocompleteStr='autocomplete="off" value=""'
+ autocompleteStr = 'autocomplete="off" value=""'
- loginForm=htmlHeader(cssFilename,loginCSS)
- loginForm+=''
+ loginForm += \
+ '' + \
+ ' '
+ loginForm += htmlFooter()
return loginForm
-def htmlTermsOfService(baseDir: str,httpPrefix: str,domainFull: str) -> str:
+
+def htmlTermsOfService(baseDir: str, httpPrefix: str, domainFull: str) -> str:
"""Show the terms of service screen
"""
- adminNickname=getConfigParam(baseDir,'admin')
- if not os.path.isfile(baseDir+'/accounts/tos.txt'):
- copyfile(baseDir+'/default_tos.txt',baseDir+'/accounts/tos.txt')
- if os.path.isfile(baseDir+'/img/login-background.png'):
- if not os.path.isfile(baseDir+'/accounts/login-background.png'):
- copyfile(baseDir+'/img/login-background.png', \
- baseDir+'/accounts/login-background.png')
+ adminNickname = getConfigParam(baseDir, 'admin')
+ if not os.path.isfile(baseDir + '/accounts/tos.txt'):
+ copyfile(baseDir + '/default_tos.txt',
+ baseDir + '/accounts/tos.txt')
+ if os.path.isfile(baseDir + '/img/login-background.png'):
+ if not os.path.isfile(baseDir + '/accounts/login-background.png'):
+ copyfile(baseDir + '/img/login-background.png',
+ baseDir + '/accounts/login-background.png')
- TOSText='Terms of Service go here.'
- if os.path.isfile(baseDir+'/accounts/tos.txt'):
- with open(baseDir+'/accounts/tos.txt', 'r') as file:
- TOSText=file.read()
+ TOSText = 'Terms of Service go here.'
+ if os.path.isfile(baseDir + '/accounts/tos.txt'):
+ with open(baseDir + '/accounts/tos.txt', 'r') as file:
+ TOSText = file.read()
- TOSForm=''
- cssFilename=baseDir+'/epicyon-profile.css'
- if os.path.isfile(baseDir+'/epicyon.css'):
- cssFilename=baseDir+'/epicyon.css'
+ TOSForm = ''
+ cssFilename = baseDir + '/epicyon-profile.css'
+ if os.path.isfile(baseDir + '/epicyon.css'):
+ cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
- termsCSS=cssFile.read()
- if httpPrefix!='https':
- termsCSS=termsCSS.replace('https://',httpPrefix+'://')
+ termsCSS = cssFile.read()
+ if httpPrefix != 'https':
+ termsCSS = termsCSS.replace('https://', httpPrefix+'://')
- TOSForm=htmlHeader(cssFilename,termsCSS)
- TOSForm+=''+TOSText+'
'
+ TOSForm = htmlHeader(cssFilename, termsCSS)
+ TOSForm += '' + TOSText + '
'
if adminNickname:
- adminActor=httpPrefix+'://'+domainFull+'/users/'+adminNickname
- TOSForm+= \
- ''
- TOSForm+=htmlFooter()
+ adminActor = httpPrefix + '://' + domainFull + \
+ '/users/' + adminNickname
+ TOSForm += \
+ ''
+ TOSForm += htmlFooter()
return TOSForm
-def htmlAbout(baseDir: str,httpPrefix: str,domainFull: str) -> str:
+
+def htmlAbout(baseDir: str, httpPrefix: str, domainFull: str) -> str:
"""Show the about screen
"""
- adminNickname=getConfigParam(baseDir,'admin')
- if not os.path.isfile(baseDir+'/accounts/about.txt'):
- copyfile(baseDir+'/default_about.txt',baseDir+'/accounts/about.txt')
- if os.path.isfile(baseDir+'/img/login-background.png'):
- if not os.path.isfile(baseDir+'/accounts/login-background.png'):
- copyfile(baseDir+'/img/login-background.png', \
- baseDir+'/accounts/login-background.png')
+ adminNickname = getConfigParam(baseDir, 'admin')
+ if not os.path.isfile(baseDir + '/accounts/about.txt'):
+ copyfile(baseDir + '/default_about.txt',
+ baseDir + '/accounts/about.txt')
+ if os.path.isfile(baseDir + '/img/login-background.png'):
+ if not os.path.isfile(baseDir + '/accounts/login-background.png'):
+ copyfile(baseDir + '/img/login-background.png',
+ baseDir + '/accounts/login-background.png')
- aboutText='Information about this instance goes here.'
- if os.path.isfile(baseDir+'/accounts/about.txt'):
- with open(baseDir+'/accounts/about.txt', 'r') as file:
- aboutText=file.read()
+ aboutText = 'Information about this instance goes here.'
+ if os.path.isfile(baseDir + '/accounts/about.txt'):
+ with open(baseDir + '/accounts/about.txt', 'r') as file:
+ aboutText = file.read()
- aboutForm=''
- cssFilename=baseDir+'/epicyon-profile.css'
- if os.path.isfile(baseDir+'/epicyon.css'):
- cssFilename=baseDir+'/epicyon.css'
+ aboutForm = ''
+ cssFilename = baseDir + '/epicyon-profile.css'
+ if os.path.isfile(baseDir + '/epicyon.css'):
+ cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
- termsCSS=cssFile.read()
- if httpPrefix!='http':
- termsCSS=termsCSS.replace('https://',httpPrefix+'://')
+ termsCSS = cssFile.read()
+ if httpPrefix != 'http':
+ termsCSS = termsCSS.replace('https://',
+ httpPrefix + '://')
- aboutForm=htmlHeader(cssFilename,termsCSS)
- aboutForm+=''+aboutText+'
'
+ aboutForm = htmlHeader(cssFilename, termsCSS)
+ aboutForm += '' + aboutText + '
'
if adminNickname:
- adminActor=httpPrefix+'://'+domainFull+'/users/'+adminNickname
- aboutForm+= \
- ''
- aboutForm+=htmlFooter()
+ adminActor = \
+ httpPrefix + '://' + domainFull + '/users/' + adminNickname
+ aboutForm += \
+ ''
+ aboutForm += htmlFooter()
return aboutForm
+
def htmlHashtagBlocked(baseDir: str) -> 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'
+ blockedHashtagForm = ''
+ cssFilename = baseDir + '/epicyon-suspended.css'
+ if os.path.isfile(baseDir + '/suspended.css'):
+ cssFilename = baseDir + '/suspended.css'
with open(cssFilename, 'r') as cssFile:
- blockedHashtagCSS=cssFile.read()
- blockedHashtagForm=htmlHeader(cssFilename,blockedHashtagCSS)
- blockedHashtagForm+=''
- blockedHashtagForm+=' Hashtag Blocked
'
- blockedHashtagForm+=' See Terms of Service
'
- blockedHashtagForm+=' '
- blockedHashtagForm+=htmlFooter()
+ blockedHashtagCSS = cssFile.read()
+ blockedHashtagForm = htmlHeader(cssFilename,
+ blockedHashtagCSS)
+ blockedHashtagForm += ''
+ blockedHashtagForm += ' Hashtag Blocked
'
+ blockedHashtagForm += \
+ ' See Terms of Service
'
+ blockedHashtagForm += ' '
+ blockedHashtagForm += htmlFooter()
return blockedHashtagForm
+
def htmlSuspended(baseDir: str) -> str:
"""Show the screen for suspended accounts
"""
- suspendedForm=''
- cssFilename=baseDir+'/epicyon-suspended.css'
- if os.path.isfile(baseDir+'/suspended.css'):
- cssFilename=baseDir+'/suspended.css'
+ suspendedForm = ''
+ cssFilename = baseDir + '/epicyon-suspended.css'
+ if os.path.isfile(baseDir + '/suspended.css'):
+ cssFilename = baseDir + '/suspended.css'
with open(cssFilename, 'r') as cssFile:
- suspendedCSS=cssFile.read()
- suspendedForm=htmlHeader(cssFilename,suspendedCSS)
- suspendedForm+=''
- suspendedForm+=' Account Suspended
'
- suspendedForm+=' See Terms of Service
'
- suspendedForm+=' '
- suspendedForm+=htmlFooter()
+ suspendedCSS = cssFile.read()
+ suspendedForm = htmlHeader(cssFilename, suspendedCSS)
+ suspendedForm += ''
+ suspendedForm += ' Account Suspended
'
+ suspendedForm += ' See Terms of Service
'
+ suspendedForm += ' '
+ suspendedForm += htmlFooter()
return suspendedForm
-def htmlNewPost(mediaInstance: bool,translate: {}, \
- baseDir: str,httpPrefix: str, \
- path: str,inReplyTo: str, \
- mentions: [], \
- reportUrl: str,pageNumber: int, \
- nickname: str,domain: str) -> str:
+
+def htmlNewPost(mediaInstance: bool, translate: {},
+ baseDir: str, httpPrefix: str,
+ path: str, inReplyTo: str,
+ mentions: [],
+ reportUrl: str, pageNumber: int,
+ nickname: str, domain: str) -> str:
"""New post screen
"""
- iconsDir=getIconsDir(baseDir)
- replyStr=''
+ iconsDir = getIconsDir(baseDir)
+ replyStr = ''
- showPublicOnDropdown=True
+ showPublicOnDropdown = True
if not path.endswith('/newshare'):
if not path.endswith('/newreport'):
if not inReplyTo:
- newPostText=''+translate['Write your post text below.']+'
'
+ newPostText = '' + \
+ translate['Write your post text below.'] + '
'
else:
- newPostText= \
- ''+translate['Write your reply to']+ \
- ' '+translate['this post']+'
'
- replyStr=' '
+ newPostText = \
+ '' + \
+ translate['Write your reply to'] + \
+ ' ' + \
+ translate['this post'] + '
'
+ replyStr = ' '
- # if replying to a non-public post then also make this post non-public
- if not isPublicPostFromUrl(baseDir,nickname,domain,inReplyTo):
- newPostPath=path
+ # if replying to a non-public post then also make
+ # this post non-public
+ if not isPublicPostFromUrl(baseDir, nickname, domain,
+ inReplyTo):
+ newPostPath = path
if '?' in newPostPath:
- newPostPath=newPostPath.split('?')[0]
+ newPostPath = newPostPath.split('?')[0]
if newPostPath.endswith('/newpost'):
- path=path.replace('/newpost','/newfollowers')
+ path = path.replace('/newpost', '/newfollowers')
elif newPostPath.endswith('/newunlisted'):
- path=path.replace('/newunlisted','/newfollowers')
- showPublicOnDropdown=False
+ path = path.replace('/newunlisted', '/newfollowers')
+ showPublicOnDropdown = False
else:
- newPostText= \
- ''+translate['Write your report below.']+'
'
+ newPostText = \
+ '' + \
+ translate['Write your report below.'] + '
'
# custom report header with any additional instructions
- if os.path.isfile(baseDir+'/accounts/report.txt'):
- with open(baseDir+'/accounts/report.txt', 'r') as file:
- customReportText=file.read()
+ if os.path.isfile(baseDir + '/accounts/report.txt'):
+ with open(baseDir + '/accounts/report.txt', 'r') as file:
+ customReportText = file.read()
if '' not in customReportText:
- customReportText= \
- ''+customReportText+'
'
- customReportText= \
- customReportText.replace('','
')
- newPostText+=customReportText
+ customReportText = \
+ '
' + \
+ customReportText + '
'
+ repStr = ''
+ customReportText = \
+ customReportText.replace('
', repStr)
+ newPostText += customReportText
- newPostText+= \
- '
'+ \
- translate['This message only goes to moderators, even if it mentions other fediverse addresses.']+ \
- '
'+translate['Also see']+ \
- ' '+translate['Terms of Service']+'
'
+ idx = 'This message only goes to moderators, even if it ' + \
+ 'mentions other fediverse addresses.'
+ newPostText += \
+ '' + translate[idx] + \
+ '
' + translate['Also see'] + \
+ ' ' + \
+ translate['Terms of Service'] + '
'
else:
- newPostText= \
- ''+ \
- translate['Enter the details for your shared item below.']+'
'
+ newPostText = \
+ '' + \
+ translate['Enter the details for your shared item below.'] + '
'
if path.endswith('/newquestion'):
- newPostText= \
- ''+ \
- translate['Enter the choices for your question below.']+'
'
+ newPostText = \
+ '' + \
+ translate['Enter the choices for your question below.'] + '
'
- if os.path.isfile(baseDir+'/accounts/newpost.txt'):
- with open(baseDir+'/accounts/newpost.txt', 'r') as file:
- newPostText=''+file.read()+'
'
+ if os.path.isfile(baseDir + '/accounts/newpost.txt'):
+ with open(baseDir + '/accounts/newpost.txt', 'r') as file:
+ newPostText = \
+ '' + file.read() + '
'
- cssFilename=baseDir+'/epicyon-profile.css'
- if os.path.isfile(baseDir+'/epicyon.css'):
- cssFilename=baseDir+'/epicyon.css'
+ cssFilename = baseDir + '/epicyon-profile.css'
+ if os.path.isfile(baseDir + '/epicyon.css'):
+ cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
- newPostCSS=cssFile.read()
- if httpPrefix!='https':
- newPostCSS=newPostCSS.replace('https://',httpPrefix+'://')
+ newPostCSS = cssFile.read()
+ if httpPrefix != 'https':
+ newPostCSS = newPostCSS.replace('https://',
+ httpPrefix + '://')
if '?' in path:
- path=path.split('?')[0]
- pathBase= \
- path.replace('/newreport','').replace('/newpost','').replace('/newblog','').replace('/newshare','').replace('/newunlisted','').replace('/newfollowers','').replace('/newdm','')
+ path = path.split('?')[0]
+ pathBase = path.replace('/newreport', '').replace('/newpost', '')
+ pathBase = pathBase.replace('/newblog', '').replace('/newshare', '')
+ pathBase = pathBase.replace('/newunlisted', '')
+ pathBase = pathBase.replace('/newfollowers', '').replace('/newdm', '')
- newPostImageSection =' '
- newPostImageSection+=' '+translate['Image description']+' '
- newPostImageSection+=' '
- newPostImageSection+=' '
- newPostImageSection+='
'
+ newPostImageSection = ' '
+ newPostImageSection += \
+ ' ' + translate['Image description'] + \
+ ' '
+ newPostImageSection += ' '
+ newPostImageSection += \
+ ' '
+ newPostImageSection += '
'
- scopeIcon='scope_public.png'
- scopeDescription=translate['Public']
- placeholderSubject=translate['Subject or Content Warning (optional)']+'...'
- placeholderMessage=translate['Write something']+'...'
- extraFields=''
- endpoint='newpost'
+ scopeIcon = 'scope_public.png'
+ scopeDescription = translate['Public']
+ placeholderSubject = \
+ translate['Subject or Content Warning (optional)'] + '...'
+ placeholderMessage = translate['Write something'] + '...'
+ extraFields = ''
+ endpoint = 'newpost'
if path.endswith('/newblog'):
- placeholderSubject=translate['Title']
- scopeIcon='scope_blog.png'
- scopeDescription=translate['Blog']
- endpoint='newblog'
+ placeholderSubject = translate['Title']
+ scopeIcon = 'scope_blog.png'
+ scopeDescription = translate['Blog']
+ endpoint = 'newblog'
elif path.endswith('/newunlisted'):
- scopeIcon='scope_unlisted.png'
- scopeDescription=translate['Unlisted']
- endpoint='newunlisted'
+ scopeIcon = 'scope_unlisted.png'
+ scopeDescription = translate['Unlisted']
+ endpoint = 'newunlisted'
elif path.endswith('/newfollowers'):
- scopeIcon='scope_followers.png'
- scopeDescription=translate['Followers']
- endpoint='newfollowers'
+ scopeIcon = 'scope_followers.png'
+ scopeDescription = translate['Followers']
+ endpoint = 'newfollowers'
elif path.endswith('/newdm'):
- scopeIcon='scope_dm.png'
- scopeDescription=translate['DM']
- endpoint='newdm'
+ scopeIcon = 'scope_dm.png'
+ scopeDescription = translate['DM']
+ endpoint = 'newdm'
elif path.endswith('/newreport'):
- scopeIcon='scope_report.png'
- scopeDescription=translate['Report']
- endpoint='newreport'
+ scopeIcon = 'scope_report.png'
+ scopeDescription = translate['Report']
+ endpoint = 'newreport'
elif path.endswith('/newquestion'):
- scopeIcon='scope_question.png'
- scopeDescription=translate['Question']
- placeholderMessage=translate['Enter your question']+'...'
- endpoint='newquestion'
- extraFields=''
elif path.endswith('/newshare'):
- scopeIcon='scope_share.png'
- scopeDescription=translate['Shared Item']
- placeholderSubject=translate['Name of the shared item']+'...'
- placeholderMessage=translate['Description of the item being shared']+'...'
- endpoint='newshare'
- extraFields=''
- extraFields+= \
- ' '+ \
- translate['Type of shared item. eg. hat']+': '
- extraFields+=' '
- extraFields+= \
- ' '+ \
- translate['Category of shared item. eg. clothing']+': '
- extraFields+=' '
- extraFields+= \
- ' '+ \
- translate['Duration of listing in days']+': '
- extraFields+=' '
- extraFields+='
'
- extraFields+=''
- extraFields+= \
- ''+ \
- translate['City or location of the shared item']+': '
- extraFields+=' '
- extraFields+='
'
+ scopeIcon = 'scope_share.png'
+ scopeDescription = translate['Shared Item']
+ placeholderSubject = translate['Name of the shared item'] + '...'
+ placeholderMessage = \
+ translate['Description of the item being shared'] + '...'
+ endpoint = 'newshare'
+ extraFields = ''
+ extraFields += \
+ ' ' + \
+ translate['Type of shared item. eg. hat'] + ': '
+ extraFields += ' '
+ extraFields += \
+ ' ' + \
+ translate['Category of shared item. eg. clothing'] + ': '
+ extraFields += ' '
+ extraFields += \
+ ' ' + \
+ translate['Duration of listing in days'] + ': '
+ extraFields += ' '
+ extraFields += '
'
+ extraFields += ''
+ extraFields += \
+ '' + \
+ translate['City or location of the shared item'] + ': '
+ extraFields += ' '
+ extraFields += '
'
- dateAndLocation=''
- if endpoint!='newshare' and endpoint!='newreport' and endpoint!='newquestion':
- dateAndLocation=''
+ dateAndLocation += ''
+ dateAndLocation += '' + \
+ translate['Location'] + ': '
+ dateAndLocation += ' '
+ dateAndLocation += '
'
- newPostForm=htmlHeader(cssFilename,newPostCSS)
+ newPostForm = htmlHeader(cssFilename, newPostCSS)
# only show the share option if this is not a reply
- shareOptionOnDropdown=''
- questionOptionOnDropdown=''
+ shareOptionOnDropdown = ''
+ questionOptionOnDropdown = ''
if not replyStr:
- shareOptionOnDropdown= \
- ''+translate['Shares']+ \
- ' '+translate['Describe a shared item']+' '
- questionOptionOnDropdown= \
- ''+translate['Question']+ \
- ' '+translate['Ask a question']+' '
+ shareOptionOnDropdown = \
+ '' + translate['Shares'] + \
+ ' ' + translate['Describe a shared item'] + ' '
+ questionOptionOnDropdown = \
+ '' + translate['Question'] + \
+ ' ' + translate['Ask a question'] + ' '
- mentionsStr=''
+ mentionsStr = ''
for m in mentions:
- mentionNickname=getNicknameFromActor(m)
+ mentionNickname = getNicknameFromActor(m)
if not mentionNickname:
continue
- mentionDomain,mentionPort=getDomainFromActor(m)
+ mentionDomain, mentionPort = getDomainFromActor(m)
if not mentionDomain:
continue
if mentionPort:
- mentionsHandle= \
- '@'+mentionNickname+'@'+mentionDomain+':'+str(mentionPort)
+ mentionsHandle = \
+ '@' + mentionNickname + '@' + \
+ mentionDomain + ':' + str(mentionPort)
else:
- mentionsHandle='@'+mentionNickname+'@'+mentionDomain
+ mentionsHandle = '@' + mentionNickname + '@' + mentionDomain
if mentionsHandle not in mentionsStr:
- mentionsStr+=mentionsHandle+' '
+ mentionsStr += mentionsHandle + ' '
# build suffixes so that any replies or mentions are
# preserved when switching between scopes
- dropdownNewPostSuffix='/newpost'
- dropdownNewBlogSuffix='/newblog'
- dropdownUnlistedSuffix='/newunlisted'
- dropdownFollowersSuffix='/newfollowers'
- dropdownDMSuffix='/newdm'
- dropdownReportSuffix='/newreport'
+ dropdownNewPostSuffix = '/newpost'
+ dropdownNewBlogSuffix = '/newblog'
+ dropdownUnlistedSuffix = '/newunlisted'
+ dropdownFollowersSuffix = '/newfollowers'
+ dropdownDMSuffix = '/newdm'
+ dropdownReportSuffix = '/newreport'
if inReplyTo or mentions:
- dropdownNewPostSuffix=''
- dropdownNewBlogSuffix=''
- dropdownUnlistedSuffix=''
- dropdownFollowersSuffix=''
- dropdownDMSuffix=''
- dropdownReportSuffix=''
+ dropdownNewPostSuffix = ''
+ dropdownNewBlogSuffix = ''
+ dropdownUnlistedSuffix = ''
+ dropdownFollowersSuffix = ''
+ dropdownDMSuffix = ''
+ dropdownReportSuffix = ''
if inReplyTo:
- dropdownNewPostSuffix+='?replyto='+inReplyTo
- dropdownNewBlogSuffix+='?replyto='+inReplyTo
- dropdownUnlistedSuffix+='?replyto='+inReplyTo
- dropdownFollowersSuffix+='?replyfollowers='+inReplyTo
- dropdownDMSuffix+='?replydm='+inReplyTo
+ dropdownNewPostSuffix += '?replyto=' + inReplyTo
+ dropdownNewBlogSuffix += '?replyto=' + inReplyTo
+ dropdownUnlistedSuffix += '?replyto=' + inReplyTo
+ dropdownFollowersSuffix += '?replyfollowers=' + inReplyTo
+ dropdownDMSuffix += '?replydm=' + inReplyTo
for mentionedActor in mentions:
- dropdownNewPostSuffix+='?mention='+mentionedActor
- dropdownNewBlogSuffix+='?mention='+mentionedActor
- dropdownUnlistedSuffix+='?mention='+mentionedActor
- dropdownFollowersSuffix+='?mention='+mentionedActor
- dropdownDMSuffix+='?mention='+mentionedActor
- dropdownReportSuffix+='?mention='+mentionedActor
+ dropdownNewPostSuffix += '?mention=' + mentionedActor
+ dropdownNewBlogSuffix += '?mention=' + mentionedActor
+ dropdownUnlistedSuffix += '?mention=' + mentionedActor
+ dropdownFollowersSuffix += '?mention=' + mentionedActor
+ dropdownDMSuffix += '?mention=' + mentionedActor
+ dropdownReportSuffix += '?mention=' + mentionedActor
- dropDownContent=''
+ dropDownContent = ''
if not reportUrl:
- dropDownContent+=' '
else:
- mentionsStr='Re: '+reportUrl+'\n\n'+mentionsStr
+ mentionsStr = 'Re: ' + reportUrl + '\n\n' + mentionsStr
- newPostForm+= \
- ''
if not reportUrl:
- newPostForm+= \
- ''
- newPostForm= \
- newPostForm.replace('','')
+ newPostForm += \
+ ''
+ newPostForm = \
+ newPostForm.replace('', '')
- newPostForm+=htmlFooter()
+ newPostForm += htmlFooter()
return newPostForm
-def htmlHeader(cssFilename: str,css=None,refreshSec=0,lang='en') -> str:
- if refreshSec==0:
- meta=' \n'
+
+def htmlHeader(cssFilename: str, css=None, refreshSec=0, lang='en') -> str:
+ if refreshSec == 0:
+ meta = ' \n'
else:
- meta= \
- ' \n'
+ meta = \
+ ' \n'
if not css:
if '/' in cssFilename:
- cssFilename=cssFilename.split('/')[-1]
- htmlStr='\n'
- htmlStr+='\n'
- htmlStr+=meta
- htmlStr+=' \n'
- htmlStr+=' \n'
+ cssFilename = cssFilename.split('/')[-1]
+ htmlStr = '\n'
+ htmlStr += '\n'
+ htmlStr += meta
+ htmlStr += ' \n'
+ htmlStr += ' \n'
else:
- htmlStr='\n'
- htmlStr+='\n'
- htmlStr+=meta
- htmlStr+=' \n'
- htmlStr+=' \n'
+ htmlStr = '\n'
+ htmlStr += '\n'
+ htmlStr += meta
+ htmlStr += ' \n'
+ htmlStr += ' \n'
return htmlStr
+
def htmlFooter() -> str:
- htmlStr=' \n'
- htmlStr+='\n'
+ htmlStr = ' \n'
+ htmlStr += '\n'
return htmlStr
-def htmlProfilePosts(recentPostsCache: {},maxRecentPosts: int, \
- translate: {}, \
- baseDir: str,httpPrefix: str, \
- authorized: bool,ocapAlways: bool, \
- nickname: str,domain: str,port: int, \
- session,wfRequest: {},personCache: {}, \
+
+def htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
+ translate: {},
+ baseDir: str, httpPrefix: str,
+ authorized: bool, ocapAlways: bool,
+ nickname: str, domain: str, port: int,
+ session, wfRequest: {}, personCache: {},
projectVersion: str) -> str:
"""Shows posts on the profile screen
These should only be public posts
"""
- iconsDir=getIconsDir(baseDir)
- profileStr=''
- maxItems=4
- profileStr+=''
- ctr=0
- currPage=1
- while ctr' + contentWarningScript() + ''
+ ctr = 0
+ currPage = 1
+ while ctr < maxItems and currPage < 4:
+ outboxFeed = \
+ personBoxJson({}, session, baseDir, domain,
+ port,
+ '/users/' + nickname + '/outbox?page=' +
+ str(currPage),
+ httpPrefix,
+ 10, 'outbox',
+ authorized,
ocapAlways)
if not outboxFeed:
break
- if len(outboxFeed['orderedItems'])==0:
+ if len(outboxFeed['orderedItems']) == 0:
break
for item in outboxFeed['orderedItems']:
- if item['type']=='Create':
- postStr= \
- individualPostAsHtml(recentPostsCache,maxRecentPosts, \
- iconsDir,translate,None, \
- baseDir,session,wfRequest,personCache, \
- nickname,domain,port,item,None,True,False, \
- httpPrefix,projectVersion,'inbox', \
- False,False,False,True,False)
+ if item['type'] == 'Create':
+ postStr = \
+ individualPostAsHtml(recentPostsCache, maxRecentPosts,
+ iconsDir, translate, None,
+ baseDir, session, wfRequest,
+ personCache,
+ nickname, domain, port, item,
+ None, True, False,
+ httpPrefix, projectVersion, 'inbox',
+ False, False, False, True, False)
if postStr:
- profileStr+=postStr
- ctr+=1
- if ctr>=maxItems:
+ profileStr += postStr
+ ctr += 1
+ if ctr >= maxItems:
break
- currPage+=1
+ currPage += 1
return profileStr
-def htmlProfileFollowing(translate: {},baseDir: str,httpPrefix: str, \
- authorized: bool,ocapAlways: bool, \
- nickname: str,domain: str,port: int, \
- session,wfRequest: {},personCache: {}, \
- followingJson: {},projectVersion: str, \
- buttons: [], \
- feedName: str,actor: str, \
- pageNumber: int, \
+
+def htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
+ authorized: bool, ocapAlways: bool,
+ nickname: str, domain: str, port: int,
+ session, wfRequest: {}, personCache: {},
+ followingJson: {}, projectVersion: str,
+ buttons: [],
+ feedName: str, actor: str,
+ pageNumber: int,
maxItemsPerPage: int) -> str:
"""Shows following on the profile screen
"""
- profileStr=''
+ profileStr = ''
- iconsDir=getIconsDir(baseDir)
+ iconsDir = getIconsDir(baseDir)
if authorized and pageNumber:
- if authorized and pageNumber>1:
+ if authorized and pageNumber > 1:
# page up arrow
- profileStr+= \
- ' '
+ profileStr += \
+ ' '
for item in followingJson['orderedItems']:
- profileStr+= \
- individualFollowAsHtml(translate,baseDir,session, \
- wfRequest,personCache, \
- domain,item,authorized,nickname, \
- httpPrefix,projectVersion, \
+ profileStr += \
+ individualFollowAsHtml(translate, baseDir, session,
+ wfRequest, personCache,
+ domain, item, authorized, nickname,
+ httpPrefix, projectVersion,
buttons)
if authorized and maxItemsPerPage and pageNumber:
- if len(followingJson['orderedItems'])>=maxItemsPerPage:
+ if len(followingJson['orderedItems']) >= maxItemsPerPage:
# page down arrow
- profileStr+= \
- ' '
+ profileStr += \
+ ' '
return profileStr
-def htmlProfileRoles(translate: {},nickname: str,domain: str,rolesJson: {}) -> str:
+
+def htmlProfileRoles(translate: {}, nickname: str, domain: str,
+ rolesJson: {}) -> str:
"""Shows roles on the profile screen
"""
- profileStr=''
- for project,rolesList in rolesJson.items():
- profileStr+= \
- ''+project+' '
+ profileStr = ''
+ for project, rolesList in rolesJson.items():
+ profileStr += \
+ '
' + project + \
+ ' '
for role in rolesList:
- profileStr+='
'+role+' '
- profileStr+=''
- if len(profileStr)==0:
- profileStr+='
@'+nickname+'@'+domain+' has no roles assigned
'
+ profileStr += '
' + role + ' '
+ profileStr += '
'
+ if len(profileStr) == 0:
+ profileStr += \
+ '@' + nickname + '@' + domain + ' has no roles assigned
'
else:
- profileStr=''+profileStr+'
'
+ profileStr = '' + profileStr + '
'
return profileStr
-def htmlProfileSkills(translate: {},nickname: str,domain: str, \
+
+def htmlProfileSkills(translate: {}, nickname: str, domain: str,
skillsJson: {}) -> str:
"""Shows skills on the profile screen
"""
- profileStr=''
- for skill,level in skillsJson.items():
- profileStr+= \
- ' '
- if len(profileStr)>0:
- profileStr=''+profileStr+'
'
+ profileStr = ''
+ for skill, level in skillsJson.items():
+ profileStr += \
+ ' '
+ if len(profileStr) > 0:
+ profileStr = '' + \
+ profileStr + '
'
return profileStr
-def htmlIndividualShare(actor: str,item: {},translate: {}, \
- showContact: bool,removeButton: bool) -> str:
+
+def htmlIndividualShare(actor: str, item: {}, translate: {},
+ showContact: bool, removeButton: bool) -> str:
"""Returns an individual shared item as html
"""
- profileStr=''
- profileStr+='
'+item['displayName']+'
'
+ profileStr = '
'
+ profileStr += '
' + item['displayName'] + '
'
if item.get('imageUrl'):
- profileStr+='
'
- profileStr+= \
- ' '
- profileStr+='
'+item['summary']+'
'
- profileStr+='
'+translate['Type']+': '+item['itemType']+' '
- profileStr+=''+translate['Category']+': '+item['category']+' '
- profileStr+=''+translate['Location']+': '+item['location']+'
'
+ profileStr += '
'
+ profileStr += \
+ ' '
+ profileStr += '
' + item['summary'] + '
'
+ profileStr += \
+ '
' + translate['Type'] + ': ' + item['itemType'] + ' '
+ profileStr += \
+ '' + translate['Category'] + ': ' + item['category'] + ' '
+ profileStr += \
+ '' + translate['Location'] + ': ' + item['location'] + '
'
if showContact:
- contactActor=item['actor']
- profileStr+= \
- '
'+ \
- translate['Contact']+' '
+ contactActor = item['actor']
+ profileStr += \
+ '
' + \
+ translate['Contact'] + ' '
if removeButton:
- profileStr+= \
- ' '+translate['Remove']+' '
- profileStr+='
'
+ profileStr += \
+ '
' + \
+ translate['Remove'] + ' '
+ profileStr += '
'
return profileStr
-def htmlProfileShares(actor: str,translate: {}, \
- nickname: str,domain: str,sharesJson: {}) -> str:
+
+def htmlProfileShares(actor: str, translate: {},
+ nickname: str, domain: str, sharesJson: {}) -> str:
"""Shows shares on the profile screen
"""
- profileStr=''
+ profileStr = ''
for item in sharesJson['orderedItems']:
- profileStr+=htmlIndividualShare(actor,item,translate,False,False)
- if len(profileStr)>0:
- profileStr=''+profileStr+'
'
+ profileStr += htmlIndividualShare(actor, item, translate, False, False)
+ if len(profileStr) > 0:
+ profileStr = '' + profileStr + '
'
return profileStr
-def sharesTimelineJson(actor: str,pageNumber: int,itemsPerPage: int, \
- baseDir: str,maxSharesPerAccount: int) -> ({},bool):
+
+def sharesTimelineJson(actor: str, pageNumber: int, itemsPerPage: int,
+ baseDir: str, maxSharesPerAccount: int) -> ({}, bool):
"""Get a page on the shared items timeline as json
maxSharesPerAccount helps to avoid one person dominating the timeline
by sharing a large number of things
"""
- allSharesJson={}
- for subdir, dirs, files in os.walk(baseDir+'/accounts'):
+ allSharesJson = {}
+ for subdir, dirs, files in os.walk(baseDir + '/accounts'):
for handle in dirs:
if '@' in handle:
- accountDir=baseDir+'/accounts/'+handle
- sharesFilename=accountDir+'/shares.json'
+ accountDir = baseDir + '/accounts/' + handle
+ sharesFilename = accountDir + '/shares.json'
if os.path.isfile(sharesFilename):
- sharesJson=loadJson(sharesFilename)
+ sharesJson = loadJson(sharesFilename)
if not sharesJson:
continue
- nickname=handle.split('@')[0]
+ nickname = handle.split('@')[0]
# actor who owns this share
- owner=actor.split('/users/')[0]+'/users/'+nickname
- ctr=0
- for itemID,item in sharesJson.items():
+ owner = actor.split('/users/')[0] + '/users/' + nickname
+ ctr = 0
+ for itemID, item in sharesJson.items():
# assign owner to the item
- item['actor']=owner
- allSharesJson[str(item['published'])]=item
- ctr+=1
- if ctr>=maxSharesPerAccount:
+ item['actor'] = owner
+ allSharesJson[str(item['published'])] = item
+ ctr += 1
+ if ctr >= maxSharesPerAccount:
break
# sort the shared items in descending order of publication date
- sharesJson=OrderedDict(sorted(allSharesJson.items(),reverse=True))
- lastPage=False
- startIndex=itemsPerPage*pageNumber
- maxIndex=len(sharesJson.items())
- if maxIndex=maxIndex-itemsPerPage:
- lastPage=True
- startIndex=maxIndex-itemsPerPage
- if startIndex<0:
- startIndex=0
- ctr=0
- resultJson={}
- for published,item in sharesJson.items():
- if ctr>=startIndex+itemsPerPage:
+ sharesJson = OrderedDict(sorted(allSharesJson.items(), reverse=True))
+ lastPage = False
+ startIndex = itemsPerPage*pageNumber
+ maxIndex = len(sharesJson.items())
+ if maxIndex < itemsPerPage:
+ lastPage = True
+ if startIndex >= maxIndex - itemsPerPage:
+ lastPage = True
+ startIndex = maxIndex - itemsPerPage
+ if startIndex < 0:
+ startIndex = 0
+ ctr = 0
+ resultJson = {}
+ for published, item in sharesJson.items():
+ if ctr >= startIndex + itemsPerPage:
break
- if ctr str:
+
+def htmlSharesTimeline(translate: {}, pageNumber: int, itemsPerPage: int,
+ baseDir: str, actor: str,
+ nickname: str, domain: str, port: int,
+ maxSharesPerAccount: int, httpPrefix: str) -> str:
"""Show shared items timeline as html
"""
- sharesJson,lastPage= \
- sharesTimelineJson(actor,pageNumber,itemsPerPage, \
- baseDir,maxSharesPerAccount)
- domainFull=domain
- if port!=80 and port!=443:
+ sharesJson, lastPage = \
+ sharesTimelineJson(actor, pageNumber, itemsPerPage,
+ baseDir, maxSharesPerAccount)
+ domainFull = domain
+ if port != 80 and port != 443:
if ':' not in domain:
- domainFull=domain+':'+str(port)
- actor=httpPrefix+'://'+domainFull+'/users/'+nickname
- timelineStr=''
+ domainFull = domain + ':' + str(port)
+ actor = httpPrefix + '://' + domainFull + '/users/' + nickname
+ timelineStr = ''
- if pageNumber>1:
- timelineStr+= \
- ' '
+ if pageNumber > 1:
+ iconsDir = getIconsDir(baseDir)
+ timelineStr += \
+ ' '
- for published,item in sharesJson.items():
- showContactButton=False
- if item['actor']!=actor:
- showContactButton=True
- showRemoveButton=False
- if item['actor']==actor:
- showRemoveButton=True
- timelineStr+= \
- htmlIndividualShare(actor,item,translate, \
- showContactButton,showRemoveButton)
+ for published, item in sharesJson.items():
+ showContactButton = False
+ if item['actor'] != actor:
+ showContactButton = True
+ showRemoveButton = False
+ if item['actor'] == actor:
+ showRemoveButton = True
+ timelineStr += \
+ htmlIndividualShare(actor, item, translate,
+ showContactButton, showRemoveButton)
if not lastPage:
- timelineStr+= \
- ' '
+ iconsDir = getIconsDir(baseDir)
+ timelineStr += \
+ ' '
return timelineStr
-def htmlProfile(defaultTimeline: str, \
- recentPostsCache: {},maxRecentPosts: int, \
- translate: {},projectVersion: str, \
- baseDir: str,httpPrefix: str,authorized: bool, \
- ocapAlways: bool,profileJson: {},selected: str, \
- session,wfRequest: {},personCache: {}, \
- extraJson=None, \
- pageNumber=None,maxItemsPerPage=None) -> str:
+
+def htmlProfile(defaultTimeline: str,
+ recentPostsCache: {}, maxRecentPosts: int,
+ translate: {}, projectVersion: str,
+ baseDir: str, httpPrefix: str, authorized: bool,
+ ocapAlways: bool, profileJson: {}, selected: str,
+ session, wfRequest: {}, personCache: {},
+ extraJson=None,
+ pageNumber=None, maxItemsPerPage=None) -> str:
"""Show the profile page as html
"""
- nickname=profileJson['preferredUsername']
+ nickname = profileJson['preferredUsername']
if not nickname:
return ""
- domain,port=getDomainFromActor(profileJson['id'])
+ domain, port = getDomainFromActor(profileJson['id'])
if not domain:
return ""
- displayName= \
- addEmojiToDisplayName(baseDir,httpPrefix, \
- nickname,domain, \
- profileJson['name'],True)
- domainFull=domain
+ displayName = \
+ addEmojiToDisplayName(baseDir, httpPrefix,
+ nickname, domain,
+ profileJson['name'], True)
+ domainFull = domain
if port:
- domainFull=domain+':'+str(port)
- profileDescription= \
- addEmojiToDisplayName(baseDir,httpPrefix, \
- nickname,domain, \
- profileJson['summary'],False)
- postsButton='button'
- followingButton='button'
- followersButton='button'
- rolesButton='button'
- skillsButton='button'
- sharesButton='button'
- if selected=='posts':
- postsButton='buttonselected'
- elif selected=='following':
- followingButton='buttonselected'
- elif selected=='followers':
- followersButton='buttonselected'
- elif selected=='roles':
- rolesButton='buttonselected'
- elif selected=='skills':
- skillsButton='buttonselected'
- elif selected=='shares':
- sharesButton='buttonselected'
- loginButton=''
+ domainFull = domain + ':' + str(port)
+ profileDescription = \
+ addEmojiToDisplayName(baseDir, httpPrefix,
+ nickname, domain,
+ profileJson['summary'], False)
+ postsButton = 'button'
+ followingButton = 'button'
+ followersButton = 'button'
+ rolesButton = 'button'
+ skillsButton = 'button'
+ sharesButton = 'button'
+ if selected == 'posts':
+ postsButton = 'buttonselected'
+ elif selected == 'following':
+ followingButton = 'buttonselected'
+ elif selected == 'followers':
+ followersButton = 'buttonselected'
+ elif selected == 'roles':
+ rolesButton = 'buttonselected'
+ elif selected == 'skills':
+ skillsButton = 'buttonselected'
+ elif selected == 'shares':
+ sharesButton = 'buttonselected'
+ loginButton = ''
- followApprovalsSection=''
- followApprovals=False
- linkToTimelineStart=''
- linkToTimelineEnd=''
- editProfileStr=''
- logoutStr=''
- actor=profileJson['id']
- usersPath='/users/'+actor.split('/users/')[1]
+ followApprovalsSection = ''
+ followApprovals = False
+ linkToTimelineStart = ''
+ linkToTimelineEnd = ''
+ editProfileStr = ''
+ logoutStr = ''
+ actor = profileJson['id']
+ usersPath = '/users/' + actor.split('/users/')[1]
- donateSection=''
- donateUrl=getDonationUrl(profileJson)
- PGPpubKey=getPGPpubKey(profileJson)
- emailAddress=getEmailAddress(profileJson)
- xmppAddress=getXmppAddress(profileJson)
- matrixAddress=getMatrixAddress(profileJson)
- ssbAddress=getSSBAddress(profileJson)
- toxAddress=getToxAddress(profileJson)
+ donateSection = ''
+ donateUrl = getDonationUrl(profileJson)
+ PGPpubKey = getPGPpubKey(profileJson)
+ emailAddress = getEmailAddress(profileJson)
+ xmppAddress = getXmppAddress(profileJson)
+ matrixAddress = getMatrixAddress(profileJson)
+ ssbAddress = getSSBAddress(profileJson)
+ toxAddress = getToxAddress(profileJson)
if donateUrl or xmppAddress or matrixAddress or \
ssbAddress or toxAddress or PGPpubKey or emailAddress:
- donateSection='\n'
- donateSection+='
\n'
+ donateSection = '\n'
+ donateSection += \
+ '' + PGPpubKey.replace('\n', ' ') + '
\n'
+ donateSection += ' \n'
+ donateSection += '
\n'
if not authorized:
- loginButton= \
- ''+ \
- translate['Login']+' '
+ loginButton = \
+ '' + \
+ translate['Login'] + ' '
else:
- editProfileStr= \
- ''+ \
- translate['Edit']+' '
- logoutStr= \
- ''+ \
- translate['Logout']+' '
- linkToTimelineStart= \
- ''+ \
- translate['Switch to timeline view']+' '
- linkToTimelineStart+= \
- ''
- linkToTimelineEnd=' '
+ editProfileStr = \
+ '' + \
+ translate['Edit'] + ' '
+ logoutStr = \
+ '' + \
+ translate['Logout'] + ' '
+ linkToTimelineStart = \
+ '' + \
+ translate['Switch to timeline view'] + ' '
+ linkToTimelineStart += \
+ ''
+ linkToTimelineEnd = ' '
# are there any follow requests?
- followRequestsFilename= \
- baseDir+'/accounts/'+nickname+'@'+domain+'/followrequests.txt'
+ followRequestsFilename = \
+ baseDir + '/accounts/' + \
+ nickname + '@' + domain + '/followrequests.txt'
if os.path.isfile(followRequestsFilename):
- with open(followRequestsFilename,'r') as f:
+ with open(followRequestsFilename, 'r') as f:
for line in f:
- if len(line)>0:
- followApprovals=True
- followersButton='buttonhighlighted'
- if selected=='followers':
- followersButton='buttonselectedhighlighted'
+ if len(line) > 0:
+ followApprovals = True
+ followersButton = 'buttonhighlighted'
+ if selected == 'followers':
+ followersButton = 'buttonselectedhighlighted'
break
- if selected=='followers':
+ if selected == 'followers':
if followApprovals:
- with open(followRequestsFilename,'r') as f:
+ with open(followRequestsFilename, 'r') as f:
for followerHandle in f:
- if len(line)>0:
+ if len(line) > 0:
if '://' in followerHandle:
- followerActor=followerHandle
+ followerActor = followerHandle
else:
- followerActor= \
- httpPrefix+'://'+followerHandle.split('@')[1]+ \
- '/users/'+followerHandle.split('@')[0]
- basePath=httpPrefix+'://'+domainFull+'/users/'+nickname
- followApprovalsSection+=''
+ followerActor = \
+ httpPrefix + '://' + \
+ followerHandle.split('@')[1] + \
+ '/users/' + followerHandle.split('@')[0]
+ basePath = httpPrefix + '://' + domainFull + \
+ '/users/' + nickname
+ followApprovalsSection += ''
- profileDescriptionShort=profileDescription
+ profileDescriptionShort = profileDescription
if '\n' in profileDescription:
- if len(profileDescription.split('\n'))>2:
- profileDescriptionShort=''
+ if len(profileDescription.split('\n')) > 2:
+ profileDescriptionShort = ''
else:
if ' ' in profileDescription:
- if len(profileDescription.split(' '))>2:
- profileDescriptionShort=''
- profileDescription=profileDescription.replace(' ','\n')
+ if len(profileDescription.split(' ')) > 2:
+ profileDescriptionShort = ''
+ profileDescription = profileDescription.replace(' ', '\n')
# keep the profile description short
- if len(profileDescriptionShort)>256:
- profileDescriptionShort=''
+ if len(profileDescriptionShort) > 256:
+ profileDescriptionShort = ''
# remove formatting from profile description used on title
- avatarDescription=''
+ avatarDescription = ''
if profileJson.get('summary'):
- avatarDescription= \
- profileJson['summary'].replace(' ','\n').replace('','').replace('
','')
- profileHeaderStr=''
- profileHeaderStr+='
'
- profileHeaderStr+= \
- '
'
- profileHeaderStr+='
'+displayName+' '
- profileHeaderStr+='
@'+nickname+'@'+domainFull+'
'
- profileHeaderStr+='
'+profileDescriptionShort+'
'
- profileHeaderStr+=loginButton
- profileHeaderStr+='
'
- profileHeaderStr+='
'
+ avatarDescription = profileJson['summary'].replace(' ', '\n')
+ avatarDescription = avatarDescription.replace('', '')
+ avatarDescription = avatarDescription.replace('
', '')
+ profileHeaderStr = ''
+ profileHeaderStr += '
'
+ profileHeaderStr += \
+ '
'
+ profileHeaderStr += '
' + displayName + ' '
+ profileHeaderStr += \
+ '
@' + nickname + '@' + domainFull + '
'
+ profileHeaderStr += '
' + profileDescriptionShort + '
'
+ profileHeaderStr += loginButton
+ profileHeaderStr += '
'
+ profileHeaderStr += '
'
- profileStr= \
+ profileStr = \
linkToTimelineStart + profileHeaderStr + \
linkToTimelineEnd + donateSection
- profileStr+=''
- profileStr+=followApprovalsSection
+ profileStr += followApprovalsSection
- cssFilename=baseDir+'/epicyon-profile.css'
- if os.path.isfile(baseDir+'/epicyon.css'):
- cssFilename=baseDir+'/epicyon.css'
+ cssFilename = baseDir + '/epicyon-profile.css'
+ if os.path.isfile(baseDir + '/epicyon.css'):
+ cssFilename = baseDir + '/epicyon.css'
with open(cssFilename, 'r') as cssFile:
- profileStyle= \
- cssFile.read().replace('image.png', \
+ profileStyle = \
+ cssFile.read().replace('image.png',
profileJson['image']['url'])
- licenseStr= \
- ' '
+ licenseStr = \
+ '' + \
+ ' '
- if selected=='posts':
- profileStr+= \
- htmlProfilePosts(recentPostsCache,maxRecentPosts, \
- translate, \
- baseDir,httpPrefix,authorized, \
- ocapAlways,nickname,domain,port, \
- session,wfRequest,personCache, \
- projectVersion)+licenseStr
- if selected=='following':
- profileStr+= \
- htmlProfileFollowing(translate,baseDir,httpPrefix, \
- authorized,ocapAlways,nickname, \
- domain,port,session, \
- wfRequest,personCache,extraJson, \
- projectVersion, \
- ["unfollow"], \
- selected,actor, \
- pageNumber,maxItemsPerPage)
- if selected=='followers':
- profileStr+= \
- htmlProfileFollowing(translate,baseDir,httpPrefix, \
- authorized,ocapAlways,nickname, \
- domain,port,session, \
- wfRequest,personCache,extraJson, \
- projectVersion, \
- ["block"], \
- selected,actor, \
- pageNumber,maxItemsPerPage)
- if selected=='roles':
- profileStr+= \
- htmlProfileRoles(translate,nickname,domainFull,extraJson)
- if selected=='skills':
- profileStr+= \
- htmlProfileSkills(translate,nickname,domainFull,extraJson)
- if selected=='shares':
- profileStr+= \
- htmlProfileShares(actor,translate, \
- nickname,domainFull, \
- extraJson)+licenseStr
- profileStr= \
- htmlHeader(cssFilename,profileStyle)+profileStr+htmlFooter()
+ if selected == 'posts':
+ profileStr += \
+ htmlProfilePosts(recentPostsCache, maxRecentPosts,
+ translate,
+ baseDir, httpPrefix, authorized,
+ ocapAlways, nickname, domain, port,
+ session, wfRequest, personCache,
+ projectVersion) + licenseStr
+ if selected == 'following':
+ profileStr += \
+ htmlProfileFollowing(translate, baseDir, httpPrefix,
+ authorized, ocapAlways, nickname,
+ domain, port, session,
+ wfRequest, personCache, extraJson,
+ projectVersion, ["unfollow"], selected,
+ actor, pageNumber, maxItemsPerPage)
+ if selected == 'followers':
+ profileStr += \
+ htmlProfileFollowing(translate, baseDir, httpPrefix,
+ authorized, ocapAlways, nickname,
+ domain, port, session,
+ wfRequest, personCache, extraJson,
+ projectVersion, ["block"],
+ selected, actor, pageNumber,
+ maxItemsPerPage)
+ if selected == 'roles':
+ profileStr += \
+ htmlProfileRoles(translate, nickname, domainFull, extraJson)
+ if selected == 'skills':
+ profileStr += \
+ htmlProfileSkills(translate, nickname, domainFull, extraJson)
+ if selected == 'shares':
+ profileStr += \
+ htmlProfileShares(actor, translate,
+ nickname, domainFull,
+ extraJson) + licenseStr
+ profileStr = \
+ htmlHeader(cssFilename, profileStyle) + profileStr + htmlFooter()
return profileStr
-def individualFollowAsHtml(translate: {}, \
- baseDir: str,session,wfRequest: {}, \
- personCache: {},domain: str, \
- followUrl: str, \
- authorized: bool, \
- actorNickname: str, \
- httpPrefix: str, \
- projectVersion: str, \
- buttons=[]) -> str:
- nickname=getNicknameFromActor(followUrl)
- domain,port=getDomainFromActor(followUrl)
- titleStr='@'+nickname+'@'+domain
- avatarUrl=getPersonAvatarUrl(baseDir,followUrl,personCache)
- if not avatarUrl:
- avatarUrl=followUrl+'/avatar.png'
- if domain not in followUrl:
- inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl2,displayName= \
- getPersonBox(baseDir,session,wfRequest,personCache, \
- projectVersion,httpPrefix,nickname,domain,'outbox')
- if avatarUrl2:
- avatarUrl=avatarUrl2
- if displayName:
- titleStr=displayName+' '+titleStr
- buttonsStr=''
+def individualFollowAsHtml(translate: {},
+ baseDir: str, session, wfRequest: {},
+ personCache: {}, domain: str,
+ followUrl: str,
+ authorized: bool,
+ actorNickname: str,
+ httpPrefix: str,
+ projectVersion: str,
+ buttons=[]) -> str:
+ nickname = getNicknameFromActor(followUrl)
+ domain, port = getDomainFromActor(followUrl)
+ titleStr = '@' + nickname + '@' + domain
+ avatarUrl = getPersonAvatarUrl(baseDir, followUrl, personCache)
+ if not avatarUrl:
+ avatarUrl = followUrl + '/avatar.png'
+ if domain not in followUrl:
+ (inboxUrl, pubKeyId, pubKey,
+ fromPersonId, sharedInbox,
+ capabilityAcquisition,
+ avatarUrl2, displayName) = getPersonBox(baseDir, session, wfRequest,
+ personCache, projectVersion,
+ httpPrefix, nickname,
+ domain, 'outbox')
+ if avatarUrl2:
+ avatarUrl = avatarUrl2
+ if displayName:
+ titleStr = displayName + ' ' + titleStr
+
+ buttonsStr = ''
if authorized:
for b in buttons:
- if b=='block':
- buttonsStr+= \
- ''+ \
- translate['Block']+' '
- #buttonsStr+=''+translate['Block']+' '
- if b=='unfollow':
- buttonsStr+= \
- ''+ \
- translate['Unfollow']+' '
- #buttonsStr+=''+translate['Unfollow']+' '
+ if b == 'block':
+ buttonsStr += \
+ '' + \
+ translate['Block'] + ' '
+ if b == 'unfollow':
+ buttonsStr += \
+ '' + \
+ translate['Unfollow'] + ' '
- resultStr='\n'
+ resultStr = '\n'
return resultStr
+
def clickToDropDownScript() -> str:
"""Function run onclick to create a dropdown
"""
- script='function dropdown() {\n'
- script+=' document.getElementById("myDropdown").classList.toggle("show");\n'
- script+='}\n'
+ script = 'function dropdown() {\n'
+ script += ' document.getElementById("myDropdown")' + \
+ '.classList.toggle("show");\n'
+ script += '}\n'
return script
+
def cursorToEndOfMessageScript() -> str:
"""Moves the cursor to the end of the text in a textarea
This avoids the cursor being in the wrong position when replying
"""
- script='function focusOnMessage() {\n'
- script+=" var replyTextArea=document.getElementById('message');\n"
- script+=' val=replyTextArea.value;\n'
- script+=' if ((val.length>0) && (val.charAt(val.length-1) != " ")) {\n'
- script+=' val += " ";\n'
- script+=' }\n'
- script+=' replyTextArea.focus();\n'
- script+=' replyTextArea.value="";\n'
- script+=' replyTextArea.value=val;\n'
- script+='}\n'
- script+="var replyTextArea=document.getElementById('message')\n"
- script+='replyTextArea.onFocus=function() {\n'
- script+=' focusOnMessage();'
- script+='}\n'
+ script = 'function focusOnMessage() {\n'
+ script += " var replyTextArea=document.getElementById('message');\n"
+ script += ' val=replyTextArea.value;\n'
+ script += ' if ((val.length>0) && (val.charAt(val.length-1) != " ")) {\n'
+ script += ' val += " ";\n'
+ script += ' }\n'
+ script += ' replyTextArea.focus();\n'
+ script += ' replyTextArea.value="";\n'
+ script += ' replyTextArea.value=val;\n'
+ script += '}\n'
+ script += "var replyTextArea=document.getElementById('message')\n"
+ script += 'replyTextArea.onFocus=function() {\n'
+ script += ' focusOnMessage();'
+ script += '}\n'
return script
+
def contentWarningScript() -> str:
"""Returns a script used for content warnings
"""
- script='function showContentWarning(postID) {\n'
- script+=' var x=document.getElementById(postID);\n'
- script+=' if (x.style.display !== "block") {\n'
- script+=' x.style.display="block";\n'
- script+=' } else {\n'
- script+=' x.style.display="none";\n'
- script+=' }\n'
- script+='}\n'
+ script = 'function showContentWarning(postID) {\n'
+ script += ' var x=document.getElementById(postID);\n'
+ script += ' if (x.style.display !== "block") {\n'
+ script += ' x.style.display="block";\n'
+ script += ' } else {\n'
+ script += ' x.style.display="none";\n'
+ script += ' }\n'
+ script += '}\n'
return script
+
def contentWarningScriptOpen() -> str:
"""Returns a script used for content warnings
The warning is open by default. This is used on blog replies.
"""
- script='function showContentWarning(postID) {\n'
- script+=' var x=document.getElementById(postID);\n'
- script+=' x.style.display="block";\n'
- script+='}\n'
+ script = 'function showContentWarning(postID) {\n'
+ script += ' var x=document.getElementById(postID);\n'
+ script += ' x.style.display="block";\n'
+ script += '}\n'
return script
-def addEmbeddedAudio(translate: {},content: str) -> str:
+
+def addEmbeddedAudio(translate: {}, content: str) -> str:
"""Adds embedded audio for mp3/ogg
"""
if not ('.mp3' in content or '.ogg' in content):
@@ -2199,37 +2524,42 @@ def addEmbeddedAudio(translate: {},content: str) -> str:
if '','')
+ w = w.replace('href="', '').replace('">', '')
if w.endswith('.'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith('"'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith(';'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith(':'):
- w=w[:-1]
+ w = w[:-1]
if not w.endswith(extension):
continue
- if not (w.startswith('http') or w.startswith('dat:') or \
+ if not (w.startswith('http') or w.startswith('dat:') or
w.startswith('i2p:') or '/' in w):
continue
- url=w
- content+=''
- content+=''
- content+=translate['Your browser does not support the audio element.']
- content+=' '
+ url = w
+ content += ''
+ content += \
+ ''
+ content += \
+ translate['Your browser does not support the audio element.']
+ content += ' '
return content
-def addEmbeddedVideo(translate: {},content: str,width=400,height=300) -> str:
+
+def addEmbeddedVideo(translate: {}, content: str,
+ width=400, height=300) -> str:
"""Adds embedded video for mp4/webm/ogv
"""
if not ('.mp4' in content or '.webm' in content or '.ogv' in content):
@@ -2238,338 +2568,377 @@ def addEmbeddedVideo(translate: {},content: str,width=400,height=300) -> str:
if '','')
+ w = w.replace('href="', '').replace('">', '')
if w.endswith('.'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith('"'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith(';'):
- w=w[:-1]
+ w = w[:-1]
if w.endswith(':'):
- w=w[:-1]
+ w = w[:-1]
if not w.endswith(extension):
continue
- if not (w.startswith('http') or w.startswith('dat:') or \
+ if not (w.startswith('http') or w.startswith('dat:') or
w.startswith('i2p:') or '/' in w):
continue
- url=w
- content+= \
- ''
- content+= \
- ''
- content+=translate['Your browser does not support the video element.']
- content+=' '
+ url = w
+ content += \
+ ''
+ content += \
+ ''
+ content += \
+ translate['Your browser does not support the video element.']
+ content += ' '
return content
-def addEmbeddedVideoFromSites(translate: {},content: str,width=400,height=300) -> str:
+
+def addEmbeddedVideoFromSites(translate: {}, content: str,
+ width=400, height=300) -> str:
"""Adds embedded videos
"""
if '>vimeo.com/' in content:
- url=content.split('>vimeo.com/')[1]
+ url = content.split('>vimeo.com/')[1]
if '<' in url:
- url=url.split('<')[0]
- content= \
- content+" "
+ url = url.split('<')[0]
+ content = \
+ content + " "
return content
- videoSite='https://www.youtube.com'
- if '"'+videoSite in content:
- url=content.split('"'+videoSite)[1]
+ videoSite = 'https://www.youtube.com'
+ if '"' + videoSite in content:
+ url = content.split('"' + videoSite)[1]
if '"' in url:
- url=url.split('"')[0].replace('/watch?v=','/embed/')
+ url = url.split('"')[0].replace('/watch?v=', '/embed/')
if '&' in url:
- url=url.split('&')[0]
- content= \
- content+" "
+ url = url.split('&')[0]
+ content = \
+ content + " "
return content
- invidiousSites=('https://invidio.us', \
- 'axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4bzzsg2ii4fv2iid.onion')
+ invidiousSites = ('https://invidio.us',
+ 'axqzx4s6s54s32yentfqojs3x5i7faxza6xo3ehd4' +
+ 'bzzsg2ii4fv2iid.onion')
for videoSite in invidiousSites:
- if '"'+videoSite in content:
- url=content.split('"'+videoSite)[1]
+ if '"' + videoSite in content:
+ url = content.split('"' + videoSite)[1]
if '"' in url:
- url=url.split('"')[0].replace('/watch?v=','/embed/')
+ url = url.split('"')[0].replace('/watch?v=', '/embed/')
if '&' in url:
- url=url.split('&')[0]
- content= \
- content+" "
+ url = url.split('&')[0]
+ content = \
+ content + " "
return content
- videoSite='https://media.ccc.de'
- if '"'+videoSite in content:
- url=content.split('"'+videoSite)[1]
+ videoSite = 'https://media.ccc.de'
+ if '"' + videoSite in content:
+ url = content.split('"' + videoSite)[1]
if '"' in url:
- url=url.split('"')[0]
+ url = url.split('"')[0]
if not url.endswith('/oembed'):
- url=url+'/oembed'
- content= \
- content+" "
+ url = url + '/oembed'
+ content = \
+ content + " "
return content
if '"https://' in content:
- # A selection of the current larger peertube sites, mostly French and German language
- # These have been chosen based on reported numbers of users and the content of each has not been reviewed, so mileage could vary
- peerTubeSites=('peertube.mastodon.host','open.tube','share.tube', \
- 'tube.tr4sk.me','videos.elbinario.net','hkvideo.live', \
- 'peertube.snargol.com','tube.22decembre.eu', \
- 'tube.fabrigli.fr','libretube.net','libre.video', \
- 'peertube.linuxrocks.online','spacepub.space', \
- 'video.ploud.jp','video.omniatv.com','peertube.servebeer.com', \
- 'tube.tchncs.de','tubee.fr','video.alternanet.fr', \
- 'devtube.dev-wiki.de','video.samedi.pm', \
- 'video.irem.univ-paris-diderot.fr', \
- 'peertube.openstreetmap.fr','video.antopie.org', \
- 'scitech.video','tube.4aem.com','video.ploud.fr', \
- 'peervideo.net','video.valme.io','videos.pair2jeux.tube', \
- 'vault.mle.party','hostyour.tv','diode.zone','visionon.tv', \
- 'artitube.artifaille.fr','peertube.fr','peertube.live', \
- 'tube.ac-lyon.fr','www.yiny.org','betamax.video', \
- 'tube.piweb.be','pe.ertu.be','peertube.social', \
- 'videos.lescommuns.org','peertube.nogafa.org', \
- 'skeptikon.fr','video.tedomum.net','tube.p2p.legal', \
- 'sikke.fi','exode.me','peertube.video')
+ # A selection of the current larger peertube sites, mostly
+ # French and German language
+ # These have been chosen based on reported numbers of users
+ # and the content of each has not been reviewed, so mileage could vary
+ peerTubeSites = ('peertube.mastodon.host', 'open.tube', 'share.tube',
+ 'tube.tr4sk.me', 'videos.elbinario.net',
+ 'hkvideo.live',
+ 'peertube.snargol.com', 'tube.22decembre.eu',
+ 'tube.fabrigli.fr', 'libretube.net', 'libre.video',
+ 'peertube.linuxrocks.online', 'spacepub.space',
+ 'video.ploud.jp', 'video.omniatv.com',
+ 'peertube.servebeer.com',
+ 'tube.tchncs.de', 'tubee.fr', 'video.alternanet.fr',
+ 'devtube.dev-wiki.de', 'video.samedi.pm',
+ 'video.irem.univ-paris-diderot.fr',
+ 'peertube.openstreetmap.fr', 'video.antopie.org',
+ 'scitech.video', 'tube.4aem.com', 'video.ploud.fr',
+ 'peervideo.net', 'video.valme.io',
+ 'videos.pair2jeux.tube',
+ 'vault.mle.party', 'hostyour.tv',
+ 'diode.zone', 'visionon.tv',
+ 'artitube.artifaille.fr', 'peertube.fr',
+ 'peertube.live',
+ 'tube.ac-lyon.fr', 'www.yiny.org', 'betamax.video',
+ 'tube.piweb.be', 'pe.ertu.be', 'peertube.social',
+ 'videos.lescommuns.org', 'peertube.nogafa.org',
+ 'skeptikon.fr', 'video.tedomum.net',
+ 'tube.p2p.legal',
+ 'sikke.fi', 'exode.me', 'peertube.video')
for site in peerTubeSites:
- if '"https://'+site in content:
- url=content.split('"https://'+site)[1]
+ if '"https://' + site in content:
+ url = content.split('"https://' + site)[1]
if '"' in url:
- url=url.split('"')[0].replace('/watch/','/embed/')
- content= \
- content+" "
+ url = url.split('"')[0].replace('/watch/', '/embed/')
+ content = \
+ content + " "
return content
return content
-def addEmbeddedElements(translate: {},content: str) -> str:
+
+def addEmbeddedElements(translate: {}, content: str) -> str:
"""Adds embedded elements for various media types
"""
- content=addEmbeddedVideoFromSites(translate,content)
- content=addEmbeddedAudio(translate,content)
- return addEmbeddedVideo(translate,content)
+ content = addEmbeddedVideoFromSites(translate, content)
+ content = addEmbeddedAudio(translate, content)
+ return addEmbeddedVideo(translate, content)
-def followerApprovalActive(baseDir: str,nickname: str,domain: str) -> bool:
+
+def followerApprovalActive(baseDir: str, nickname: str, domain: str) -> bool:
"""Returns true if the given account requires follower approval
"""
- manuallyApprovesFollowers=False
- actorFilename=baseDir+'/accounts/'+nickname+'@'+domain+'.json'
+ manuallyApprovesFollowers = False
+ actorFilename = baseDir + '/accounts/' + nickname + '@' + domain + '.json'
if os.path.isfile(actorFilename):
- actorJson=loadJson(actorFilename)
+ actorJson = loadJson(actorFilename)
if actorJson:
if actorJson.get('manuallyApprovesFollowers'):
- manuallyApprovesFollowers=actorJson['manuallyApprovesFollowers']
+ manuallyApprovesFollowers = \
+ actorJson['manuallyApprovesFollowers']
return manuallyApprovesFollowers
-def insertQuestion(baseDir: str,translate: {}, \
- nickname: str,domain: str,port: int, \
- content: str, \
- postJsonObject: {},pageNumber: int) -> str:
+
+def insertQuestion(baseDir: str, translate: {},
+ nickname: str, domain: str, port: int,
+ content: str,
+ postJsonObject: {}, pageNumber: int) -> str:
""" Inserts question selection into a post
"""
if not isQuestion(postJsonObject):
return content
- if len(postJsonObject['object']['oneOf'])==0:
+ if len(postJsonObject['object']['oneOf']) == 0:
return content
- messageId=postJsonObject['id'].replace('/activity','')
+ messageId = postJsonObject['id'].replace('/activity', '')
if '#' in messageId:
- messageId=messageId.split('#',1)[0]
- pageNumberStr=''
+ messageId = messageId.split('#', 1)[0]
+ pageNumberStr = ''
if pageNumber:
- pageNumberStr='?page='+str(pageNumber)
+ pageNumberStr = '?page=' + str(pageNumber)
- votesFilename= \
- baseDir+'/accounts/'+nickname+'@'+domain+'/questions.txt'
+ votesFilename = \
+ baseDir + '/accounts/' + nickname + '@' + domain + '/questions.txt'
- showQuestionResults=False
+ showQuestionResults = False
if os.path.isfile(votesFilename):
if messageId in open(votesFilename).read():
- showQuestionResults=True
+ showQuestionResults = True
if not showQuestionResults:
# show the question options
- content+=''
else:
# show the responses to a question
- content+=''
return content
-def addEmojiToDisplayName(baseDir: str,httpPrefix: str, \
- nickname: str,domain: str, \
- displayName: str,inProfileName: bool) -> str:
+
+def addEmojiToDisplayName(baseDir: str, httpPrefix: str,
+ nickname: str, domain: str,
+ displayName: str, inProfileName: bool) -> str:
"""Adds emoji icons to display names on individual posts
"""
if ':' not in displayName:
return displayName
- displayName=displayName.replace('','').replace('
','')
- emojiTags={}
- print('TAG: displayName before tags: '+displayName)
- displayName= \
- addHtmlTags(baseDir,httpPrefix, \
- nickname,domain,displayName,[],emojiTags)
- displayName=displayName.replace('','').replace('
','')
- print('TAG: displayName after tags: '+displayName)
+ displayName = displayName.replace('', '').replace('
', '')
+ emojiTags = {}
+ print('TAG: displayName before tags: ' + displayName)
+ displayName = \
+ addHtmlTags(baseDir, httpPrefix,
+ nickname, domain, displayName, [], emojiTags)
+ displayName = displayName.replace('', '').replace('
', '')
+ print('TAG: displayName after tags: ' + displayName)
# convert the emoji dictionary to a list
- emojiTagsList=[]
- for tagName,tag in emojiTags.items():
+ emojiTagsList = []
+ for tagName, tag in emojiTags.items():
emojiTagsList.append(tag)
- print('TAG: emoji tags list: '+str(emojiTagsList))
+ print('TAG: emoji tags list: ' + str(emojiTagsList))
if not inProfileName:
- displayName=replaceEmojiFromTags(displayName,emojiTagsList,'post header')
+ displayName = \
+ replaceEmojiFromTags(displayName, emojiTagsList, 'post header')
else:
- displayName=replaceEmojiFromTags(displayName,emojiTagsList,'profile')
- print('TAG: displayName after tags 2: '+displayName)
+ displayName = \
+ replaceEmojiFromTags(displayName, emojiTagsList, 'profile')
+ print('TAG: displayName after tags 2: ' + displayName)
# remove any stray emoji
while ':' in displayName:
if '://' in displayName:
break
- emojiStr=displayName.split(':')[1]
- prevDisplayName=displayName
- displayName=displayName.replace(':'+emojiStr+':','').strip()
- if prevDisplayName==displayName:
+ emojiStr = displayName.split(':')[1]
+ prevDisplayName = displayName
+ displayName = displayName.replace(':' + emojiStr + ':', '').strip()
+ if prevDisplayName == displayName:
break
- print('TAG: displayName after tags 3: '+displayName)
- print('TAG: displayName after tag replacements: '+displayName)
+ print('TAG: displayName after tags 3: ' + displayName)
+ print('TAG: displayName after tag replacements: ' + displayName)
return displayName
+
def postContainsPublic(postJsonObject: {}) -> bool:
"""Does the given post contain #Public
"""
- containsPublic=False
+ containsPublic = False
if not postJsonObject['object'].get('to'):
return containsPublic
for toAddress in postJsonObject['object']['to']:
if toAddress.endswith('#Public'):
- containsPublic=True
+ containsPublic = True
break
if not containsPublic:
if postJsonObject['object'].get('cc'):
for toAddress in postJsonObject['object']['cc']:
if toAddress.endswith('#Public'):
- containsPublic=True
+ containsPublic = True
break
return containsPublic
-def loadIndividualPostAsHtmlFromCache(baseDir: str,nickname: str,domain: str, \
+
+def loadIndividualPostAsHtmlFromCache(baseDir: str,
+ nickname: str, domain: str,
postJsonObject: {}) -> str:
"""If a cached html version of the given post exists then load it and
return the html text
This is much quicker than generating the html from the json object
"""
- cachedPostFilename= \
- getCachedPostFilename(baseDir,nickname,domain,postJsonObject)
+ cachedPostFilename = \
+ getCachedPostFilename(baseDir, nickname, domain, postJsonObject)
- postHtml=''
+ postHtml = ''
if not cachedPostFilename:
return postHtml
if not os.path.isfile(cachedPostFilename):
return postHtml
- tries=0
- while tries<3:
+ tries = 0
+ while tries < 3:
try:
with open(cachedPostFilename, 'r') as file:
- postHtml=file.read()
+ postHtml = file.read()
break
except Exception as e:
print(e)
# no sleep
- tries+=1
+ tries += 1
if postHtml:
return postHtml
-def saveIndividualPostAsHtmlToCache(baseDir: str,nickname: str,domain: str, \
- postJsonObject: {},postHtml: str) -> bool:
+
+def saveIndividualPostAsHtmlToCache(baseDir: str,
+ nickname: str, domain: str,
+ postJsonObject: {},
+ postHtml: str) -> bool:
"""Saves the given html for a post to a cache file
- This is so that it can be quickly reloaded on subsequent refresh of the timeline
+ This is so that it can be quickly reloaded on subsequent
+ refresh of the timeline
"""
- htmlPostCacheDir= \
- getCachedPostDirectory(baseDir,nickname,domain)
- cachedPostFilename= \
- getCachedPostFilename(baseDir,nickname,domain,postJsonObject)
+ htmlPostCacheDir = \
+ getCachedPostDirectory(baseDir, nickname, domain)
+ cachedPostFilename = \
+ getCachedPostFilename(baseDir, nickname, domain, postJsonObject)
# create the cache directory if needed
if not os.path.isdir(htmlPostCacheDir):
@@ -2580,352 +2949,380 @@ def saveIndividualPostAsHtmlToCache(baseDir: str,nickname: str,domain: str, \
fp.write(postHtml)
return True
except Exception as e:
- print('ERROR: saving post to cache '+str(e))
+ print('ERROR: saving post to cache ' + str(e))
return False
-def preparePostFromHtmlCache(postHtml: str,boxName: str,pageNumber: int) -> str:
+
+def preparePostFromHtmlCache(postHtml: str, boxName: str,
+ pageNumber: int) -> str:
"""Sets the page number on a cached html post
"""
# if on the bookmarks timeline then remain there
- if boxName=='tlbookmarks':
- postHtml=postHtml.replace('?tl=inbox','?tl=tlbookmarks')
- return postHtml.replace(';-999;',';'+str(pageNumber)+';').replace('?page=-999','?page='+str(pageNumber))
+ if boxName == 'tlbookmarks':
+ postHtml = postHtml.replace('?tl=inbox', '?tl=tlbookmarks')
+ withPageNumber = postHtml.replace(';-999;', ';' + str(pageNumber) + ';')
+ withPageNumber = withPageNumber.replace('?page=-999',
+ '?page=' + str(pageNumber))
+ return withPageNumber
-def postIsMuted(baseDir: str,nickname: str,domain: str, \
- postJsonObject: {},messageId: str) -> bool:
+
+def postIsMuted(baseDir: str, nickname: str, domain: str,
+ postJsonObject: {}, messageId: str) -> bool:
""" Returns true if the given post is muted
"""
- isMuted=postJsonObject.get('muted')
- if isMuted==True or isMuted==False:
+ isMuted = postJsonObject.get('muted')
+ if isMuted is True or isMuted is False:
return isMuted
- postDir=baseDir+'/accounts/'+nickname+'@'+domain
- muteFilename= \
- postDir+'/inbox/'+messageId.replace('/','#')+'.json.muted'
+ postDir = baseDir + '/accounts/' + nickname + '@' + domain
+ muteFilename = \
+ postDir + '/inbox/' + messageId.replace('/', '#') + '.json.muted'
if os.path.isfile(muteFilename):
return True
- muteFilename= \
- postDir+'/outbox/'+messageId.replace('/','#')+'.json.muted'
+ muteFilename = \
+ postDir + '/outbox/' + messageId.replace('/', '#') + '.json.muted'
if os.path.isfile(muteFilename):
return True
- muteFilename= \
- baseDir+'/accounts/cache/announce/'+nickname+ \
- '/'+messageId.replace('/','#')+'.json.muted'
+ muteFilename = \
+ baseDir + '/accounts/cache/announce/' + nickname + \
+ '/' + messageId.replace('/', '#') + '.json.muted'
if os.path.isfile(muteFilename):
return True
return False
-def getPostAttachmentsAsHtml(postJsonObject: {},boxName: str,translate: {}, \
- isMuted: bool,avatarLink: str, \
- replyStr: str,announceStr: str,likeStr: str, \
- bookmarkStr: str,deleteStr: str,muteStr: str) -> (str,str):
+
+def getPostAttachmentsAsHtml(postJsonObject: {}, boxName: str, translate: {},
+ isMuted: bool, avatarLink: str,
+ replyStr: str, announceStr: str, likeStr: str,
+ bookmarkStr: str, deleteStr: str,
+ muteStr: str) -> (str, str):
"""Returns a string representing any attachments
"""
- attachmentStr=''
- galleryStr=''
+ attachmentStr = ''
+ galleryStr = ''
if not postJsonObject['object'].get('attachment'):
- return attachmentStr,galleryStr
+ return attachmentStr, galleryStr
if not isinstance(postJsonObject['object']['attachment'], list):
- return attachmentStr,galleryStr
+ return attachmentStr, galleryStr
- attachmentCtr=0
- attachmentStr+=''
+ return attachmentStr, galleryStr
-def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
- iconsDir: str,translate: {}, \
- pageNumber: int,baseDir: str, \
- session,wfRequest: {},personCache: {}, \
- nickname: str,domain: str,port: int, \
- postJsonObject: {}, \
- avatarUrl: str,showAvatarOptions: bool,
- allowDeletion: bool, \
- httpPrefix: str,projectVersion: str, \
- boxName: str,showRepeats=True, \
- showIcons=False, \
- manuallyApprovesFollowers=False, \
- showPublicOnly=False, \
+
+def individualPostAsHtml(recentPostsCache: {}, maxRecentPosts: int,
+ iconsDir: str, translate: {},
+ pageNumber: int, baseDir: str,
+ session, wfRequest: {}, personCache: {},
+ nickname: str, domain: str, port: int,
+ postJsonObject: {},
+ avatarUrl: str, showAvatarOptions: bool,
+ allowDeletion: bool,
+ httpPrefix: str, projectVersion: str,
+ boxName: str, showRepeats=True,
+ showIcons=False,
+ manuallyApprovesFollowers=False,
+ showPublicOnly=False,
storeToCache=True) -> str:
""" Shows a single post as html
"""
- postActor=postJsonObject['actor']
+ postActor = postJsonObject['actor']
# ZZZzzz
- if isPersonSnoozed(baseDir,nickname,domain,postActor):
+ if isPersonSnoozed(baseDir, nickname, domain, postActor):
return ''
- avatarPosition=''
- messageId=''
+ avatarPosition = ''
+ messageId = ''
if postJsonObject.get('id'):
- messageId=postJsonObject['id'].replace('/activity','')
+ messageId = postJsonObject['id'].replace('/activity', '')
- messageIdStr=''
+ messageIdStr = ''
if messageId:
- messageIdStr=';'+messageId
+ messageIdStr = ';' + messageId
- fullDomain=domain
+ fullDomain = domain
if port:
- if port!=80 and port!=443:
+ if port != 80 and port != 443:
if ':' not in domain:
- fullDomain=domain+':'+str(port)
+ fullDomain = domain + ':' + str(port)
- pageNumberParam=''
+ pageNumberParam = ''
if pageNumber:
- pageNumberParam='?page='+str(pageNumber)
+ pageNumberParam = '?page=' + str(pageNumber)
- if not showPublicOnly and storeToCache and boxName!='tlmedia':
+ if not showPublicOnly and storeToCache and boxName != 'tlmedia':
# update avatar if needed
if not avatarUrl:
- avatarUrl= \
- getPersonAvatarUrl(baseDir,postActor,personCache)
- updateAvatarImageCache(session,baseDir,httpPrefix, \
- postActor,avatarUrl,personCache)
+ avatarUrl = \
+ getPersonAvatarUrl(baseDir, postActor, personCache)
+ updateAvatarImageCache(session, baseDir, httpPrefix,
+ postActor, avatarUrl, personCache)
- postHtml= \
- loadIndividualPostAsHtmlFromCache(baseDir,nickname,domain, \
+ postHtml = \
+ loadIndividualPostAsHtmlFromCache(baseDir, nickname, domain,
postJsonObject)
if postHtml:
- postHtml=preparePostFromHtmlCache(postHtml,boxName,pageNumber)
- updateRecentPostsCache(recentPostsCache,maxRecentPosts, \
- postJsonObject,postHtml)
+ postHtml = preparePostFromHtmlCache(postHtml, boxName, pageNumber)
+ updateRecentPostsCache(recentPostsCache, maxRecentPosts,
+ postJsonObject, postHtml)
return postHtml
if not avatarUrl:
- avatarUrl= \
- getPersonAvatarUrl(baseDir,postActor,personCache)
- avatarUrl= \
- updateAvatarImageCache(session,baseDir,httpPrefix, \
- postActor,avatarUrl,personCache)
+ avatarUrl = \
+ getPersonAvatarUrl(baseDir, postActor, personCache)
+ avatarUrl = \
+ updateAvatarImageCache(session, baseDir, httpPrefix,
+ postActor, avatarUrl, personCache)
else:
- updateAvatarImageCache(session,baseDir,httpPrefix, \
- postActor,avatarUrl,personCache)
+ updateAvatarImageCache(session, baseDir, httpPrefix,
+ postActor, avatarUrl, personCache)
if not avatarUrl:
- avatarUrl=postActor+'/avatar.png'
+ avatarUrl = postActor + '/avatar.png'
if fullDomain not in postActor:
- inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl2,displayName= \
- getPersonBox(baseDir,session,wfRequest,personCache, \
- projectVersion,httpPrefix,nickname,domain,'outbox')
+ (inboxUrl, pubKeyId, pubKey,
+ fromPersonId, sharedInbox,
+ capabilityAcquisition,
+ avatarUrl2, displayName) = getPersonBox(baseDir, session, wfRequest,
+ personCache,
+ projectVersion, httpPrefix,
+ nickname, domain, 'outbox')
if avatarUrl2:
- avatarUrl=avatarUrl2
+ avatarUrl = avatarUrl2
if displayName:
if ':' in displayName:
- displayName= \
- addEmojiToDisplayName(baseDir,httpPrefix, \
- nickname,domain, \
- displayName,False)
- titleStr=displayName+' '+titleStr
+ displayName = \
+ addEmojiToDisplayName(baseDir, httpPrefix,
+ nickname, domain,
+ displayName, False)
- avatarLink=' '
- avatarLink+= \
- ' '
+ avatarLink = ' '
+ avatarLink += \
+ ' '
- if showAvatarOptions and fullDomain+'/users/'+nickname not in postActor:
- avatarLink= \
- ' '
- avatarLink+= \
- ' '
- avatarImageInPost=' '+avatarLink+'
'
+ if showAvatarOptions and \
+ fullDomain + '/users/' + nickname not in postActor:
+ avatarLink = \
+ ' '
+ avatarLink += \
+ ' '
+ avatarImageInPost = \
+ ' ' + avatarLink + '
'
# don't create new html within the bookmarks timeline
# it should already have been created for the inbox
- if boxName=='tlbookmarks':
+ if boxName == 'tlbookmarks':
return ''
- timelinePostBookmark= \
- postJsonObject['id'].replace('/activity','').replace('://','-').replace('/','-')
+ timelinePostBookmark = postJsonObject['id'].replace('/activity', '')
+ timelinePostBookmark = timelinePostBookmark.replace('://', '-')
+ timelinePostBookmark = timelinePostBookmark.replace('/', '-')
# If this is the inbox timeline then don't show the repeat icon on any DMs
- showRepeatIcon=showRepeats
- isPublicRepeat=False
- showDMicon=False
+ showRepeatIcon = showRepeats
+ isPublicRepeat = False
+ showDMicon = False
if showRepeats:
if isDM(postJsonObject):
- showDMicon=True
- showRepeatIcon=False
+ showDMicon = True
+ showRepeatIcon = False
else:
if not isPublicPost(postJsonObject):
- isPublicRepeat=True
+ isPublicRepeat = True
- titleStr=''
- galleryStr=''
- isAnnounced=False
- if postJsonObject['type']=='Announce':
- postJsonAnnounce= \
- downloadAnnounce(session,baseDir,httpPrefix,nickname,domain,postJsonObject,projectVersion)
+ titleStr = ''
+ galleryStr = ''
+ isAnnounced = False
+ if postJsonObject['type'] == 'Announce':
+ postJsonAnnounce = \
+ downloadAnnounce(session, baseDir, httpPrefix,
+ nickname, domain, postJsonObject,
+ projectVersion)
if not postJsonAnnounce:
return ''
- postJsonObject=postJsonAnnounce
- isAnnounced=True
+ postJsonObject = postJsonAnnounce
+ isAnnounced = True
if not isinstance(postJsonObject['object'], dict):
return ''
@@ -2935,478 +3332,558 @@ def individualPostAsHtml(recentPostsCache: {},maxRecentPosts: int, \
if not postContainsPublic(postJsonObject):
return ''
- isModerationPost=False
+ isModerationPost = False
if postJsonObject['object'].get('moderationStatus'):
- isModerationPost=True
- containerClass='container'
- containerClassIcons='containericons'
- timeClass='time-right'
- actorNickname=getNicknameFromActor(postActor)
+ isModerationPost = True
+ containerClass = 'container'
+ containerClassIcons = 'containericons'
+ timeClass = 'time-right'
+ actorNickname = getNicknameFromActor(postActor)
if not actorNickname:
# single user instance
- actorNickname='dev'
- actorDomain,actorPort=getDomainFromActor(postActor)
+ actorNickname = 'dev'
+ actorDomain, actorPort = getDomainFromActor(postActor)
- displayName=getDisplayName(baseDir,postActor,personCache)
+ displayName = getDisplayName(baseDir, postActor, personCache)
if displayName:
if ':' in displayName:
- displayName= \
- addEmojiToDisplayName(baseDir,httpPrefix, \
- nickname,domain, \
- displayName,False)
- titleStr+= \
- ''+displayName+' '
+ displayName = \
+ addEmojiToDisplayName(baseDir, httpPrefix,
+ nickname, domain,
+ displayName, False)
+ titleStr += \
+ '' + displayName + ' '
else:
if not messageId:
- #pprint(postJsonObject)
+ # pprint(postJsonObject)
print('ERROR: no messageId')
if not actorNickname:
- #pprint(postJsonObject)
+ # pprint(postJsonObject)
print('ERROR: no actorNickname')
if not actorDomain:
- #pprint(postJsonObject)
+ # pprint(postJsonObject)
print('ERROR: no actorDomain')
- titleStr+= \
- '@'+actorNickname+'@'+actorDomain+' '
+ titleStr += \
+ '@' + actorNickname + '@' + actorDomain + ' '
# Show a DM icon for DMs in the inbox timeline
if showDMicon:
- titleStr= \
- titleStr+' '
+ titleStr = \
+ titleStr + ' '
- replyStr=''
+ replyStr = ''
if showIcons:
- replyToLink=postJsonObject['object']['id']
+ replyToLink = postJsonObject['object']['id']
if postJsonObject['object'].get('attributedTo'):
- replyToLink+='?mention='+postJsonObject['object']['attributedTo']
+ replyToLink += \
+ '?mention=' + postJsonObject['object']['attributedTo']
if postJsonObject['object'].get('content'):
- mentionedActors= \
+ mentionedActors = \
getMentionsFromHtml(postJsonObject['object']['content'])
if mentionedActors:
for actorUrl in mentionedActors:
- if '?mention='+actorUrl not in replyToLink:
- replyToLink+='?mention='+actorUrl
- if len(replyToLink)>500:
+ if '?mention=' + actorUrl not in replyToLink:
+ replyToLink += '?mention=' + actorUrl
+ if len(replyToLink) > 500:
break
- replyToLink+=pageNumberParam
+ replyToLink += pageNumberParam
- replyStr=''
+ replyStr = ''
if isPublicRepeat:
- replyStr+= \
- ''
+ replyStr += \
+ ' '
else:
if isDM(postJsonObject):
- replyStr+= \
- ' '
+ replyStr += \
+ ' '
else:
- replyStr+= \
- ' '
+ replyStr += \
+ ' '
- replyStr+= \
- ' '
+ replyStr += \
+ '