__filename__ = "webapp_column_left.py"
__author__ = "Bob Mottram"
__license__ = "AGPL3+"
__version__ = "1.1.0"
__maintainer__ = "Bob Mottram"
__email__ = "bob@freedombone.net"
__status__ = "Production"
import os
from utils import getConfigParam
from utils import getNicknameFromActor
from posts import isEditor
from posts import isModerator
from webapp_utils import sharesTimelineJson
from webapp_utils import htmlPostSeparator
from webapp_utils import getLeftImageFile
from webapp_utils import headerButtonsFrontScreen
from webapp_utils import htmlHeaderWithExternalStyle, htmlHeaderWithExternalStyles
from webapp_utils import htmlFooter
from webapp_utils import getBannerFile
from webapp_headerbuttons import headerNewsTabs
def _linksExist(baseDir: str) -> bool:
"""Returns true if links have been created
"""
linksFilename = baseDir + '/accounts/links.txt'
return os.path.isfile(linksFilename)
def _getLeftColumnShares(baseDir: str,
httpPrefix: str, domainFull: str,
nickname: str,
maxSharesInLeftColumn: int,
translate: {}) -> []:
"""get any shares and turn them into the left column links format
"""
pageNumber = 1
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
sharesJson, lastPage = \
sharesTimelineJson(actor, pageNumber,
maxSharesInLeftColumn,
baseDir, maxSharesInLeftColumn)
if not sharesJson:
return []
linksList = []
ctr = 0
for published, item in sharesJson.items():
sharedesc = item['displayName']
if '<' in sharedesc or '?' in sharedesc:
continue
contactActor = item['actor']
shareLink = actor + \
'?replydm=sharedesc:' + \
sharedesc.replace(' ', '_') + \
'?mention=' + contactActor
linksList.append(sharedesc + ' ' + shareLink)
ctr += 1
if ctr >= maxSharesInLeftColumn:
break
if linksList:
linksList = ['* ' + translate['Shares']] + linksList
return linksList
def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
httpPrefix: str, translate: {},
editor: bool,
showBackButton: bool, timelinePath: str,
rssIconAtTop: bool, showHeaderImage: bool,
frontPage: bool, theme: str) -> str:
"""Returns html content for the left column
"""
htmlStr = ''
separatorStr = htmlPostSeparator(baseDir, 'left')
domain = domainFull
if ':' in domain:
domain = domain.split(':')
editImageClass = ''
# show a column header, eg. title of the theme or newswire banner
htmlStr += '
Links
\n'
if showBackButton:
htmlStr += \
'
' + \
' ' + \
'\n'
if (editor or rssIconAtTop):
htmlStr += '
'
if editImageClass == 'leftColEdit':
htmlStr += '\n
\n'
if editor:
# show the edit icon
htmlStr += \
' ' + \
'\n'
# RSS icon
if nickname != 'news':
# rss feed for this account
rssUrl = httpPrefix + '://' + domainFull + \
'/blog/' + nickname + '/rss.xml'
else:
# rss feed for all accounts on the instance
rssUrl = httpPrefix + '://' + domainFull + '/blog/rss.xml'
if not frontPage:
rssTitle = translate['RSS feed for your blog']
else:
rssTitle = translate['RSS feed for this site']
rssIconStr = \
' ' + \
'\n'
if rssIconAtTop:
htmlStr += rssIconStr
if editImageClass == 'leftColEdit':
htmlStr += '
\n'
if (editor or rssIconAtTop):
htmlStr += '
'
# if showHeaderImage:
# htmlStr += ' '
# flag used not to show the first separator
firstSeparatorAdded = False
linksFilename = baseDir + '/accounts/links.txt'
linksFileContainsEntries = False
linksList = None
if os.path.isfile(linksFilename):
with open(linksFilename, "r") as f:
linksList = f.readlines()
if not frontPage:
# show a number of shares
maxSharesInLeftColumn = 3
sharesList = \
_getLeftColumnShares(baseDir,
httpPrefix, domainFull, nickname,
maxSharesInLeftColumn, translate)
if linksList and sharesList:
linksList = sharesList + linksList
if linksList:
# Bool to enable clean
creation for sub-lists
firstList = True
for lineStr in linksList:
if ' ' not in lineStr:
if '#' not in lineStr:
if '*' not in lineStr:
continue
lineStr = lineStr.strip()
words = lineStr.split(' ')
# get the link
linkStr = None
for word in words:
if word == '#':
continue
if word == '*':
continue
if '://' in word:
linkStr = word
break
if linkStr:
lineStr = lineStr.replace(linkStr, '').strip()
# avoid any dubious scripts being added
if '<' not in lineStr:
# remove trailing comma if present
if lineStr.endswith(','):
lineStr = lineStr[:len(lineStr)-1]
# add link to the returned html
htmlStr += \
' ' + \
lineStr + '\n'
linksFileContainsEntries = True
else:
if lineStr.startswith('#') or lineStr.startswith('*'):
if not firstList:
htmlStr += \
'
\n'
if linksFileContainsEntries and not rssIconAtTop:
htmlStr += '
' + rssIconStr + '
'
return htmlStr
def htmlLinksMobile(cssCache: {}, baseDir: str,
nickname: str, domainFull: str,
httpPrefix: str, translate,
timelinePath: str, authorized: bool,
rssIconAtTop: bool,
iconsAsButtons: bool,
defaultTimeline: str,
theme: str) -> str:
"""Show the left column links within mobile view
"""
htmlStr = ''
cssFiles = []
# the css filename
cssFiles.append(baseDir + '/epicyon-profile.css')
if os.path.isfile(baseDir + '/epicyon.css'):
cssFiles[0] = baseDir + '/epicyon.css'
# TODO: Clean up and remove this override
cssFiles[0] = 'base.css'
# Get theme-specific css if exists - must be named '.css'
themeName = getConfigParam(baseDir, 'theme')
themePath = f'{baseDir}/theme/{themeName}.css'
if os.path.isfile(themePath):
cssFiles.append('theme/' + themeName + '.css')
# is the user a site editor?
if nickname == 'news':
editor = False
moderator = False
else:
# is the user a moderator?
moderator = isModerator(baseDir, nickname)
# is the user a site editor?
editor = isEditor(baseDir, nickname)
domain = domainFull
if ':' in domain:
domain = domain.split(':')[0]
htmlStr = htmlHeaderWithExternalStyles(cssFiles)
bannerFile, bannerFilename = getBannerFile(baseDir, nickname, domain)
usersPath = '/users/' + nickname
htmlStr += '
\n'
if not defaultTimeline == 'tlfeatures':
htmlStr += (f"\t"
f"{translate['Switch to profile view']}\n")
else:
# TODO: News instances should ignore personalised banners
# Currently uses the 'news' actor banner - as it remains unchanged
htmlStr += (f"\t"
f"{translate['Features']}\n"
f"\t
\n"
f"\t\t#IndymediaBack\n"
f"\t
\n")
# Certain Epciyon pages should only be accessible via the 'User' page for News instances
userPages = ['inbox', 'outbox', 'dm', 'tlreplies', 'tlblogs', 'tlmedia', 'tlshares', \
'tlsaves', 'tlevents', 'tlbookmarks', 'moderation', 'search', \
'followers', 'newfollowers']
# Full row "navbar"
if defaultTimeline == 'tlfeatures':
# Show "tab" links instead of standard "buttons"
htmlStr += headerNewsTabs('linksmobile', translate, usersPath, baseDir, authorized, userPages)
# Close banner div
htmlStr += '