mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon
commit
a0916dea8f
76
daemon.py
76
daemon.py
|
@ -230,6 +230,7 @@ from media import removeMetaData
|
|||
from cache import storePersonInCache
|
||||
from cache import getPersonFromCache
|
||||
from httpsig import verifyPostHeaders
|
||||
from theme import getTextModeBanner
|
||||
from theme import setNewsAvatar
|
||||
from theme import setTheme
|
||||
from theme import getTheme
|
||||
|
@ -2078,7 +2079,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
domainFull,
|
||||
self.server.defaultTimeline,
|
||||
self.server.newswire,
|
||||
self.server.themeName).encode('utf-8')
|
||||
self.server.themeName,
|
||||
True).encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
cookie, callingDomain)
|
||||
|
@ -2176,7 +2178,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
domainFull,
|
||||
self.server.defaultTimeline,
|
||||
self.server.newswire,
|
||||
self.server.themeName).encode('utf-8')
|
||||
self.server.themeName,
|
||||
True).encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
cookie, callingDomain)
|
||||
|
@ -4169,6 +4172,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.themeName = fields['themeDropdown']
|
||||
setTheme(baseDir, self.server.themeName, domain,
|
||||
allowLocalNetworkAccess)
|
||||
self.server.textModeBanner = \
|
||||
getTextModeBanner(self.server.baseDir)
|
||||
self.server.iconsCache = {}
|
||||
self.server.fontsCache = {}
|
||||
self.server.showPublishAsIcon = \
|
||||
|
@ -4618,6 +4623,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.themeName = currTheme
|
||||
setTheme(baseDir, currTheme, domain,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.textModeBanner = \
|
||||
getTextModeBanner(self.server.baseDir)
|
||||
self.server.iconsCache = {}
|
||||
self.server.fontsCache = {}
|
||||
self.server.showPublishAsIcon = \
|
||||
|
@ -7023,6 +7030,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
actorJson['roles'],
|
||||
None, None)
|
||||
msg = msg.encode('utf-8')
|
||||
|
@ -7110,6 +7118,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
actorJson['skills'],
|
||||
None, None)
|
||||
msg = msg.encode('utf-8')
|
||||
|
@ -7501,7 +7510,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
if GETstartTime:
|
||||
self._benchmarkGETtimings(GETstartTime, GETtimings,
|
||||
'show status done',
|
||||
|
@ -7629,7 +7639,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.publishButtonAtTop,
|
||||
authorized, self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -7750,7 +7761,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.publishButtonAtTop,
|
||||
authorized, self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -7872,7 +7884,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -7994,7 +8007,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8125,7 +8139,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8252,7 +8267,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8340,7 +8356,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.publishButtonAtTop,
|
||||
authorized, self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8445,7 +8462,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8570,7 +8588,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8687,7 +8706,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8794,7 +8814,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized, moderationActionStr,
|
||||
self.server.themeName,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -8895,6 +8916,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
shares,
|
||||
pageNumber, sharesPerPage)
|
||||
msg = msg.encode('utf-8')
|
||||
|
@ -8992,6 +9014,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
following,
|
||||
pageNumber,
|
||||
followsPerPage).encode('utf-8')
|
||||
|
@ -9089,6 +9112,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
followers,
|
||||
pageNumber,
|
||||
followsPerPage).encode('utf-8')
|
||||
|
@ -9209,6 +9233,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.dormantMonths,
|
||||
self.server.peertubeInstances,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.textModeBanner,
|
||||
None, None).encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -9711,7 +9736,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
inReplyToUrl: str, replyToList: [],
|
||||
shareDescription: str, replyPageNumber: int,
|
||||
domain: str, domainFull: str,
|
||||
GETstartTime, GETtimings: {}, cookie) -> bool:
|
||||
GETstartTime, GETtimings: {}, cookie,
|
||||
noDropDown: bool) -> bool:
|
||||
"""Shows the new post screen
|
||||
"""
|
||||
isNewPostEndpoint = False
|
||||
|
@ -9740,7 +9766,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
domainFull,
|
||||
self.server.defaultTimeline,
|
||||
self.server.newswire,
|
||||
self.server.themeName).encode('utf-8')
|
||||
self.server.themeName,
|
||||
noDropDown).encode('utf-8')
|
||||
if not msg:
|
||||
print('Error replying to ' + inReplyToUrl)
|
||||
self._404()
|
||||
|
@ -9773,7 +9800,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
httpPrefix,
|
||||
self.server.defaultTimeline,
|
||||
self.server.themeName,
|
||||
peertubeInstances).encode('utf-8')
|
||||
peertubeInstances,
|
||||
self.server.textModeBanner).encode('utf-8')
|
||||
if msg:
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen,
|
||||
|
@ -9983,6 +10011,12 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
if self.path.startswith('/@'):
|
||||
self.path = self.path.replace('/@', '/users/')
|
||||
|
||||
# turn off dropdowns on new post screen
|
||||
noDropDown = False
|
||||
if self.path.endswith('?nodropdown'):
|
||||
noDropDown = True
|
||||
self.path = self.path.replace('?nodropdown', '')
|
||||
|
||||
# redirect music to #nowplaying list
|
||||
if self.path == '/music' or self.path == '/nowplaying':
|
||||
self.path = '/tags/nowplaying'
|
||||
|
@ -11009,7 +11043,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.baseDir, self.path,
|
||||
self.server.domain,
|
||||
self.server.defaultTimeline,
|
||||
self.server.themeName).encode('utf-8')
|
||||
self.server.themeName,
|
||||
self.server.textModeBanner).encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._set_headers('text/html', msglen, cookie, callingDomain)
|
||||
self._write(msg)
|
||||
|
@ -11556,7 +11591,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.domain,
|
||||
self.server.domainFull,
|
||||
GETstartTime, GETtimings,
|
||||
cookie):
|
||||
cookie, noDropDown):
|
||||
return
|
||||
|
||||
self._benchmarkGETtimings(GETstartTime, GETtimings,
|
||||
|
@ -13850,6 +13885,9 @@ def runDaemon(verifyAllSignatures: bool,
|
|||
print('ERROR: HTTP server failed to start. ' + str(e))
|
||||
return False
|
||||
|
||||
# ASCII/ANSI text banner used in shell browsers, such as Lynx
|
||||
httpd.textModeBanner = getTextModeBanner(baseDir)
|
||||
|
||||
httpd.unitTest = unitTest
|
||||
httpd.allowLocalNetworkAccess = allowLocalNetworkAccess
|
||||
if unitTest:
|
||||
|
|
|
@ -94,6 +94,14 @@ form {
|
|||
border-radius: var(--form-border-radius);
|
||||
}
|
||||
|
||||
.transparent {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
font-size: 0px;
|
||||
line-height: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
input[type=text], input[type=password] {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
|
|
|
@ -702,6 +702,15 @@ input[type=number] {
|
|||
height: 0px;
|
||||
}
|
||||
|
||||
.transparent hr {
|
||||
border: 0;
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
font-size: 0px;
|
||||
line-height: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.labelsright {
|
||||
float: right;
|
||||
font-size: var(--font-size);
|
||||
|
@ -1145,7 +1154,7 @@ div.container {
|
|||
filter: brightness(var(--icon-brightness-change));
|
||||
}
|
||||
.col-right img.rightColEdit {
|
||||
float: right;
|
||||
float: right;
|
||||
background: transparent;
|
||||
width: var(--column-right-icon-size);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,14 @@ a:focus {
|
|||
border: 2px solid var(--focus-color);
|
||||
}
|
||||
|
||||
.transparent {
|
||||
color: transparent;
|
||||
background: transparent;
|
||||
font-size: 0px;
|
||||
line-height: 0px;
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
.cw {
|
||||
font-style: var(--cw-style);
|
||||
color: var(--cw-color);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
8888888888 8888888b. 8888888 .d8888b. Y88b d88P .d88888b. 888b 888
|
||||
888 888 Y88b 888 d88P Y88b Y88b d88P d88P" "Y88b 8888b 888
|
||||
888 888 888 888 888 888 Y88o88P 888 888 88888b 888
|
||||
8888888 888 d88P 888 888 Y888P 888 888 888Y88b 888
|
||||
888 8888888P" 888 888 888 888 888 888 Y88b888
|
||||
888 888 888 888 888 888 888 888 888 Y88888
|
||||
888 888 888 Y88b d88P 888 Y88b. .d88P 888 Y8888
|
||||
8888888888 888 8888888 "Y8888P" 888 "Y88888P" 888 Y888
|
|
@ -25,11 +25,10 @@ scripts =
|
|||
deploy/i2p
|
||||
deploy/onion
|
||||
install_requires =
|
||||
crypto >= 1.4.1, < 2
|
||||
idna >= 2.5, < 3
|
||||
numpy >= 1.20.0, < 2
|
||||
pillow >= 8.1.0, < 9
|
||||
cryptography
|
||||
cryptography >= 3.3.1, < 4
|
||||
pyqrcode >= 1.2.1, < 2
|
||||
python-dateutil >= 2.8.1, < 3
|
||||
requests >= 2.25.1, < 3
|
||||
|
|
69
theme.py
69
theme.py
|
@ -15,6 +15,8 @@ from content import dangerousCSS
|
|||
|
||||
|
||||
def _getThemeFiles() -> []:
|
||||
"""Gets the list of theme style sheets
|
||||
"""
|
||||
return ('epicyon.css', 'login.css', 'follow.css',
|
||||
'suspended.css', 'calendar.css', 'blog.css',
|
||||
'options.css', 'search.css', 'links.css')
|
||||
|
@ -39,6 +41,8 @@ def getThemesList(baseDir: str) -> []:
|
|||
|
||||
|
||||
def _setThemeInConfig(baseDir: str, name: str) -> bool:
|
||||
"""Sets the theme with the given name within config.json
|
||||
"""
|
||||
configFilename = baseDir + '/config.json'
|
||||
if not os.path.isfile(configFilename):
|
||||
return False
|
||||
|
@ -118,6 +122,8 @@ def _setFullWidthTimelineButtonHeader(baseDir: str, fullWidth: bool) -> bool:
|
|||
|
||||
|
||||
def getTheme(baseDir: str) -> str:
|
||||
"""Gets the current theme name from config.json
|
||||
"""
|
||||
configFilename = baseDir + '/config.json'
|
||||
if os.path.isfile(configFilename):
|
||||
configJson = loadJson(configFilename, 0)
|
||||
|
@ -128,6 +134,8 @@ def getTheme(baseDir: str) -> str:
|
|||
|
||||
|
||||
def _removeTheme(baseDir: str):
|
||||
"""Removes the current theme style sheets
|
||||
"""
|
||||
themeFiles = _getThemeFiles()
|
||||
for filename in themeFiles:
|
||||
if os.path.isfile(baseDir + '/' + filename):
|
||||
|
@ -422,6 +430,63 @@ def _setThemeFonts(baseDir: str, themeName: str) -> None:
|
|||
break
|
||||
|
||||
|
||||
def getTextModeBanner(baseDir: str) -> str:
|
||||
"""Returns the banner used for shell browsers, like Lynx
|
||||
"""
|
||||
textModeBannerFilename = baseDir + '/accounts/banner.txt'
|
||||
if os.path.isfile(textModeBannerFilename):
|
||||
with open(textModeBannerFilename, 'r') as fp:
|
||||
bannerStr = fp.read()
|
||||
if bannerStr:
|
||||
return bannerStr.replace('\n', '<br>')
|
||||
return None
|
||||
|
||||
|
||||
def getTextModeLogo(baseDir: str) -> str:
|
||||
"""Returns the login screen logo used for shell browsers, like Lynx
|
||||
"""
|
||||
textModeLogoFilename = baseDir + '/accounts/logo.txt'
|
||||
if not os.path.isfile(textModeLogoFilename):
|
||||
textModeLogoFilename = baseDir + '/img/logo.txt'
|
||||
|
||||
with open(textModeLogoFilename, 'r') as fp:
|
||||
logoStr = fp.read()
|
||||
if logoStr:
|
||||
return logoStr.replace('\n', '<br>')
|
||||
return None
|
||||
|
||||
|
||||
def _setTextModeTheme(baseDir: str, name: str) -> None:
|
||||
# set the text mode logo which appears on the login screen
|
||||
# in browsers such as Lynx
|
||||
textModeLogoFilename = \
|
||||
baseDir + '/theme/' + name + '/logo.txt'
|
||||
if os.path.isfile(textModeLogoFilename):
|
||||
try:
|
||||
copyfile(textModeLogoFilename,
|
||||
baseDir + '/accounts/logo.txt')
|
||||
except BaseException:
|
||||
pass
|
||||
else:
|
||||
try:
|
||||
copyfile(baseDir + '/img/logo.txt',
|
||||
baseDir + '/accounts/logo.txt')
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
# set the text mode banner which appears in browsers such as Lynx
|
||||
textModeBannerFilename = \
|
||||
baseDir + '/theme/' + name + '/banner.txt'
|
||||
if os.path.isfile(baseDir + '/accounts/banner.txt'):
|
||||
os.remove(baseDir + '/accounts/banner.txt')
|
||||
if os.path.isfile(textModeBannerFilename):
|
||||
try:
|
||||
copyfile(textModeBannerFilename,
|
||||
baseDir + '/accounts/banner.txt')
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
|
||||
def _setThemeImages(baseDir: str, name: str) -> None:
|
||||
"""Changes the profile background image
|
||||
and banner to the defaults
|
||||
|
@ -439,6 +504,8 @@ def _setThemeImages(baseDir: str, name: str) -> None:
|
|||
rightColImageFilename = \
|
||||
baseDir + '/theme/' + themeNameLower + '/right_col_image.png'
|
||||
|
||||
_setTextModeTheme(baseDir, themeNameLower)
|
||||
|
||||
backgroundNames = ('login', 'shares', 'delete', 'follow',
|
||||
'options', 'block', 'search', 'calendar')
|
||||
extensions = getImageExtensions()
|
||||
|
@ -554,6 +621,8 @@ def setNewsAvatar(baseDir: str, name: str,
|
|||
|
||||
def setTheme(baseDir: str, name: str, domain: str,
|
||||
allowLocalNetworkAccess: bool) -> bool:
|
||||
"""Sets the theme with the given name as the current theme
|
||||
"""
|
||||
result = False
|
||||
|
||||
prevThemeName = getTheme(baseDir)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
88888888888 88
|
||||
88 ""
|
||||
88
|
||||
88aaaaa 8b,dPPYba, 88 ,adPPYba, 8b d8 ,adPPYba, 8b,dPPYba,
|
||||
88""""" 88P' "8a 88 a8" "" `8b d8' a8" "8a 88P' `"8a
|
||||
88 88 d8 88 8b `8b d8' 8b d8 88 88
|
||||
88 88b, ,a8" 88 "8a, ,aa `8b,d8' "8a, ,a8" 88 88
|
||||
88888888888 88`YbbdP"' 88 `"Ybbd8"' Y88' `"YbbdP"' 88 88
|
||||
88 d8'
|
||||
88 d8'
|
|
@ -0,0 +1,10 @@
|
|||
88888888888 88
|
||||
88 ""
|
||||
88
|
||||
88aaaaa 8b,dPPYba, 88 ,adPPYba, 8b d8 ,adPPYba, 8b,dPPYba,
|
||||
88""""" 88P' "8a 88 a8" "" `8b d8' a8" "8a 88P' `"8a
|
||||
88 88 d8 88 8b `8b d8' 8b d8 88 88
|
||||
88 88b, ,a8" 88 "8a, ,aa `8b,d8' "8a, ,a8" 88 88
|
||||
88888888888 88`YbbdP"' 88 `"Ybbd8"' Y88' `"YbbdP"' 88 88
|
||||
88 d8'
|
||||
88 d8'
|
|
@ -0,0 +1,11 @@
|
|||
_, _, ,'`.
|
||||
`$$' `$$' `. ,' E P I C Y O N
|
||||
$$ $$ `'
|
||||
$$ $$ _, _
|
||||
,d$$$g$$ ,d$$$b. $$,d$$$b.`$$' g$$$$$b.`$$,d$$b.
|
||||
,$P' `$$ ,$P' `Y$. $$$' `$$ $$ "' `$$ $$$' `$$
|
||||
$$' $$ $$' `$$ $$' $$ $$ ,ggggg$$ $$' $$
|
||||
$$ $$ $$ggggg$$ $$ $$ $$ ,$P" $$ $$ $$
|
||||
$$ ,$$ $$. $$ ,$P $$ $$' ,$$ $$ $$
|
||||
`$g. ,$$$ `$$._ _., $$ _,g$P' $$ `$b. ,$$$ $$ $$
|
||||
`Y$$P'$$. `Y$$$$P',$$$$P"' ,$$. `Y$$P'$$.$$. ,$$.
|
|
@ -0,0 +1,14 @@
|
|||
_,met$$$$$gg.
|
||||
,g$$$$$$$$$$$$$$$P.
|
||||
,g$$P"" """Y$$.".
|
||||
,$$P' `$$$.
|
||||
,$$P ,ggs. `$$b:
|
||||
`d$$' ,$P"' . $$$
|
||||
$$P d$' , $$P
|
||||
$$: $$. - ,d$$'
|
||||
$$; Y$b._ _,d$P'
|
||||
Y$$. `.`"Y$$$$P"'
|
||||
`$$b "-.__
|
||||
`Y$$b
|
||||
`$$. E P I C Y O N
|
||||
`$.
|
|
@ -0,0 +1,8 @@
|
|||
__
|
||||
, ," e`--o
|
||||
(( ( | __,'
|
||||
\\~-------' \_;/
|
||||
( /
|
||||
/) .______. )
|
||||
(( ( (( (
|
||||
``-' ``-'
|
|
@ -0,0 +1,8 @@
|
|||
8888888888 8888888b. 8888888 .d8888b. Y88b d88P .d88888b. 888b 888
|
||||
888 888 Y88b 888 d88P Y88b Y88b d88P d88P" "Y88b 8888b 888
|
||||
888 888 888 888 888 888 Y88o88P 888 888 88888b 888
|
||||
8888888 888 d88P 888 888 Y888P 888 888 888Y88b 888
|
||||
888 8888888P" 888 888 888 888 888 888 Y88b888
|
||||
888 888 888 888 888 888 888 888 888 Y88888
|
||||
888 888 888 Y88b d88P 888 Y88b. .d88P 888 Y8888
|
||||
8888888888 888 8888888 "Y8888P" 888 "Y88888P" 888 Y888
|
|
@ -0,0 +1,10 @@
|
|||
88888888888 88
|
||||
88 ""
|
||||
88
|
||||
88aaaaa 8b,dPPYba, 88 ,adPPYba, 8b d8 ,adPPYba, 8b,dPPYba,
|
||||
88""""" 88P' "8a 88 a8" "" `8b d8' a8" "8a 88P' `"8a
|
||||
88 88 d8 88 8b `8b d8' 8b d8 88 88
|
||||
88 88b, ,a8" 88 "8a, ,aa `8b,d8' "8a, ,a8" 88 88
|
||||
88888888888 88`YbbdP"' 88 `"Ybbd8"' Y88' `"YbbdP"' 88 88
|
||||
88 d8'
|
||||
88 d8'
|
|
@ -0,0 +1,10 @@
|
|||
88888888888 88
|
||||
88 ""
|
||||
88
|
||||
88aaaaa 8b,dPPYba, 88 ,adPPYba, 8b d8 ,adPPYba, 8b,dPPYba,
|
||||
88""""" 88P' "8a 88 a8" "" `8b d8' a8" "8a 88P' `"8a
|
||||
88 88 d8 88 8b `8b d8' 8b d8 88 88
|
||||
88 88b, ,a8" 88 "8a, ,aa `8b,d8' "8a, ,a8" 88 88
|
||||
88888888888 88`YbbdP"' 88 `"Ybbd8"' Y88' `"YbbdP"' 88 88
|
||||
88 d8'
|
||||
88 d8'
|
|
@ -0,0 +1,7 @@
|
|||
____ _________ __ _____ ___ ____
|
||||
/ _]| \ | / ]| | | / \ | \
|
||||
| [_ | o ) | / / | | || || _ |
|
||||
| _]| _/| |/ / | ~ || O || | |
|
||||
| [_ | | | / \_ |___, || || | |
|
||||
| || | | \ || || || | |
|
||||
|_____||__| |____\____||____/ \___/ |__|__|
|
|
@ -0,0 +1,7 @@
|
|||
____ _________ __ _____ ___ ____
|
||||
/ _]| \ | / ]| | | / \ | \
|
||||
| [_ | o ) | / / | | || || _ |
|
||||
| _]| _/| |/ / | ~ || O || | |
|
||||
| [_ | | | / \_ |___, || || | |
|
||||
| || | | \ || || || | |
|
||||
|_____||__| |____\____||____/ \___/ |__|__|
|
|
@ -0,0 +1,8 @@
|
|||
/ \
|
||||
| / ,--. \ |
|
||||
\ \ `--' / /
|
||||
,------.,------. ,--. ,-----.,--. ,--.,-----. ,--. ,--.
|
||||
| .---'| .--. '| |' .--./ \ `.' /' .-. '| ,'.| |
|
||||
| `--, | '--' || || | '. / | | | || |' ' |
|
||||
| `---.| | --' | |' '--'\ | | ' '-' '| | ` |
|
||||
`------'`--' `--' `-----' `--' `-----' `--' `--'
|
|
@ -0,0 +1,8 @@
|
|||
/ \
|
||||
| / ,--. \ |
|
||||
\ \ `--' / /
|
||||
,------.,------. ,--. ,-----.,--. ,--.,-----. ,--. ,--.
|
||||
| .---'| .--. '| |' .--./ \ `.' /' .-. '| ,'.| |
|
||||
| `--, | '--' || || | '. / | | | || |' ' |
|
||||
| `---.| | --' | |' '--'\ | | ' '-' '| | ` |
|
||||
`------'`--' `--' `-----' `--' `-----' `--' `--'
|
|
@ -0,0 +1,8 @@
|
|||
/ \
|
||||
| / ,--. \ |
|
||||
\ \ `--' / /
|
||||
,------.,------. ,--. ,-----.,--. ,--.,-----. ,--. ,--.
|
||||
| .---'| .--. '| |' .--./ \ `.' /' .-. '| ,'.| |
|
||||
| `--, | '--' || || | '. / | | | || |' ' |
|
||||
| `---.| | --' | |' '--'\ | | ' '-' '| | ` |
|
||||
`------'`--' `--' `-----' `--' `-----' `--' `--'
|
|
@ -0,0 +1,8 @@
|
|||
/ \
|
||||
| / ,--. \ |
|
||||
\ \ `--' / /
|
||||
,------.,------. ,--. ,-----.,--. ,--.,-----. ,--. ,--.
|
||||
| .---'| .--. '| |' .--./ \ `.' /' .-. '| ,'.| |
|
||||
| `--, | '--' || || | '. / | | | || |' ' |
|
||||
| `---.| | --' | |' '--'\ | | ' '-' '| | ` |
|
||||
`------'`--' `--' `-----' `--' `-----' `--' `--'
|
|
@ -0,0 +1,6 @@
|
|||
_______ ______ _____ ______ _ _ _____ ______
|
||||
(_______|_____ (_____) _____) | | |/ ___ \| ___ \
|
||||
_____ _____) ) _ | / | |___| | | | | | | |
|
||||
| ___) | ____/ | || | \_____/| | | | | | |
|
||||
| |_____| | _| || \_____ ___ | |___| | | | |
|
||||
|_______)_| (_____)______) (___) \_____/|_| |_|
|
|
@ -0,0 +1,6 @@
|
|||
_______ ______ _____ ______ _ _ _____ ______
|
||||
(_______|_____ (_____) _____) | | |/ ___ \| ___ \
|
||||
_____ _____) ) _ | / | |___| | | | | | | |
|
||||
| ___) | ____/ | || | \_____/| | | | | | |
|
||||
| |_____| | _| || \_____ ___ | |___| | | | |
|
||||
|_______)_| (_____)______) (___) \_____/|_| |_|
|
|
@ -0,0 +1,6 @@
|
|||
88888888b 888888ba dP a88888b. dP dP .88888. 888888ba
|
||||
88 88 `8b 88 d8' `88 Y8. .8P d8' `8b 88 `8b
|
||||
a88aaaa a88aaaa8P' 88 88 Y8aa8P 88 88 88 88
|
||||
88 88 88 88 88 88 88 88 88
|
||||
88 88 88 Y8. .88 88 Y8. .8P 88 88
|
||||
88888888P dP dP Y88888P' dP `8888P' dP dP
|
|
@ -0,0 +1,6 @@
|
|||
88888888b 888888ba dP a88888b. dP dP .88888. 888888ba
|
||||
88 88 `8b 88 d8' `88 Y8. .8P d8' `8b 88 `8b
|
||||
a88aaaa a88aaaa8P' 88 88 Y8aa8P 88 88 88 88
|
||||
88 88 88 88 88 88 88 88 88
|
||||
88 88 88 Y8. .88 88 Y8. .8P 88 88
|
||||
88888888P dP dP Y88888P' dP `8888P' dP dP
|
|
@ -0,0 +1,14 @@
|
|||
( (
|
||||
) )
|
||||
___ ___ ___ _____ _____ _ _ ........
|
||||
| __| _ \_ _/ __\ \ / / _ \| \| | | |]
|
||||
| _|| _/| | (__ \ V / (_) | .` | \ /
|
||||
|___|_| |___\___| |_| \___/|_|\_| \____/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
( (
|
||||
) )
|
||||
___ ___ ___ _____ _____ _ _ ........
|
||||
| __| _ \_ _/ __\ \ / / _ \| \| | | |]
|
||||
| _|| _/| | (__ \ V / (_) | .` | \ /
|
||||
|___|_| |___\___| |_| \___/|_|\_| \____/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
888888888b 888888ba dP a88888b. dP dP .88888. 888888ba
|
||||
88 88 `8b 88 d8' `88 Y8. .8P d8' `8b 88 `8b
|
||||
a88aaaa a88aaaa8P' 88 88 Y8aa8P 88 88 88 88
|
||||
88 88 88 88 88 88 88 88 88
|
||||
88 88 88 Y8. .88 88 Y8. .8P 88 88
|
||||
88888888P' dP dP Y88888P' 88 `8888P' dP dP
|
||||
88
|
||||
dP
|
|
@ -0,0 +1,8 @@
|
|||
888888888b 888888ba dP a88888b. dP dP .88888. 888888ba
|
||||
88 88 `8b 88 d8' `88 Y8. .8P d8' `8b 88 `8b
|
||||
a88aaaa a88aaaa8P' 88 88 Y8aa8P 88 88 88 88
|
||||
88 88 88 88 88 88 88 88 88
|
||||
88 88 88 Y8. .88 88 Y8. .8P 88 88
|
||||
88888888P' dP dP Y88888P' 88 `8888P' dP dP
|
||||
88
|
||||
dP
|
|
@ -0,0 +1,8 @@
|
|||
__
|
||||
, ," e`--o
|
||||
(( ( | __,'
|
||||
\\~-------' \_;/
|
||||
( /
|
||||
/) .______. )
|
||||
(( ( (( (
|
||||
``-' ``-'
|
|
@ -0,0 +1,8 @@
|
|||
8888888888 8888888b. 8888888 .d8888b. Y88b d88P .d88888b. 888b 888
|
||||
888 888 Y88b 888 d88P Y88b Y88b d88P d88P" "Y88b 8888b 888
|
||||
888 888 888 888 888 888 Y88o88P 888 888 88888b 888
|
||||
8888888 888 d88P 888 888 Y888P 888 888 888Y88b 888
|
||||
888 8888888P" 888 888 888 888 888 888 Y88b888
|
||||
888 888 888 888 888 888 888 888 888 Y88888
|
||||
888 888 888 Y88b d88P 888 Y88b. .d88P 888 Y8888
|
||||
8888888888 888 8888888 "Y8888P" 888 "Y88888P" 888 Y888
|
|
@ -0,0 +1,9 @@
|
|||
oooooooooooo o8o
|
||||
`888' `8 `"'
|
||||
888 oo.ooooo. oooo .ooooo. oooo ooo .ooooo. ooo. .oo.
|
||||
888oooo8 888' `88b `888 d88' `"Y8 `88. .8' d88' `88b `888P"Y88b
|
||||
888 " 888 888 888 888 `88..8' 888 888 888 888
|
||||
888 o 888 888 888 888 .o8 `888' 888 888 888 888
|
||||
o888ooooood8 888bod8P' o888o `Y8bod8P' .8' `Y8bod8P' o888o o888o
|
||||
888 .o..P'
|
||||
o888o `Y8P'
|
|
@ -0,0 +1,9 @@
|
|||
oooooooooooo o8o
|
||||
`888' `8 `"'
|
||||
888 oo.ooooo. oooo .ooooo. oooo ooo .ooooo. ooo. .oo.
|
||||
888oooo8 888' `88b `888 d88' `"Y8 `88. .8' d88' `88b `888P"Y88b
|
||||
888 " 888 888 888 888 `88..8' 888 888 888 888
|
||||
888 o 888 888 888 888 .o8 `888' 888 888 888 888
|
||||
o888ooooood8 888bod8P' o888o `Y8bod8P' .8' `Y8bod8P' o888o o888o
|
||||
888 .o..P'
|
||||
o888o `Y8P'
|
|
@ -0,0 +1,6 @@
|
|||
_______ ______ _____ ______ _ _ _____ ______
|
||||
(_______|_____ (_____) _____) | | |/ ___ \| ___ \
|
||||
_____ _____) ) _ | / | |___| | | | | | | |
|
||||
| ___) | ____/ | || | \_____/| | | | | | |
|
||||
| |_____| | _| || \_____ ___ | |___| | | | |
|
||||
|_______)_| (_____)______) (___) \_____/|_| |_|
|
|
@ -0,0 +1,6 @@
|
|||
_______ ______ _____ ______ _ _ _____ ______
|
||||
(_______|_____ (_____) _____) | | |/ ___ \| ___ \
|
||||
_____ _____) ) _ | / | |___| | | | | | | |
|
||||
| ___) | ____/ | || | \_____/| | | | | | |
|
||||
| |_____| | _| || \_____ ___ | |___| | | | |
|
||||
|_______)_| (_____)______) (___) \_____/|_| |_|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
_______ _____ _____ _______ __ __ _____ __ _ _=_
|
||||
| | | | | \ / | | |\ | q(-_-)p
|
||||
|______ |_____| | | \_/ | | | \ | ,\___/\
|
||||
| | | | | | | | \ | ( _ _ )
|
||||
|______ | __|__ |_____ | |_____| | \| (_\_\_|_/_)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
_______ _____ _____ _______ __ __ _____ __ _ _=_
|
||||
| | | | | \ / | | |\ | q(-_-)p
|
||||
|______ |_____| | | \_/ | | | \ | ,\___/\
|
||||
| | | | | | | | \ | ( _ _ )
|
||||
|______ | __|__ |_____ | |_____| | \| (_\_\_|_/_)
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "الإصدار",
|
||||
"Skip to timeline": "تخطي إلى الجدول الزمني",
|
||||
"Skip to Newswire": "انتقل إلى Newswire",
|
||||
"Skip to Links": "تخطي إلى روابط الويب"
|
||||
"Skip to Links": "تخطي إلى روابط الويب",
|
||||
"Publish a blog article": "نشر مقال بلوق"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Versió",
|
||||
"Skip to timeline": "Ves a la cronologia",
|
||||
"Skip to Newswire": "Vés a Newswire",
|
||||
"Skip to Links": "Vés als enllaços web"
|
||||
"Skip to Links": "Vés als enllaços web",
|
||||
"Publish a blog article": "Publicar un article del bloc"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Fersiwn",
|
||||
"Skip to timeline": "Neidio i'r llinell amser",
|
||||
"Skip to Newswire": "Neidio i Newswire",
|
||||
"Skip to Links": "Neidio i Dolenni Gwe"
|
||||
"Skip to Links": "Neidio i Dolenni Gwe",
|
||||
"Publish a blog article": "Cyhoeddi erthygl blog"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Ausführung",
|
||||
"Skip to timeline": "Zur Zeitleiste springen",
|
||||
"Skip to Newswire": "Springe zu Newswire",
|
||||
"Skip to Links": "Springe zu Weblinks"
|
||||
"Skip to Links": "Springe zu Weblinks",
|
||||
"Publish a blog article": "Veröffentlichen Sie einen Blog-Artikel"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Version",
|
||||
"Skip to timeline": "Skip to timeline",
|
||||
"Skip to Newswire": "Skip to Newswire",
|
||||
"Skip to Links": "Skip to Links"
|
||||
"Skip to Links": "Skip to Links",
|
||||
"Publish a blog article": "Publish a blog article"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Versión",
|
||||
"Skip to timeline": "Saltar a la línea de tiempo",
|
||||
"Skip to Newswire": "Saltar a Newswire",
|
||||
"Skip to Links": "Saltar a enlaces web"
|
||||
"Skip to Links": "Saltar a enlaces web",
|
||||
"Publish a blog article": "Publica un artículo de blog"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Version",
|
||||
"Skip to timeline": "Passer à la chronologie",
|
||||
"Skip to Newswire": "Passer à Newswire",
|
||||
"Skip to Links": "Passer aux liens Web"
|
||||
"Skip to Links": "Passer aux liens Web",
|
||||
"Publish a blog article": "Publier un article de blog"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Leagan",
|
||||
"Skip to timeline": "Scipeáil chuig an amlíne",
|
||||
"Skip to Newswire": "Scipeáil chuig Newswire",
|
||||
"Skip to Links": "Scipeáil chuig Naisc Ghréasáin"
|
||||
"Skip to Links": "Scipeáil chuig Naisc Ghréasáin",
|
||||
"Publish a blog article": "Foilsigh alt blagála"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "संस्करण",
|
||||
"Skip to timeline": "टाइमलाइन पर जाएं",
|
||||
"Skip to Newswire": "Newswire पर जाएं",
|
||||
"Skip to Links": "वेब लिंक पर जाएं"
|
||||
"Skip to Links": "वेब लिंक पर जाएं",
|
||||
"Publish a blog article": "एक ब्लॉग लेख प्रकाशित करें"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Versione",
|
||||
"Skip to timeline": "Passa alla sequenza temporale",
|
||||
"Skip to Newswire": "Passa a Newswire",
|
||||
"Skip to Links": "Passa a collegamenti Web"
|
||||
"Skip to Links": "Passa a collegamenti Web",
|
||||
"Publish a blog article": "Pubblica un articolo sul blog"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "バージョン",
|
||||
"Skip to timeline": "タイムラインにスキップ",
|
||||
"Skip to Newswire": "Newswireにスキップ",
|
||||
"Skip to Links": "Webリンクにスキップ"
|
||||
"Skip to Links": "Webリンクにスキップ",
|
||||
"Publish a blog article": "ブログ記事を公開する"
|
||||
}
|
||||
|
|
|
@ -362,5 +362,6 @@
|
|||
"Version": "Version",
|
||||
"Skip to timeline": "Skip to timeline",
|
||||
"Skip to Newswire": "Skip to Newswire",
|
||||
"Skip to Links": "Skip to Links"
|
||||
"Skip to Links": "Skip to Links",
|
||||
"Publish a blog article": "Publish a blog article"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Versão",
|
||||
"Skip to timeline": "Pular para a linha do tempo",
|
||||
"Skip to Newswire": "Pular para Newswire",
|
||||
"Skip to Links": "Pular para links da web"
|
||||
"Skip to Links": "Pular para links da web",
|
||||
"Publish a blog article": "Publique um artigo de blog"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "Версия",
|
||||
"Skip to timeline": "Перейти к временной шкале",
|
||||
"Skip to Newswire": "Перейти к ленте новостей",
|
||||
"Skip to Links": "Перейти к веб-ссылкам"
|
||||
"Skip to Links": "Перейти к веб-ссылкам",
|
||||
"Publish a blog article": "Опубликовать статью в блоге"
|
||||
}
|
||||
|
|
|
@ -366,5 +366,6 @@
|
|||
"Version": "版",
|
||||
"Skip to timeline": "跳到时间线",
|
||||
"Skip to Newswire": "跳到新闻专线",
|
||||
"Skip to Links": "跳到网页链接"
|
||||
"Skip to Links": "跳到网页链接",
|
||||
"Publish a blog article": "发布博客文章"
|
||||
}
|
||||
|
|
12
utils.py
12
utils.py
|
@ -494,10 +494,20 @@ def evilIncarnate() -> []:
|
|||
|
||||
|
||||
def isEvil(domain: str) -> bool:
|
||||
# https://www.youtube.com/watch?v=5qw1hcevmdU
|
||||
if not isinstance(domain, str):
|
||||
print('WARN: Malformed domain ' + str(domain))
|
||||
return True
|
||||
# https://www.youtube.com/watch?v=5qw1hcevmdU
|
||||
# if a domain contains any of these strings then it is
|
||||
# declaring itself to be hostile
|
||||
evilEmporium = (
|
||||
'nazi', 'extremis', 'extreemis', 'gendercritic',
|
||||
'kiwifarm', 'illegal', 'raplst', 'rapist',
|
||||
'antivax', 'plandemic'
|
||||
)
|
||||
for hostileStr in evilEmporium:
|
||||
if hostileStr in domain:
|
||||
return True
|
||||
evilDomains = evilIncarnate()
|
||||
for concentratedEvil in evilDomains:
|
||||
if domain.endswith(concentratedEvil):
|
||||
|
|
|
@ -50,7 +50,8 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool,
|
||||
showHeaderImage: bool,
|
||||
theme: str) -> str:
|
||||
theme: str,
|
||||
defaultTimeline: str) -> str:
|
||||
"""Returns html content for the right column
|
||||
"""
|
||||
htmlStr = ''
|
||||
|
@ -62,10 +63,13 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
if authorized:
|
||||
# only show the publish button if logged in, otherwise replace it with
|
||||
# a login button
|
||||
titleStr = translate['Publish a blog article']
|
||||
if defaultTimeline == 'tlfeatures':
|
||||
titleStr = translate['Publish a news article']
|
||||
publishButtonStr = \
|
||||
' <a href="' + \
|
||||
'/users/' + nickname + '/newblog" ' + \
|
||||
'title="' + translate['Publish a news article'] + '">' + \
|
||||
'/users/' + nickname + '/newblog?nodropdown" ' + \
|
||||
'title="' + titleStr + '">' + \
|
||||
'<button class="publishbtn">' + \
|
||||
translate['Publish'] + '</button></a>\n'
|
||||
else:
|
||||
|
@ -158,13 +162,16 @@ def getRightColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
# show publish icon at top
|
||||
if showPublishButton:
|
||||
if showPublishAsIcon:
|
||||
titleStr = translate['Publish a blog article']
|
||||
if defaultTimeline == 'tlfeatures':
|
||||
titleStr = translate['Publish a news article']
|
||||
htmlStr += \
|
||||
' <a href="' + \
|
||||
'/users/' + nickname + '/newblog">' + \
|
||||
'/users/' + nickname + '/newblog?nodropdown">' + \
|
||||
'<img class="' + editImageClass + \
|
||||
'" loading="lazy" alt="' + \
|
||||
translate['Publish a news article'] + '" title="' + \
|
||||
translate['Publish a news article'] + '" src="/' + \
|
||||
titleStr + '" title="' + \
|
||||
titleStr + '" src="/' + \
|
||||
'icons/publish.png" /></a>\n'
|
||||
|
||||
if editImageClass == 'rightColEdit':
|
||||
|
@ -485,7 +492,8 @@ def htmlNewswireMobile(cssCache: {}, baseDir: str, nickname: str,
|
|||
newswire, positiveVoting,
|
||||
False, timelinePath, showPublishButton,
|
||||
showPublishAsIcon, rssIconAtTop, False,
|
||||
authorized, False, theme)
|
||||
authorized, False, theme,
|
||||
defaultTimeline)
|
||||
else:
|
||||
if editor:
|
||||
htmlStr += '<br><br><br>\n'
|
||||
|
|
|
@ -71,19 +71,25 @@ def _htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
|
|||
dropdownDMSuffix: str,
|
||||
dropdownReminderSuffix: str,
|
||||
dropdownEventSuffix: str,
|
||||
dropdownReportSuffix: str) -> str:
|
||||
dropdownReportSuffix: str,
|
||||
noDropDown: bool) -> str:
|
||||
"""Returns the html for a drop down list of new post types
|
||||
"""
|
||||
dropDownContent = '<nav><div class="newPostDropdown">\n'
|
||||
dropDownContent += ' <input type="checkbox" ' + \
|
||||
'id="my-newPostDropdown" value="" name="my-checkbox">\n'
|
||||
if not noDropDown:
|
||||
dropDownContent += ' <input type="checkbox" ' + \
|
||||
'id="my-newPostDropdown" value="" name="my-checkbox">\n'
|
||||
dropDownContent += ' <label for="my-newPostDropdown"\n'
|
||||
dropDownContent += ' data-toggle="newPostDropdown">\n'
|
||||
dropDownContent += ' <img loading="lazy" alt="" title="" src="/' + \
|
||||
'icons/' + scopeIcon + '"/><b>' + \
|
||||
scopeDescription + '</b></label>\n'
|
||||
dropDownContent += ' <ul>\n'
|
||||
|
||||
if noDropDown:
|
||||
dropDownContent += '</div></nav>\n'
|
||||
return dropDownContent
|
||||
|
||||
dropDownContent += ' <ul>\n'
|
||||
if showPublicOnDropdown:
|
||||
dropDownContent += \
|
||||
'<li><a href="' + pathBase + dropdownNewPostSuffix + \
|
||||
|
@ -156,8 +162,8 @@ def _htmlNewPostDropDown(scopeIcon: str, scopeDescription: str,
|
|||
'icons/scope_question.png"/><b>' + \
|
||||
translate['Question'] + '</b><br>' + \
|
||||
translate['Ask a question'] + '</a></li>\n'
|
||||
|
||||
dropDownContent += ' </ul>\n'
|
||||
|
||||
dropDownContent += '</div></nav>\n'
|
||||
return dropDownContent
|
||||
|
||||
|
@ -171,7 +177,7 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
|
|||
nickname: str, domain: str,
|
||||
domainFull: str,
|
||||
defaultTimeline: str, newswire: {},
|
||||
theme: str) -> str:
|
||||
theme: str, noDropDown: bool) -> str:
|
||||
"""New post screen
|
||||
"""
|
||||
replyStr = ''
|
||||
|
@ -641,7 +647,8 @@ def htmlNewPost(cssCache: {}, mediaInstance: bool, translate: {},
|
|||
dropdownDMSuffix,
|
||||
dropdownReminderSuffix,
|
||||
dropdownEventSuffix,
|
||||
dropdownReportSuffix)
|
||||
dropdownReportSuffix,
|
||||
noDropDown)
|
||||
else:
|
||||
if not shareDescription:
|
||||
# reporting a post to moderator
|
||||
|
|
|
@ -169,7 +169,8 @@ def htmlFrontScreen(rssIconAtTop: bool,
|
|||
httpPrefix, translate,
|
||||
False, False, newswire, False,
|
||||
False, None, False, False,
|
||||
False, True, authorized, True, theme)
|
||||
False, True, authorized, True, theme,
|
||||
defaultTimeline)
|
||||
profileFooterStr += ' </td>\n'
|
||||
profileFooterStr += ' </tr>\n'
|
||||
profileFooterStr += ' </tbody>\n'
|
||||
|
|
|
@ -53,25 +53,25 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if defaultTimeline == 'tlmedia':
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/tlmedia"><button class="' + \
|
||||
'/tlmedia" tabindex="-1"><button class="' + \
|
||||
mediaButton + '"><span>' + translate['Media'] + \
|
||||
'</span></button></a>'
|
||||
elif defaultTimeline == 'tlblogs':
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/tlblogs"><button class="' + \
|
||||
'/tlblogs" tabindex="-1"><button class="' + \
|
||||
blogsButton + '"><span>' + translate['Blogs'] + \
|
||||
'</span></button></a>'
|
||||
elif defaultTimeline == 'tlfeatures':
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/tlfeatures"><button class="' + \
|
||||
'/tlfeatures" tabindex="-1"><button class="' + \
|
||||
featuresButton + '"><span>' + translate['Features'] + \
|
||||
'</span></button></a>'
|
||||
else:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/inbox"><button class="' + \
|
||||
'/inbox" tabindex="-1"><button class="' + \
|
||||
inboxButton + '"><span>' + \
|
||||
translate['Inbox'] + '</span></button></a>'
|
||||
|
||||
|
@ -83,7 +83,7 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if not featuresHeader:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/dm"><button class="' + dmButton + \
|
||||
'/dm" tabindex="-1"><button class="' + dmButton + \
|
||||
'"><span>' + htmlHighlightLabel(translate['DM'], newDM) + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -92,8 +92,8 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
nickname + '@' + domain + '/tlreplies.index'
|
||||
if os.path.isfile(repliesIndexFilename):
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + '/tlreplies"><button class="' + \
|
||||
repliesButton + '"><span>' + \
|
||||
'<a href="' + usersPath + '/tlreplies" tabindex="-1">' + \
|
||||
'<button class="' + repliesButton + '"><span>' + \
|
||||
htmlHighlightLabel(translate['Replies'], newReply) + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -102,14 +102,14 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if not minimal and not featuresHeader:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/tlmedia"><button class="' + \
|
||||
'/tlmedia" tabindex="-1"><button class="' + \
|
||||
mediaButton + '"><span>' + translate['Media'] + \
|
||||
'</span></button></a>'
|
||||
else:
|
||||
if not minimal:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/inbox"><button class="' + \
|
||||
'/inbox" tabindex="-1"><button class="' + \
|
||||
inboxButton+'"><span>' + translate['Inbox'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -123,14 +123,14 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
titleStr = translate['Article']
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/tlblogs"><button class="' + \
|
||||
'/tlblogs" tabindex="-1"><button class="' + \
|
||||
blogsButton + '"><span>' + titleStr + \
|
||||
'</span></button></a>'
|
||||
else:
|
||||
if not minimal:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/inbox"><button class="' + \
|
||||
'/inbox" tabindex="-1"><button class="' + \
|
||||
inboxButton + '"><span>' + translate['Inbox'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -140,7 +140,7 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if not featuresHeader:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/inbox"><button class="' + \
|
||||
'/inbox" tabindex="-1"><button class="' + \
|
||||
inboxButton + '"><span>' + translate['Inbox'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -155,14 +155,14 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
happeningStr += \
|
||||
'<a href="' + usersPath + '/calendar?year=' + \
|
||||
str(now.year) + '?month=' + str(now.month) + \
|
||||
'?day=' + str(now.day) + '">' + \
|
||||
'?day=' + str(now.day) + '" tabindex="-1">' + \
|
||||
'<button class="buttonevent">' + \
|
||||
translate['Happening Today'] + '</button></a>'
|
||||
else:
|
||||
happeningStr += \
|
||||
'<a href="' + usersPath + '/calendar?year=' + \
|
||||
str(now.year) + '?month=' + str(now.month) + \
|
||||
'?day=' + str(now.day) + '">' + \
|
||||
'?day=' + str(now.day) + '" tabindex="-1">' + \
|
||||
'<button class="button">' + \
|
||||
translate['Happening Today'] + '</button></a>'
|
||||
|
||||
|
@ -171,12 +171,14 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if not iconsAsButtons:
|
||||
happeningStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/calendar"><button class="buttonevent">' + \
|
||||
'/calendar" tabindex="-1">' + \
|
||||
'<button class="buttonevent">' + \
|
||||
translate['Happening This Week'] + '</button></a>'
|
||||
else:
|
||||
happeningStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/calendar"><button class="button">' + \
|
||||
'/calendar" tabindex="-1">' + \
|
||||
'<button class="button">' + \
|
||||
translate['Happening This Week'] + '</button></a>'
|
||||
else:
|
||||
# happening this week button
|
||||
|
@ -184,12 +186,14 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
if not iconsAsButtons:
|
||||
happeningStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/calendar"><button class="buttonevent">' + \
|
||||
'/calendar" tabindex="-1">' + \
|
||||
'<button class="buttonevent">' + \
|
||||
translate['Happening This Week'] + '</button></a>'
|
||||
else:
|
||||
happeningStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/calendar"><button class="button">' + \
|
||||
'/calendar" tabindex="-1">' + \
|
||||
'<button class="button">' + \
|
||||
translate['Happening This Week'] + '</button></a>'
|
||||
|
||||
if not featuresHeader:
|
||||
|
@ -197,7 +201,8 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/outbox"><button class="' + \
|
||||
sentButton + '"><span>' + translate['Outbox'] + \
|
||||
sentButton + '" tabindex="-1">' + \
|
||||
'<span>' + translate['Outbox'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
# add other buttons
|
||||
|
@ -219,7 +224,7 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
# the search button
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + \
|
||||
'/search"><button class="button">' + \
|
||||
'/search" tabindex="-1"><button class="button">' + \
|
||||
'<span>' + translate['Search'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -245,7 +250,7 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
else:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + calendarPath + \
|
||||
'"><button class="button">' + \
|
||||
'" tabindex="-1"><button class="button">' + \
|
||||
'<span>' + translate['Calendar'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -262,13 +267,13 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
else:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + '/minimal' + \
|
||||
'"><button class="button">' + \
|
||||
'" tabindex="-1"><button class="button">' + \
|
||||
'<span>' + translate['Show/Hide Buttons'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
if featuresHeader:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + '/inbox">' + \
|
||||
'<a href="' + usersPath + '/inbox" tabindex="-1">' + \
|
||||
'<button class="button">' + \
|
||||
'<span>' + translate['User'] + '</span></button></a>'
|
||||
|
||||
|
@ -286,7 +291,7 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
tlStr += \
|
||||
'<a href="' + \
|
||||
usersPath + '/newswiremobile' + \
|
||||
'"><button class="buttonMobile">' + \
|
||||
'" tabindex="-1"><button class="buttonMobile">' + \
|
||||
'<span>' + translate['Newswire'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
|
@ -304,13 +309,13 @@ def headerButtonsTimeline(defaultTimeline: str,
|
|||
tlStr += \
|
||||
'<a href="' + \
|
||||
usersPath + '/linksmobile' + \
|
||||
'"><button class="buttonMobile">' + \
|
||||
'" tabindex="-1"><button class="buttonMobile">' + \
|
||||
'<span>' + translate['Links'] + \
|
||||
'</span></button></a>'
|
||||
|
||||
if featuresHeader:
|
||||
tlStr += \
|
||||
'<a href="' + usersPath + '/editprofile">' + \
|
||||
'<a href="' + usersPath + '/editprofile" tabindex="-1">' + \
|
||||
'<button class="buttonDesktop">' + \
|
||||
'<span>' + translate['Settings'] + '</span></button></a>'
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ from utils import getConfigParam
|
|||
from utils import noOfAccounts
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
from webapp_utils import htmlFooter
|
||||
from webapp_utils import htmlKeyboardNavigation
|
||||
from theme import getTextModeLogo
|
||||
|
||||
|
||||
def htmlGetLoginCredentials(loginParams: str,
|
||||
|
@ -75,6 +77,9 @@ def htmlLogin(cssCache: {}, translate: {},
|
|||
loginImageFilename = baseDir + '/accounts/' + loginImage
|
||||
copyfile(baseDir + '/img/login.png', loginImageFilename)
|
||||
|
||||
textModeLogo = getTextModeLogo(baseDir)
|
||||
textModeLogoHtml = htmlKeyboardNavigation(textModeLogo, {})
|
||||
|
||||
if os.path.isfile(baseDir + '/accounts/login-background-custom.jpg'):
|
||||
if not os.path.isfile(baseDir + '/accounts/login-background.jpg'):
|
||||
copyfile(baseDir + '/accounts/login-background-custom.jpg',
|
||||
|
@ -139,8 +144,7 @@ def htmlLogin(cssCache: {}, translate: {},
|
|||
loginForm += '<form method="POST" action="/login">\n'
|
||||
loginForm += ' <div class="imgcontainer">\n'
|
||||
instanceTitle = getConfigParam(baseDir, 'instanceTitle')
|
||||
if not instanceTitle:
|
||||
instanceTitle = "Epicyon"
|
||||
loginForm += textModeLogoHtml + '\n'
|
||||
loginForm += \
|
||||
' <img loading="lazy" src="' + loginImage + \
|
||||
'" alt="' + instanceTitle + '" class="loginimage">\n'
|
||||
|
|
|
@ -43,7 +43,8 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, moderationActionStr: str,
|
||||
theme: str, peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the moderation feed as html
|
||||
This is what you see when selecting the "mod" timeline
|
||||
"""
|
||||
|
@ -58,7 +59,8 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, moderationActionStr, theme,
|
||||
peertubeInstances, allowLocalNetworkAccess)
|
||||
peertubeInstances, allowLocalNetworkAccess,
|
||||
textModeBanner)
|
||||
|
||||
|
||||
def htmlAccountInfo(cssCache: {}, translate: {},
|
||||
|
|
|
@ -244,15 +244,19 @@ def _getAvatarImageHtml(showAvatarOptions: bool,
|
|||
';' + str(pageNumber) + ';' + avatarUrl + messageIdStr + '">\n'
|
||||
avatarLink += \
|
||||
' <img loading="lazy" title="' + \
|
||||
translate['Show options for this person'] + \
|
||||
'" src="' + avatarUrl + '" ' + avatarPosition + \
|
||||
translate['Show options for this person'] + '" ' + \
|
||||
'alt="👤 ' + \
|
||||
translate['Show options for this person'] + '" ' + \
|
||||
'src="' + avatarUrl + '" ' + avatarPosition + \
|
||||
getBrokenLinkSubstitute() + '/></a>\n'
|
||||
else:
|
||||
# don't link to the person options for the news account
|
||||
avatarLink += \
|
||||
' <img loading="lazy" title="' + \
|
||||
translate['Show options for this person'] + \
|
||||
'" src="' + avatarUrl + '" ' + avatarPosition + \
|
||||
translate['Show options for this person'] + '" ' + \
|
||||
'alt="👤 ' + \
|
||||
translate['Show options for this person'] + '" ' + \
|
||||
'src="' + avatarUrl + '" ' + avatarPosition + \
|
||||
getBrokenLinkSubstitute() + '/>\n'
|
||||
return avatarLink.strip()
|
||||
|
||||
|
@ -388,12 +392,14 @@ def _getAnnounceIconHtml(nickname: str, domainFull: str,
|
|||
# don't allow announce/repeat of your own posts
|
||||
announceIcon = 'repeat_inactive.png'
|
||||
announceLink = 'repeat'
|
||||
announceEmoji = ''
|
||||
if not isPublicRepeat:
|
||||
announceLink = 'repeatprivate'
|
||||
announceTitle = translate['Repeat this post']
|
||||
|
||||
if announcedByPerson(postJsonObject, nickname, domainFull):
|
||||
announceIcon = 'repeat.png'
|
||||
announceEmoji = '🔁 '
|
||||
if not isPublicRepeat:
|
||||
announceLink = 'unrepeatprivate'
|
||||
announceTitle = translate['Undo the repeat']
|
||||
|
@ -409,7 +415,7 @@ def _getAnnounceIconHtml(nickname: str, domainFull: str,
|
|||
announceStr += \
|
||||
' ' + \
|
||||
'<img loading="lazy" title="' + translate['Repeat this post'] + \
|
||||
'" alt="' + translate['Repeat this post'] + \
|
||||
'" alt="' + announceEmoji + translate['Repeat this post'] + \
|
||||
' |" src="/icons/' + announceIcon + '"/></a>\n'
|
||||
return announceStr
|
||||
|
||||
|
@ -430,6 +436,7 @@ def _getLikeIconHtml(nickname: str, domainFull: str,
|
|||
likeIcon = 'like_inactive.png'
|
||||
likeLink = 'like'
|
||||
likeTitle = translate['Like this post']
|
||||
likeEmoji = ''
|
||||
likeCount = noOfLikes(postJsonObject)
|
||||
|
||||
_logPostTiming(enableTimingLog, postStartTime, '12.1')
|
||||
|
@ -447,6 +454,7 @@ def _getLikeIconHtml(nickname: str, domainFull: str,
|
|||
likeIcon = 'like.png'
|
||||
likeLink = 'unlike'
|
||||
likeTitle = translate['Undo the like']
|
||||
likeEmoji = '👍 '
|
||||
|
||||
_logPostTiming(enableTimingLog, postStartTime, '12.2')
|
||||
|
||||
|
@ -467,7 +475,7 @@ def _getLikeIconHtml(nickname: str, domainFull: str,
|
|||
likeStr += \
|
||||
' ' + \
|
||||
'<img loading="lazy" title="' + likeTitle + likeCountStr + \
|
||||
'" alt="' + likeTitle + \
|
||||
'" alt="' + likeEmoji + likeTitle + \
|
||||
' |" src="/icons/' + likeIcon + '"/></a>\n'
|
||||
return likeStr
|
||||
|
||||
|
@ -489,10 +497,12 @@ def _getBookmarkIconHtml(nickname: str, domainFull: str,
|
|||
|
||||
bookmarkIcon = 'bookmark_inactive.png'
|
||||
bookmarkLink = 'bookmark'
|
||||
bookmarkEmoji = ''
|
||||
bookmarkTitle = translate['Bookmark this post']
|
||||
if bookmarkedByPerson(postJsonObject, nickname, domainFull):
|
||||
bookmarkIcon = 'bookmark.png'
|
||||
bookmarkLink = 'unbookmark'
|
||||
bookmarkEmoji = '🔖 '
|
||||
bookmarkTitle = translate['Undo the bookmark']
|
||||
_logPostTiming(enableTimingLog, postStartTime, '12.6')
|
||||
bookmarkStr = \
|
||||
|
@ -505,7 +515,7 @@ def _getBookmarkIconHtml(nickname: str, domainFull: str,
|
|||
bookmarkStr += \
|
||||
' ' + \
|
||||
'<img loading="lazy" title="' + bookmarkTitle + '" alt="' + \
|
||||
bookmarkTitle + ' |" src="/icons' + \
|
||||
bookmarkEmoji + bookmarkTitle + ' |" src="/icons' + \
|
||||
'/' + bookmarkIcon + '"/></a>\n'
|
||||
return bookmarkStr
|
||||
|
||||
|
@ -548,7 +558,7 @@ def _getMuteIconHtml(isMuted: bool,
|
|||
translate['Undo mute'] + '">\n'
|
||||
muteStr += \
|
||||
' ' + \
|
||||
'<img loading="lazy" alt="' + translate['Undo mute'] + \
|
||||
'<img loading="lazy" alt="🔇 ' + translate['Undo mute'] + \
|
||||
' |" title="' + translate['Undo mute'] + \
|
||||
'" src="/icons/unmute.png"/></a>\n'
|
||||
return muteStr
|
||||
|
|
|
@ -40,6 +40,8 @@ from jami import getJamiAddress
|
|||
from filters import isFiltered
|
||||
from follow import isFollowerOfPerson
|
||||
from webapp_frontscreen import htmlFrontScreen
|
||||
from webapp_utils import htmlKeyboardNavigation
|
||||
from webapp_utils import htmlHideFromScreenReader
|
||||
from webapp_utils import scheduledPostsExist
|
||||
from webapp_utils import getPersonAvatarUrl
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
|
@ -472,6 +474,7 @@ def htmlProfile(rssIconAtTop: bool,
|
|||
newswire: {}, theme: str, dormantMonths: int,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str,
|
||||
extraJson=None, pageNumber=None,
|
||||
maxItemsPerPage=None) -> str:
|
||||
"""Show the profile page as html
|
||||
|
@ -707,16 +710,37 @@ def htmlProfile(rssIconAtTop: bool,
|
|||
movedTo, alsoKnownAs,
|
||||
pinnedContent)
|
||||
|
||||
# Links for keyboard navigation
|
||||
profileStr = \
|
||||
'<div class="transparent">' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a href="/users/' + nickname + '/' + defaultTimeline + '">' + \
|
||||
translate['Switch to timeline view'] + '</a></label> | ' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a class="skip-main" href="#buttonheader">' + \
|
||||
translate['Skip to timeline'] + '</a></label>' + \
|
||||
'</div>\n'
|
||||
# keyboard navigation
|
||||
userPathStr = '/users/' + nickname
|
||||
deft = defaultTimeline
|
||||
menuTimeline = \
|
||||
htmlHideFromScreenReader('🏠') + ' ' + \
|
||||
translate['Switch to timeline view']
|
||||
menuEdit = \
|
||||
htmlHideFromScreenReader('✍') + ' ' + translate['Edit']
|
||||
menuFollowing = \
|
||||
htmlHideFromScreenReader('👥') + ' ' + translate['Following']
|
||||
menuFollowers = \
|
||||
htmlHideFromScreenReader('👪') + ' ' + translate['Followers']
|
||||
menuRoles = \
|
||||
htmlHideFromScreenReader('🤚') + ' ' + translate['Roles']
|
||||
menuSkills = \
|
||||
htmlHideFromScreenReader('🛠') + ' ' + translate['Skills']
|
||||
menuShares = \
|
||||
htmlHideFromScreenReader('🤝') + ' ' + translate['Shares']
|
||||
menuLogout = \
|
||||
htmlHideFromScreenReader('❎') + ' ' + translate['Logout']
|
||||
navLinks = {
|
||||
menuTimeline: userPathStr + '/' + deft,
|
||||
menuEdit: userPathStr + '/editprofile',
|
||||
menuFollowing: userPathStr + '/following#timeline',
|
||||
menuFollowers: userPathStr + '/followers#timeline',
|
||||
menuRoles: userPathStr + '/roles#timeline',
|
||||
menuSkills: userPathStr + '/skills#timeline',
|
||||
menuShares: userPathStr + '/shares#timeline',
|
||||
menuLogout: '/logout'
|
||||
}
|
||||
profileStr = htmlKeyboardNavigation(textModeBanner, navLinks)
|
||||
|
||||
profileStr += profileHeaderStr + donateSection
|
||||
profileStr += '<div class="container" id="buttonheader">\n'
|
||||
|
@ -750,6 +774,9 @@ def htmlProfile(rssIconAtTop: bool,
|
|||
profileStr += ' </center>'
|
||||
profileStr += '</div>'
|
||||
|
||||
# start of #timeline
|
||||
profileStr += '<div id="timeline">\n'
|
||||
|
||||
profileStr += followApprovalsSection
|
||||
|
||||
cssFilename = baseDir + '/epicyon-profile.css'
|
||||
|
@ -804,6 +831,8 @@ def htmlProfile(rssIconAtTop: bool,
|
|||
_htmlProfileShares(actor, translate,
|
||||
nickname, domainFull,
|
||||
extraJson) + licenseStr
|
||||
# end of #timeline
|
||||
profileStr += '</div>'
|
||||
|
||||
instanceTitle = \
|
||||
getConfigParam(baseDir, 'instanceTitle')
|
||||
|
@ -985,7 +1014,8 @@ def _htmlProfileShares(actor: str, translate: {},
|
|||
def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
||||
domain: str, port: int, httpPrefix: str,
|
||||
defaultTimeline: str, theme: str,
|
||||
peertubeInstances: []) -> str:
|
||||
peertubeInstances: [],
|
||||
textModeBanner: str) -> str:
|
||||
"""Shows the edit profile screen
|
||||
"""
|
||||
imageFormats = getImageFormats()
|
||||
|
@ -1332,13 +1362,26 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
|||
getConfigParam(baseDir, 'instanceTitle')
|
||||
editProfileForm = htmlHeaderWithExternalStyle(cssFilename, instanceTitle)
|
||||
|
||||
# keyboard navigation
|
||||
userPathStr = '/users/' + nickname
|
||||
userTimalineStr = '/users/' + nickname + '/' + defaultTimeline
|
||||
menuTimeline = \
|
||||
htmlHideFromScreenReader('🏠') + ' ' + \
|
||||
translate['Switch to timeline view']
|
||||
menuProfile = \
|
||||
htmlHideFromScreenReader('👤') + ' ' + \
|
||||
translate['Switch to profile view']
|
||||
navLinks = {
|
||||
menuProfile: userPathStr,
|
||||
menuTimeline: userTimalineStr
|
||||
}
|
||||
editProfileForm += htmlKeyboardNavigation(textModeBanner, navLinks)
|
||||
|
||||
# top banner
|
||||
editProfileForm += \
|
||||
'<a href="/users/' + nickname + '/' + defaultTimeline + '" title="' + \
|
||||
translate['Switch to timeline view'] + '" alt="' + \
|
||||
translate['Switch to timeline view'] + '">\n'
|
||||
'<a href="/users/' + nickname + '/' + defaultTimeline + '">'
|
||||
editProfileForm += '<img loading="lazy" class="timeline-banner" src="' + \
|
||||
'/users/' + nickname + '/' + bannerFile + '" /></a>\n'
|
||||
'/users/' + nickname + '/' + bannerFile + '" alt="" /></a>\n'
|
||||
|
||||
editProfileForm += \
|
||||
'<form enctype="multipart/form-data" method="POST" ' + \
|
||||
|
|
|
@ -23,6 +23,7 @@ from utils import searchBoxPosts
|
|||
from categories import getHashtagCategory
|
||||
from feeds import rss2TagHeader
|
||||
from feeds import rss2TagFooter
|
||||
from webapp_utils import htmlKeyboardNavigation
|
||||
from webapp_utils import getAltPath
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
from webapp_utils import htmlFooter
|
||||
|
@ -317,7 +318,8 @@ def htmlSearchEmojiTextEntry(cssCache: {}, translate: {},
|
|||
|
||||
def htmlSearch(cssCache: {}, translate: {},
|
||||
baseDir: str, path: str, domain: str,
|
||||
defaultTimeline: str, theme: str) -> str:
|
||||
defaultTimeline: str, theme: str,
|
||||
textModeBanner: str) -> str:
|
||||
"""Search called from the timeline icon
|
||||
"""
|
||||
actor = path.replace('/search', '')
|
||||
|
@ -340,10 +342,14 @@ def htmlSearch(cssCache: {}, translate: {},
|
|||
searchBannerFile, searchBannerFilename = \
|
||||
getSearchBannerFile(baseDir, searchNickname, domain, theme)
|
||||
|
||||
textModeBannerStr = htmlKeyboardNavigation(textModeBanner, {})
|
||||
if textModeBannerStr is None:
|
||||
textModeBannerStr = ''
|
||||
|
||||
if os.path.isfile(searchBannerFilename):
|
||||
usersPath = '/users/' + searchNickname
|
||||
followStr += \
|
||||
'<header>\n' + \
|
||||
'<header>\n' + textModeBannerStr + \
|
||||
'<a href="' + usersPath + '/' + defaultTimeline + '" title="' + \
|
||||
translate['Switch to timeline view'] + '" alt="' + \
|
||||
translate['Switch to timeline view'] + '">\n'
|
||||
|
|
|
@ -14,6 +14,8 @@ from utils import isEditor
|
|||
from utils import removeIdEnding
|
||||
from follow import followerApprovalActive
|
||||
from person import isPersonSnoozed
|
||||
from webapp_utils import htmlKeyboardNavigation
|
||||
from webapp_utils import htmlHideFromScreenReader
|
||||
from webapp_utils import htmlPostSeparator
|
||||
from webapp_utils import getBannerFile
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
|
@ -64,7 +66,8 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
moderationActionStr: str,
|
||||
theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the timeline as html
|
||||
"""
|
||||
enableTimingLog = False
|
||||
|
@ -279,14 +282,14 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
if not iconsAsButtons:
|
||||
newPostButtonStr += \
|
||||
'<a class="imageAnchor" href="' + usersPath + \
|
||||
'/newdm"><img loading="lazy" src="/' + \
|
||||
'/newdm?nodropdown"><img loading="lazy" src="/' + \
|
||||
'icons/newpost.png" title="' + \
|
||||
translate['Create a new DM'] + \
|
||||
'" alt="| ' + translate['Create a new DM'] + \
|
||||
'" class="timelineicon"/></a>\n'
|
||||
else:
|
||||
newPostButtonStr += \
|
||||
'<a href="' + usersPath + '/newdm">' + \
|
||||
'<a href="' + usersPath + '/newdm?nodropdown">' + \
|
||||
'<button class="button"><span>' + \
|
||||
translate['Post'] + ' </span></button></a>'
|
||||
elif (boxName == 'tlblogs' or
|
||||
|
@ -309,28 +312,28 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
if not iconsAsButtons:
|
||||
newPostButtonStr += \
|
||||
'<a class="imageAnchor" href="' + usersPath + \
|
||||
'/newevent"><img loading="lazy" src="/' + \
|
||||
'/newevent?nodropdown"><img loading="lazy" src="/' + \
|
||||
'icons/newpost.png" title="' + \
|
||||
translate['Create a new event'] + '" alt="| ' + \
|
||||
translate['Create a new event'] + \
|
||||
'" class="timelineicon"/></a>\n'
|
||||
else:
|
||||
newPostButtonStr += \
|
||||
'<a href="' + usersPath + '/newevent">' + \
|
||||
'<a href="' + usersPath + '/newevent?nodropdown">' + \
|
||||
'<button class="button"><span>' + \
|
||||
translate['Post'] + '</span></button></a>'
|
||||
elif boxName == 'tlshares':
|
||||
if not iconsAsButtons:
|
||||
newPostButtonStr += \
|
||||
'<a class="imageAnchor" href="' + usersPath + \
|
||||
'/newshare"><img loading="lazy" src="/' + \
|
||||
'/newshare?nodropdown"><img loading="lazy" src="/' + \
|
||||
'icons/newpost.png" title="' + \
|
||||
translate['Create a new shared item'] + '" alt="| ' + \
|
||||
translate['Create a new shared item'] + \
|
||||
'" class="timelineicon"/></a>\n'
|
||||
else:
|
||||
newPostButtonStr += \
|
||||
'<a href="' + usersPath + '/newshare">' + \
|
||||
'<a href="' + usersPath + '/newshare?nodropdown">' + \
|
||||
'<button class="button"><span>' + \
|
||||
translate['Post'] + '</span></button></a>'
|
||||
else:
|
||||
|
@ -363,25 +366,74 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
'<button class="button"><span>' + \
|
||||
translate['Post'] + '</span></button></a>'
|
||||
|
||||
# This creates a link to skip to the timeline and change to
|
||||
# profile view when accessed within lynx, but should be
|
||||
# invisible in a graphical web browser
|
||||
tlStr += \
|
||||
'<div class="transparent">' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a href="/users/' + nickname + '">' + \
|
||||
translate['Switch to profile view'] + '</a></label> | ' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a class="skip-main" href="' + usersPath + '/' + boxName + \
|
||||
'#timeline">' + \
|
||||
translate['Skip to timeline'] + '</a></label> | ' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a class="skip-newswire" href="#newswire">' + \
|
||||
translate['Skip to Newswire'] + '</a></label> | ' + \
|
||||
'<label class="transparent">' + \
|
||||
'<a class="skip-links" href="#links">' + \
|
||||
translate['Skip to Links'] + '</a></label>' + \
|
||||
'</div>\n'
|
||||
# keyboard navigation
|
||||
calendarStr = translate['Calendar']
|
||||
if newCalendarEvent:
|
||||
calendarStr = '<strong>' + calendarStr + '</strong>'
|
||||
dmStr = translate['DM']
|
||||
if newDM:
|
||||
dmStr = '<strong>' + dmStr + '</strong>'
|
||||
repliesStr = translate['Replies']
|
||||
if newReply:
|
||||
repliesStr = '<strong>' + repliesStr + '</strong>'
|
||||
sharesStr = translate['Shares']
|
||||
if newShare:
|
||||
sharesStr = '<strong>' + sharesStr + '</strong>'
|
||||
menuProfile = \
|
||||
htmlHideFromScreenReader('👤') + ' ' + \
|
||||
translate['Switch to profile view']
|
||||
menuInbox = \
|
||||
htmlHideFromScreenReader('📥') + ' ' + translate['Inbox']
|
||||
menuOutbox = \
|
||||
htmlHideFromScreenReader('📤') + ' ' + translate['Outbox']
|
||||
menuSearch = \
|
||||
htmlHideFromScreenReader('🔍') + ' ' + \
|
||||
translate['Search and follow']
|
||||
menuCalendar = \
|
||||
htmlHideFromScreenReader('📅') + ' ' + calendarStr
|
||||
menuDM = \
|
||||
htmlHideFromScreenReader('📩') + ' ' + dmStr
|
||||
menuReplies = \
|
||||
htmlHideFromScreenReader('📨') + ' ' + repliesStr
|
||||
menuBookmarks = \
|
||||
htmlHideFromScreenReader('🔖') + ' ' + \
|
||||
translate['Bookmarks']
|
||||
menuShares = \
|
||||
htmlHideFromScreenReader('🤝') + ' ' + sharesStr
|
||||
menuEvents = \
|
||||
htmlHideFromScreenReader('🎫') + ' ' + translate['Events']
|
||||
menuBlogs = \
|
||||
htmlHideFromScreenReader('📝') + ' ' + translate['Blogs']
|
||||
menuNewswire = \
|
||||
htmlHideFromScreenReader('📰') + ' ' + translate['Newswire']
|
||||
menuLinks = \
|
||||
htmlHideFromScreenReader('🔗') + ' ' + translate['Links']
|
||||
menuNewPost = \
|
||||
htmlHideFromScreenReader('➕') + ' ' + \
|
||||
translate['Create a new post']
|
||||
menuModeration = \
|
||||
htmlHideFromScreenReader('⚡️') + ' ' + \
|
||||
translate['Mod']
|
||||
navLinks = {
|
||||
menuProfile: '/users/' + nickname,
|
||||
menuInbox: usersPath + '/inbox#timeline',
|
||||
menuSearch: usersPath + '/search',
|
||||
menuNewPost: usersPath + '/newpost',
|
||||
menuCalendar: usersPath + '/calendar',
|
||||
menuDM: usersPath + '/dm#timeline',
|
||||
menuReplies: usersPath + '/tlreplies#timeline',
|
||||
menuOutbox: usersPath + '/inbox#timeline',
|
||||
menuBookmarks: usersPath + '/tlbookmarks#timeline',
|
||||
menuShares: usersPath + '/tlshares#timeline',
|
||||
menuBlogs: usersPath + '/tlblogs#timeline',
|
||||
menuEvents: usersPath + '/tlevents#timeline',
|
||||
menuNewswire: '#newswire',
|
||||
menuLinks: '#links'
|
||||
}
|
||||
if moderator:
|
||||
navLinks[menuModeration] = usersPath + '/moderation#modtimeline'
|
||||
tlStr += htmlKeyboardNavigation(textModeBanner, navLinks,
|
||||
usersPath, translate, followApprovals)
|
||||
|
||||
# banner and row of buttons
|
||||
tlStr += \
|
||||
|
@ -433,7 +485,6 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
leftColumnStr + ' </td>\n'
|
||||
# center column containing posts
|
||||
tlStr += ' <td valign="top" class="col-center">\n'
|
||||
tlStr += ' <main id="timeline" tabindex="-1">\n'
|
||||
|
||||
if not fullWidthTimelineButtonHeader:
|
||||
tlStr += \
|
||||
|
@ -451,12 +502,12 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
calendarImage, followApprovals,
|
||||
iconsAsButtons)
|
||||
|
||||
tlStr += ' <div class="timeline-posts">\n'
|
||||
tlStr += ' <div id="timeline" class="timeline-posts">\n'
|
||||
|
||||
# second row of buttons for moderator actions
|
||||
if moderator and boxName == 'moderation':
|
||||
tlStr += \
|
||||
'<form method="POST" action="/users/' + \
|
||||
'<form id="modtimeline" method="POST" action="/users/' + \
|
||||
nickname + '/moderationaction">'
|
||||
tlStr += '<div class="container">\n'
|
||||
idx = 'Nickname or URL. Block using *@domain or nickname@domain'
|
||||
|
@ -473,40 +524,57 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Information about current blocks/suspensions'] + \
|
||||
'" name="submitInfo" value="' + translate['Info'] + '">\n'
|
||||
'" alt="' + \
|
||||
translate['Information about current blocks/suspensions'] + \
|
||||
' | " ' + \
|
||||
'name="submitInfo" value="' + translate['Info'] + '">\n'
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Remove the above item'] + \
|
||||
'" name="submitRemove" value="' + \
|
||||
translate['Remove the above item'] + '" ' + \
|
||||
'alt="' + translate['Remove the above item'] + ' | " ' + \
|
||||
'name="submitRemove" value="' + \
|
||||
translate['Remove'] + '">\n'
|
||||
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Suspend the above account nickname'] + \
|
||||
'" name="submitSuspend" value="' + translate['Suspend'] + '">\n'
|
||||
translate['Suspend the above account nickname'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Suspend the above account nickname'] + ' | " ' + \
|
||||
'name="submitSuspend" value="' + translate['Suspend'] + '">\n'
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Remove a suspension for an account nickname'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Remove a suspension for an account nickname'] + \
|
||||
'" name="submitUnsuspend" value="' + \
|
||||
' | " ' + \
|
||||
'name="submitUnsuspend" value="' + \
|
||||
translate['Unsuspend'] + '">\n'
|
||||
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Block an account on another instance'] + \
|
||||
'" name="submitBlock" value="' + translate['Block'] + '">\n'
|
||||
translate['Block an account on another instance'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Block an account on another instance'] + ' | " ' + \
|
||||
'name="submitBlock" value="' + translate['Block'] + '">\n'
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Unblock an account on another instance'] + \
|
||||
'" name="submitUnblock" value="' + translate['Unblock'] + '">\n'
|
||||
translate['Unblock an account on another instance'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Unblock an account on another instance'] + ' | " ' + \
|
||||
'name="submitUnblock" value="' + translate['Unblock'] + '">\n'
|
||||
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Filter out words'] + \
|
||||
'" name="submitFilter" value="' + translate['Filter'] + '">\n'
|
||||
translate['Filter out words'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Filter out words'] + ' | " ' + \
|
||||
'name="submitFilter" value="' + translate['Filter'] + '">\n'
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Unfilter words'] + \
|
||||
'" name="submitUnfilter" value="' + translate['Unfilter'] + '">\n'
|
||||
translate['Unfilter words'] + '" ' + \
|
||||
'alt="' + \
|
||||
translate['Unfilter words'] + ' | " ' + \
|
||||
'name="submitUnfilter" value="' + translate['Unfilter'] + '">\n'
|
||||
|
||||
tlStr += '</div>\n</form>\n'
|
||||
|
||||
|
@ -522,8 +590,14 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
|
||||
_logTimelineTiming(enableTimingLog, timelineStartTime, boxName, '7')
|
||||
|
||||
# separator between posts which only appears in shell browsers
|
||||
# such as Lynx and is not read by screen readers
|
||||
textModeSeparator = \
|
||||
'<div class="transparent"><hr></div>'
|
||||
|
||||
# page up arrow
|
||||
if pageNumber > 1:
|
||||
tlStr += textModeSeparator
|
||||
tlStr += \
|
||||
' <center>\n' + \
|
||||
' <a href="' + usersPath + '/' + boxName + \
|
||||
|
@ -602,7 +676,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
|
||||
if currTlStr:
|
||||
itemCtr += 1
|
||||
tlStr += currTlStr
|
||||
tlStr += textModeSeparator + currTlStr
|
||||
if separatorStr:
|
||||
tlStr += separatorStr
|
||||
if boxName == 'tlmedia':
|
||||
|
@ -610,6 +684,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
|
||||
# page down arrow
|
||||
if itemCtr > 2:
|
||||
tlStr += textModeSeparator
|
||||
tlStr += \
|
||||
' <center>\n' + \
|
||||
' <a href="' + usersPath + '/' + boxName + '?page=' + \
|
||||
|
@ -619,6 +694,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
translate['Page down'] + '" alt="' + \
|
||||
translate['Page down'] + '"></a>\n' + \
|
||||
' </center>\n'
|
||||
tlStr += textModeSeparator
|
||||
|
||||
# end of timeline-posts
|
||||
tlStr += ' </div>\n'
|
||||
|
@ -634,8 +710,8 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
False, None, True,
|
||||
showPublishAsIcon,
|
||||
rssIconAtTop, publishButtonAtTop,
|
||||
authorized, True, theme)
|
||||
tlStr += ' </main>\n'
|
||||
authorized, True, theme,
|
||||
defaultTimeline)
|
||||
tlStr += ' <td valign="top" class="col-right" ' + \
|
||||
'id="newswire" tabindex="-1">' + \
|
||||
rightColumnStr + ' </td>\n'
|
||||
|
@ -752,7 +828,8 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the shares timeline as html
|
||||
"""
|
||||
manuallyApproveFollowers = \
|
||||
|
@ -773,7 +850,7 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInbox(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -794,7 +871,8 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the inbox as html
|
||||
"""
|
||||
manuallyApproveFollowers = \
|
||||
|
@ -815,7 +893,7 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -836,7 +914,8 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the bookmarks as html
|
||||
"""
|
||||
manuallyApproveFollowers = \
|
||||
|
@ -857,7 +936,7 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlEvents(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -878,7 +957,8 @@ def htmlEvents(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the events as html
|
||||
"""
|
||||
manuallyApproveFollowers = \
|
||||
|
@ -899,7 +979,7 @@ def htmlEvents(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -920,7 +1000,8 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the DM timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -936,7 +1017,7 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -957,7 +1038,8 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the replies timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -974,7 +1056,7 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -995,7 +1077,8 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the media timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -1012,7 +1095,7 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1033,7 +1116,8 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the blogs timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -1050,7 +1134,7 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1072,7 +1156,8 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
|||
authorized: bool,
|
||||
theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the features timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -1089,7 +1174,7 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1110,7 +1195,8 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the news timeline as html
|
||||
"""
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
|
@ -1127,7 +1213,7 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
||||
|
||||
def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1148,7 +1234,8 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|||
publishButtonAtTop: bool,
|
||||
authorized: bool, theme: str,
|
||||
peertubeInstances: [],
|
||||
allowLocalNetworkAccess: bool) -> str:
|
||||
allowLocalNetworkAccess: bool,
|
||||
textModeBanner: str) -> str:
|
||||
"""Show the Outbox as html
|
||||
"""
|
||||
manuallyApproveFollowers = \
|
||||
|
@ -1166,4 +1253,4 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
allowLocalNetworkAccess)
|
||||
allowLocalNetworkAccess, textModeBanner)
|
||||
|
|
|
@ -878,3 +878,35 @@ def getAvatarImageUrl(session,
|
|||
avatarUrl = postActor + '/avatar.png'
|
||||
|
||||
return avatarUrl
|
||||
|
||||
|
||||
def htmlHideFromScreenReader(htmlStr: str) -> str:
|
||||
"""Returns html which is hidden from screen readers
|
||||
"""
|
||||
return '<span aria-hidden="true">' + htmlStr + '</span>'
|
||||
|
||||
|
||||
def htmlKeyboardNavigation(banner: str, links: {},
|
||||
usersPath=None, translate=None,
|
||||
followApprovals=False) -> str:
|
||||
"""Given a set of links return the html for keyboard navigation
|
||||
"""
|
||||
htmlStr = '<div class="transparent"><ul>'
|
||||
|
||||
if banner:
|
||||
htmlStr += '<pre aria-label="">' + banner + '<br><br></pre>'
|
||||
|
||||
# show new follower approvals
|
||||
if usersPath and translate and followApprovals:
|
||||
htmlStr += '<strong><label class="transparent">' + \
|
||||
'<a href="' + usersPath + '/followers#timeline">' + \
|
||||
translate['Approve follow requests'] + '</a>' + \
|
||||
'</label></strong><br><br>'
|
||||
|
||||
# show the list of links
|
||||
for title, url in links.items():
|
||||
htmlStr += '<li><label class="transparent">' + \
|
||||
'<a href="' + str(url) + '">' + \
|
||||
str(title) + '</a></label></li>'
|
||||
htmlStr += '</ul></div>'
|
||||
return htmlStr
|
||||
|
|
Loading…
Reference in New Issue