Merge branch 'main' of gitlab.com:bashrc2/epicyon
150
daemon.py
|
@ -154,6 +154,7 @@ from blog import htmlBlogPage
|
|||
from blog import htmlBlogPost
|
||||
from blog import htmlEditBlog
|
||||
from blog import getBlogAddress
|
||||
from webapp_themeDesigner import htmlThemeDesigner
|
||||
from webapp_minimalbutton import setMinimal
|
||||
from webapp_minimalbutton import isMinimal
|
||||
from webapp_utils import getAvatarImageUrl
|
||||
|
@ -316,6 +317,8 @@ from cache import storePersonInCache
|
|||
from cache import getPersonFromCache
|
||||
from cache import getPersonPubKey
|
||||
from httpsig import verifyPostHeaders
|
||||
from theme import resetThemeDesignerSettings
|
||||
from theme import setThemeFromDesigner
|
||||
from theme import scanThemesForScripts
|
||||
from theme import importTheme
|
||||
from theme import exportTheme
|
||||
|
@ -2109,6 +2112,92 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.POSTbusy = False
|
||||
return
|
||||
|
||||
def _themeDesigner(self, path: str,
|
||||
callingDomain: str, cookie: str,
|
||||
baseDir: str, httpPrefix: str, nickname: str,
|
||||
domain: str, domainFull: str, port: int,
|
||||
onionDomain: str, i2pDomain: str,
|
||||
debug: bool, accessKeys: {},
|
||||
defaultTimeline: str, themeName: str,
|
||||
allowLocalNetworkAccess: bool,
|
||||
systemLanguage: str) -> None:
|
||||
"""Receive POST from webapp_themeDesigner
|
||||
"""
|
||||
usersPath = '/users/' + nickname
|
||||
originPathStr = \
|
||||
httpPrefix + '://' + domainFull + usersPath + '/' + defaultTimeline
|
||||
length = int(self.headers['Content-length'])
|
||||
|
||||
try:
|
||||
themeParams = self.rfile.read(length).decode('utf-8')
|
||||
except SocketError as e:
|
||||
if e.errno == errno.ECONNRESET:
|
||||
print('WARN: POST themeParams ' +
|
||||
'connection reset by peer')
|
||||
else:
|
||||
print('WARN: POST themeParams socket error')
|
||||
self.send_response(400)
|
||||
self.end_headers()
|
||||
self.server.POSTbusy = False
|
||||
return
|
||||
except ValueError as e:
|
||||
print('ERROR: POST themeParams rfile.read failed, ' + str(e))
|
||||
self.send_response(400)
|
||||
self.end_headers()
|
||||
self.server.POSTbusy = False
|
||||
return
|
||||
themeParams = \
|
||||
urllib.parse.unquote_plus(themeParams)
|
||||
|
||||
# theme designer screen, reset button
|
||||
# See htmlThemeDesigner
|
||||
if 'submitThemeDesignerReset=' in themeParams or \
|
||||
'submitThemeDesigner=' not in themeParams:
|
||||
if 'submitThemeDesignerReset=' in themeParams:
|
||||
resetThemeDesignerSettings(baseDir, themeName, domain,
|
||||
allowLocalNetworkAccess,
|
||||
systemLanguage)
|
||||
|
||||
if callingDomain.endswith('.onion') and onionDomain:
|
||||
originPathStr = \
|
||||
'http://' + onionDomain + usersPath + '/' + defaultTimeline
|
||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
||||
originPathStr = \
|
||||
'http://' + i2pDomain + usersPath + '/' + defaultTimeline
|
||||
self._redirect_headers(originPathStr, cookie, callingDomain)
|
||||
self.server.POSTbusy = False
|
||||
return
|
||||
|
||||
fields = {}
|
||||
fieldsList = themeParams.split('&')
|
||||
for fieldStr in fieldsList:
|
||||
if '=' not in fieldStr:
|
||||
continue
|
||||
fields[fieldStr.split('=')[0]] = fieldStr.split('=')[1].strip()
|
||||
|
||||
# get the parameters from the theme designer screen
|
||||
themeDesignerParams = {}
|
||||
for variableName, key in fields.items():
|
||||
if variableName.startswith('themeSetting_'):
|
||||
variableName = variableName.replace('themeSetting_', '')
|
||||
themeDesignerParams[variableName] = key
|
||||
|
||||
setThemeFromDesigner(baseDir, themeName, domain,
|
||||
themeDesignerParams,
|
||||
allowLocalNetworkAccess,
|
||||
systemLanguage)
|
||||
|
||||
# redirect back from theme designer screen
|
||||
if callingDomain.endswith('.onion') and onionDomain:
|
||||
originPathStr = \
|
||||
'http://' + onionDomain + usersPath + '/' + defaultTimeline
|
||||
elif callingDomain.endswith('.i2p') and i2pDomain:
|
||||
originPathStr = \
|
||||
'http://' + i2pDomain + usersPath + '/' + defaultTimeline
|
||||
self._redirect_headers(originPathStr, cookie, callingDomain)
|
||||
self.server.POSTbusy = False
|
||||
return
|
||||
|
||||
def _personOptions(self, path: str,
|
||||
callingDomain: str, cookie: str,
|
||||
baseDir: str, httpPrefix: str,
|
||||
|
@ -10849,6 +10938,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
currNickname = currNickname.split('/')[0]
|
||||
moderator = isModerator(baseDir, currNickname)
|
||||
editor = isEditor(baseDir, currNickname)
|
||||
artist = isArtist(baseDir, currNickname)
|
||||
fullWidthTimelineButtonHeader = \
|
||||
self.server.fullWidthTimelineButtonHeader
|
||||
minimalNick = isMinimal(baseDir, domain, nickname)
|
||||
|
@ -10881,7 +10971,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.twitterReplacementDomain,
|
||||
self.server.showPublishedDateOnly,
|
||||
self.server.newswire,
|
||||
moderator, editor,
|
||||
moderator, editor, artist,
|
||||
self.server.positiveVoting,
|
||||
self.server.showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
|
@ -14363,6 +14453,33 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.debug)
|
||||
return
|
||||
|
||||
if htmlGET and usersInPath and authorized and \
|
||||
self.path.endswith('/themedesigner'):
|
||||
nickname = self.path.split('/users/')[1]
|
||||
if '/' in nickname:
|
||||
nickname = nickname.split('/')[0]
|
||||
|
||||
if not isArtist(self.server.baseDir, nickname):
|
||||
self._403()
|
||||
return
|
||||
|
||||
msg = \
|
||||
htmlThemeDesigner(self.server.cssCache,
|
||||
self.server.baseDir,
|
||||
nickname, self.server.domain,
|
||||
self.server.translate,
|
||||
self.server.defaultTimeline,
|
||||
self.server.themeName,
|
||||
self.server.accessKeys)
|
||||
msg = msg.encode('utf-8')
|
||||
msglen = len(msg)
|
||||
self._login_headers('text/html', msglen, callingDomain)
|
||||
self._write(msg)
|
||||
fitnessPerformance(GETstartTime, self.server.fitness,
|
||||
'_GET', 'show theme designer screen',
|
||||
self.server.debug)
|
||||
return
|
||||
|
||||
fitnessPerformance(GETstartTime, self.server.fitness,
|
||||
'_GET', 'show about screen done',
|
||||
self.server.debug)
|
||||
|
@ -17728,6 +17845,36 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.defaultTimeline)
|
||||
return
|
||||
|
||||
# theme designer submit/cancel button
|
||||
if usersInPath and \
|
||||
self.path.endswith('/changeThemeSettings'):
|
||||
nickname = self.path.split('/users/')[1]
|
||||
if '/' in nickname:
|
||||
nickname = nickname.split('/')[0]
|
||||
|
||||
if not self.server.keyShortcuts.get(nickname):
|
||||
accessKeys = self.server.accessKeys
|
||||
self.server.keyShortcuts[nickname] = accessKeys.copy()
|
||||
accessKeys = self.server.keyShortcuts[nickname]
|
||||
|
||||
self._themeDesigner(self.path,
|
||||
callingDomain, cookie,
|
||||
self.server.baseDir,
|
||||
self.server.httpPrefix,
|
||||
nickname,
|
||||
self.server.domain,
|
||||
self.server.domainFull,
|
||||
self.server.port,
|
||||
self.server.onionDomain,
|
||||
self.server.i2pDomain,
|
||||
self.server.debug,
|
||||
accessKeys,
|
||||
self.server.defaultTimeline,
|
||||
self.server.themeName,
|
||||
self.server.allowLocalNetworkAccess,
|
||||
self.server.systemLanguage)
|
||||
return
|
||||
|
||||
# update the shared item federation token for the calling domain
|
||||
# if it is within the permitted federation
|
||||
if self.headers.get('Origin') and \
|
||||
|
@ -18330,6 +18477,7 @@ def runDaemon(contentLicenseUrl: str,
|
|||
'enterNotes': 'n',
|
||||
'menuTimeline': 't',
|
||||
'menuEdit': 'e',
|
||||
'menuThemeDesigner': 'z',
|
||||
'menuProfile': 'p',
|
||||
'menuInbox': 'i',
|
||||
'menuSearch': '/',
|
||||
|
|
4
posts.py
|
@ -2160,8 +2160,8 @@ def threadSendPost(session, postJsonStr: str, federationList: [],
|
|||
except Exception as e:
|
||||
print('ERROR: postJsonString failed ' + str(e))
|
||||
if unauthorized:
|
||||
print(postJsonStr)
|
||||
print('threadSendPost: Post is unauthorized')
|
||||
print('WARN: threadSendPost: Post is unauthorized ' +
|
||||
inboxUrl + ' ' + postJsonStr)
|
||||
break
|
||||
if postResult:
|
||||
logStr = 'Success on try ' + str(tries) + ': ' + postJsonStr
|
||||
|
|
45
theme.py
|
@ -492,6 +492,31 @@ def _setCustomFont(baseDir: str):
|
|||
cssfile.write(css)
|
||||
|
||||
|
||||
def setThemeFromDesigner(baseDir: str, themeName: str, domain: str,
|
||||
themeParams: {},
|
||||
allowLocalNetworkAccess: bool,
|
||||
systemLanguage: str):
|
||||
customThemeFilename = baseDir + '/accounts/theme.json'
|
||||
saveJson(themeParams, customThemeFilename)
|
||||
setTheme(baseDir, themeName, domain,
|
||||
allowLocalNetworkAccess, systemLanguage)
|
||||
|
||||
|
||||
def resetThemeDesignerSettings(baseDir: str, themeName: str, domain: str,
|
||||
allowLocalNetworkAccess: bool,
|
||||
systemLanguage: str) -> None:
|
||||
"""Resets the theme designer settings
|
||||
"""
|
||||
customVariablesFile = baseDir + '/accounts/theme.json'
|
||||
if os.path.isfile(customVariablesFile):
|
||||
try:
|
||||
os.remove(customVariablesFile)
|
||||
except OSError:
|
||||
print('EX: unable to remove theme designer settings on reset')
|
||||
setTheme(baseDir, themeName, domain,
|
||||
allowLocalNetworkAccess, systemLanguage)
|
||||
|
||||
|
||||
def _readVariablesFile(baseDir: str, themeName: str,
|
||||
variablesFile: str,
|
||||
allowLocalNetworkAccess: bool) -> None:
|
||||
|
@ -500,6 +525,15 @@ def _readVariablesFile(baseDir: str, themeName: str,
|
|||
themeParams = loadJson(variablesFile, 0)
|
||||
if not themeParams:
|
||||
return
|
||||
|
||||
# set custom theme parameters
|
||||
customVariablesFile = baseDir + '/accounts/theme.json'
|
||||
if os.path.isfile(customVariablesFile):
|
||||
customThemeParams = loadJson(customVariablesFile, 0)
|
||||
if customThemeParams:
|
||||
for variableName, value in customThemeParams.items():
|
||||
themeParams[variableName] = value
|
||||
|
||||
bgParams = {
|
||||
"login": "jpg",
|
||||
"follow": "jpg",
|
||||
|
@ -789,6 +823,17 @@ def setTheme(baseDir: str, name: str, domain: str,
|
|||
result = False
|
||||
|
||||
prevThemeName = getTheme(baseDir)
|
||||
|
||||
# if the theme has changed then remove any custom settings
|
||||
if prevThemeName != name:
|
||||
customVariablesFile = baseDir + '/accounts/theme.json'
|
||||
if os.path.isfile(customVariablesFile):
|
||||
print('Removing theme designer settings')
|
||||
try:
|
||||
os.remove(customVariablesFile)
|
||||
except OSError:
|
||||
print('EX: removing theme designer settings')
|
||||
|
||||
_removeTheme(baseDir)
|
||||
|
||||
themes = getThemesList(baseDir)
|
||||
|
|
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 7.7 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 9.7 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.4 KiB |
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "حدد رد الفعل",
|
||||
"Don't show the Reaction button": "لا تظهر زر رد الفعل",
|
||||
"New feed URL": "موجز جديد URL",
|
||||
"New link title and URL": "عنوان الارتباط الجديد وعنوان URL"
|
||||
"New link title and URL": "عنوان الارتباط الجديد وعنوان URL",
|
||||
"Theme Designer": "مصمم المظهر",
|
||||
"Reset": "إعادة ضبط"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Seleccioneu la reacció",
|
||||
"Don't show the Reaction button": "No mostris el botó de reacció",
|
||||
"New feed URL": "URL de feed nou",
|
||||
"New link title and URL": "Títol i URL de l'enllaç nous"
|
||||
"New link title and URL": "Títol i URL de l'enllaç nous",
|
||||
"Theme Designer": "Dissenyador temàtic",
|
||||
"Reset": "Restableix"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Dewiswch adwaith",
|
||||
"Don't show the Reaction button": "Peidiwch â dangos y botwm Adwaith",
|
||||
"New feed URL": "URL porthiant newydd",
|
||||
"New link title and URL": "Teitl dolen ac URL newydd"
|
||||
"New link title and URL": "Teitl dolen ac URL newydd",
|
||||
"Theme Designer": "Dylunydd Thema",
|
||||
"Reset": "Ail gychwyn"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Reaktion auswählen",
|
||||
"Don't show the Reaction button": "Reaktionstaste nicht anzeigen",
|
||||
"New feed URL": "Neue Feed-URL",
|
||||
"New link title and URL": "Neuer Linktitel und URL"
|
||||
"New link title and URL": "Neuer Linktitel und URL",
|
||||
"Theme Designer": "Themendesigner",
|
||||
"Reset": "Zurücksetzen"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Select reaction",
|
||||
"Don't show the Reaction button": "Don't show the Reaction button",
|
||||
"New feed URL": "New feed URL",
|
||||
"New link title and URL": "New link title and URL"
|
||||
"New link title and URL": "New link title and URL",
|
||||
"Theme Designer": "Theme Designer",
|
||||
"Reset": "Reset"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Seleccionar reacción",
|
||||
"Don't show the Reaction button": "No mostrar el botón de reacción",
|
||||
"New feed URL": "URL de nuevo feed",
|
||||
"New link title and URL": "Nuevo título de enlace y URL"
|
||||
"New link title and URL": "Nuevo título de enlace y URL",
|
||||
"Theme Designer": "Diseñadora de temas",
|
||||
"Reset": "Reiniciar"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Sélectionnez la réaction",
|
||||
"Don't show the Reaction button": "Ne pas afficher le bouton Réaction",
|
||||
"New feed URL": "Nouvelle URL de flux",
|
||||
"New link title and URL": "Nouveau titre et URL du lien"
|
||||
"New link title and URL": "Nouveau titre et URL du lien",
|
||||
"Theme Designer": "Concepteur de thème",
|
||||
"Reset": "Réinitialiser"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Roghnaigh imoibriú",
|
||||
"Don't show the Reaction button": "Ná taispeáin an cnaipe Imoibriú",
|
||||
"New feed URL": "URL beathaithe nua",
|
||||
"New link title and URL": "Teideal nasc nua agus URL"
|
||||
"New link title and URL": "Teideal nasc nua agus URL",
|
||||
"Theme Designer": "Dearthóir Téama",
|
||||
"Reset": "Athshocraigh"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "प्रतिक्रिया का चयन करें",
|
||||
"Don't show the Reaction button": "प्रतिक्रिया बटन न दिखाएं",
|
||||
"New feed URL": "नया फ़ीड URL",
|
||||
"New link title and URL": "नया लिंक शीर्षक और URL"
|
||||
"New link title and URL": "नया लिंक शीर्षक और URL",
|
||||
"Theme Designer": "थीम डिजाइनर",
|
||||
"Reset": "रीसेट"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Seleziona reazione",
|
||||
"Don't show the Reaction button": "Non mostrare il pulsante Reazione",
|
||||
"New feed URL": "Nuovo URL del feed",
|
||||
"New link title and URL": "Nuovo titolo e URL del collegamento"
|
||||
"New link title and URL": "Nuovo titolo e URL del collegamento",
|
||||
"Theme Designer": "Progettista di temi",
|
||||
"Reset": "Ripristina"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "反応を選択",
|
||||
"Don't show the Reaction button": "反応ボタンを表示しない",
|
||||
"New feed URL": "新しいフィードURL",
|
||||
"New link title and URL": "新しいリンクのタイトルとURL"
|
||||
"New link title and URL": "新しいリンクのタイトルとURL",
|
||||
"Theme Designer": "テーマデザイナー",
|
||||
"Reset": "リセット"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Reaksiyonê hilbijêrin",
|
||||
"Don't show the Reaction button": "Bişkoka Reaksiyonê nîşan nede",
|
||||
"New feed URL": "URL-ya feed nû",
|
||||
"New link title and URL": "Sernav û URL-ya girêdana nû"
|
||||
"New link title and URL": "Sernav û URL-ya girêdana nû",
|
||||
"Theme Designer": "Theme Designer",
|
||||
"Reset": "Reset"
|
||||
}
|
||||
|
|
|
@ -494,5 +494,7 @@
|
|||
"Select reaction": "Select reaction",
|
||||
"Don't show the Reaction button": "Don't show the Reaction button",
|
||||
"New feed URL": "New feed URL",
|
||||
"New link title and URL": "New link title and URL"
|
||||
"New link title and URL": "New link title and URL",
|
||||
"Theme Designer": "Theme Designer",
|
||||
"Reset": "Reset"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Selecione a reação",
|
||||
"Don't show the Reaction button": "Não mostrar o botão de reação",
|
||||
"New feed URL": "Novo URL de feed",
|
||||
"New link title and URL": "Novo título e URL do link"
|
||||
"New link title and URL": "Novo título e URL do link",
|
||||
"Theme Designer": "Designer de Tema",
|
||||
"Reset": "Redefinir"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Выберите реакцию",
|
||||
"Don't show the Reaction button": "Не показывать кнопку реакции",
|
||||
"New feed URL": "URL нового канала",
|
||||
"New link title and URL": "Новое название ссылки и URL"
|
||||
"New link title and URL": "Новое название ссылки и URL",
|
||||
"Theme Designer": "Дизайнер тем",
|
||||
"Reset": "Сброс настроек"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "Chagua majibu",
|
||||
"Don't show the Reaction button": "Usionyeshe kitufe cha Majibu",
|
||||
"New feed URL": "URL mpya ya mipasho",
|
||||
"New link title and URL": "Kichwa kipya cha kiungo na URL"
|
||||
"New link title and URL": "Kichwa kipya cha kiungo na URL",
|
||||
"Theme Designer": "Mbuni wa Mandhari",
|
||||
"Reset": "Weka upya"
|
||||
}
|
||||
|
|
|
@ -498,5 +498,7 @@
|
|||
"Select reaction": "选择反应",
|
||||
"Don't show the Reaction button": "不显示“反应”按钮",
|
||||
"New feed URL": "新供稿网址",
|
||||
"New link title and URL": "新链接标题和 URL"
|
||||
"New link title and URL": "新链接标题和 URL",
|
||||
"Theme Designer": "主题设计师",
|
||||
"Reset": "重启"
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import os
|
|||
from utils import getConfigParam
|
||||
from utils import getNicknameFromActor
|
||||
from utils import isEditor
|
||||
from utils import isArtist
|
||||
from utils import removeDomainPort
|
||||
from utils import localActorUrl
|
||||
from webapp_utils import sharesTimelineJson
|
||||
|
@ -113,7 +114,7 @@ def _getLeftColumnWanted(baseDir: str,
|
|||
|
||||
def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
|
||||
httpPrefix: str, translate: {},
|
||||
editor: bool,
|
||||
editor: bool, artist: bool,
|
||||
showBackButton: bool, timelinePath: str,
|
||||
rssIconAtTop: bool, showHeaderImage: bool,
|
||||
frontPage: bool, theme: str,
|
||||
|
@ -154,6 +155,7 @@ def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
htmlStr += '\n <center>\n'
|
||||
|
||||
htmlStr += ' <div class="leftColIcons">\n'
|
||||
|
||||
if editor:
|
||||
# show the edit icon
|
||||
htmlStr += \
|
||||
|
@ -163,6 +165,15 @@ def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
translate['Edit Links'] + ' | " title="' + \
|
||||
translate['Edit Links'] + '" src="/icons/edit.png" /></a>\n'
|
||||
|
||||
if artist:
|
||||
# show the theme designer icon
|
||||
htmlStr += \
|
||||
' <a href="/users/' + nickname + '/themedesigner" ' + \
|
||||
'accesskey="' + accessKeys['menuThemeDesigner'] + '">' + \
|
||||
'<img class="' + editImageClass + '" loading="lazy" alt="' + \
|
||||
translate['Theme Designer'] + ' | " title="' + \
|
||||
translate['Theme Designer'] + '" src="/icons/theme.png" /></a>\n'
|
||||
|
||||
# RSS icon
|
||||
if nickname != 'news':
|
||||
# rss feed for this account
|
||||
|
@ -358,8 +369,10 @@ def htmlLinksMobile(cssCache: {}, baseDir: str,
|
|||
# is the user a site editor?
|
||||
if nickname == 'news':
|
||||
editor = False
|
||||
artist = False
|
||||
else:
|
||||
editor = isEditor(baseDir, nickname)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
|
||||
domain = removeDomainPort(domainFull)
|
||||
|
||||
|
@ -383,7 +396,7 @@ def htmlLinksMobile(cssCache: {}, baseDir: str,
|
|||
htmlStr += \
|
||||
getLeftColumnContent(baseDir, nickname, domainFull,
|
||||
httpPrefix, translate,
|
||||
editor,
|
||||
editor, artist,
|
||||
False, timelinePath,
|
||||
rssIconAtTop, False, False,
|
||||
theme, accessKeys,
|
||||
|
|
|
@ -155,7 +155,8 @@ def htmlFrontScreen(signingPrivateKeyPem: str,
|
|||
profileHeaderStr += \
|
||||
getLeftColumnContent(baseDir, 'news', domainFull,
|
||||
httpPrefix, translate,
|
||||
False, False, None, rssIconAtTop, True,
|
||||
False, False,
|
||||
False, None, rssIconAtTop, True,
|
||||
True, theme, accessKeys,
|
||||
sharedItemsFederatedDomains)
|
||||
profileHeaderStr += \
|
||||
|
|
|
@ -8,6 +8,7 @@ __status__ = "Production"
|
|||
__module_group__ = "Moderation"
|
||||
|
||||
import os
|
||||
from utils import isArtist
|
||||
from utils import isAccountDir
|
||||
from utils import getFullDomain
|
||||
from utils import isEditor
|
||||
|
@ -57,6 +58,7 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
"""Show the moderation feed as html
|
||||
This is what you see when selecting the "mod" timeline
|
||||
"""
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -66,7 +68,7 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False, positiveVoting,
|
||||
newswire, False, False, artist, positiveVoting,
|
||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, moderationActionStr, theme,
|
||||
|
|
|
@ -878,6 +878,10 @@ def htmlProfile(signingPrivateKeyPem: str,
|
|||
menuSkills: userPathStr + '/skills#timeline',
|
||||
menuLogout: '/logout'
|
||||
}
|
||||
if isArtist(baseDir, nickname):
|
||||
menuThemeDesigner = \
|
||||
htmlHideFromScreenReader('🎨') + ' ' + translate['Theme Designer']
|
||||
navLinks[menuThemeDesigner] = userPathStr + '/themedesigner'
|
||||
navAccessKeys = {}
|
||||
for variableName, key in accessKeys.items():
|
||||
if not locals().get(variableName):
|
||||
|
|
|
@ -0,0 +1,262 @@
|
|||
__filename__ = "webapp_themeDesigner.py"
|
||||
__author__ = "Bob Mottram"
|
||||
__license__ = "AGPL3+"
|
||||
__version__ = "1.2.0"
|
||||
__maintainer__ = "Bob Mottram"
|
||||
__email__ = "bob@libreserver.org"
|
||||
__status__ = "Production"
|
||||
__module_group__ = "Web Interface"
|
||||
|
||||
import os
|
||||
from utils import loadJson
|
||||
from utils import getConfigParam
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
from webapp_utils import htmlFooter
|
||||
from webapp_utils import getBannerFile
|
||||
|
||||
|
||||
color_to_hex = {
|
||||
"aliceblue": "#f0f8ff",
|
||||
"antiquewhite": "#faebd7",
|
||||
"aqua": "#00ffff",
|
||||
"aquamarine": "#7fffd4",
|
||||
"azure": "#f0ffff",
|
||||
"beige": "#f5f5dc",
|
||||
"bisque": "#ffe4c4",
|
||||
"black": "#000000",
|
||||
"blanchedalmond": "#ffebcd",
|
||||
"blue": "#0000ff",
|
||||
"blueviolet": "#8a2be2",
|
||||
"brown": "#a52a2a",
|
||||
"burlywood": "#deb887",
|
||||
"cadetblue": "#5f9ea0",
|
||||
"chartreuse": "#7fff00",
|
||||
"chocolate": "#d2691e",
|
||||
"coral": "#ff7f50",
|
||||
"cornflowerblue": "#6495ed",
|
||||
"cornsilk": "#fff8dc",
|
||||
"crimson": "#dc143c",
|
||||
"cyan": "#00ffff",
|
||||
"darkblue": "#00008b",
|
||||
"darkcyan": "#008b8b",
|
||||
"darkgoldenrod": "#b8860b",
|
||||
"darkgray": "#a9a9a9",
|
||||
"darkgrey": "#a9a9a9",
|
||||
"darkgreen": "#006400",
|
||||
"darkkhaki": "#bdb76b",
|
||||
"darkmagenta": "#8b008b",
|
||||
"darkolivegreen": "#556b2f",
|
||||
"darkorange": "#ff8c00",
|
||||
"darkorchid": "#9932cc",
|
||||
"darkred": "#8b0000",
|
||||
"darksalmon": "#e9967a",
|
||||
"darkseagreen": "#8fbc8f",
|
||||
"darkslateblue": "#483d8b",
|
||||
"darkslategray": "#2f4f4f",
|
||||
"darkslategrey": "#2f4f4f",
|
||||
"darkturquoise": "#00ced1",
|
||||
"darkviolet": "#9400d3",
|
||||
"deeppink": "#ff1493",
|
||||
"deepskyblue": "#00bfff",
|
||||
"dimgray": "#696969",
|
||||
"dimgrey": "#696969",
|
||||
"dodgerblue": "#1e90ff",
|
||||
"firebrick": "#b22222",
|
||||
"floralwhite": "#fffaf0",
|
||||
"forestgreen": "#228b22",
|
||||
"fuchsia": "#ff00ff",
|
||||
"gainsboro": "#dcdcdc",
|
||||
"ghostwhite": "#f8f8ff",
|
||||
"gold": "#ffd700",
|
||||
"goldenrod": "#daa520",
|
||||
"gray": "#808080",
|
||||
"grey": "#808080",
|
||||
"green": "#008000",
|
||||
"greenyellow": "#adff2f",
|
||||
"honeydew": "#f0fff0",
|
||||
"hotpink": "#ff69b4",
|
||||
"indianred": "#cd5c5c",
|
||||
"indigo": "#4b0082",
|
||||
"ivory": "#fffff0",
|
||||
"khaki": "#f0e68c",
|
||||
"lavender": "#e6e6fa",
|
||||
"lavenderblush": "#fff0f5",
|
||||
"lawngreen": "#7cfc00",
|
||||
"lemonchiffon": "#fffacd",
|
||||
"lightblue": "#add8e6",
|
||||
"lightcoral": "#f08080",
|
||||
"lightcyan": "#e0ffff",
|
||||
"lightgoldenrodyellow": "#fafad2",
|
||||
"lightgray": "#d3d3d3",
|
||||
"lightgrey": "#d3d3d3",
|
||||
"lightgreen": "#90ee90",
|
||||
"lightpink": "#ffb6c1",
|
||||
"lightsalmon": "#ffa07a",
|
||||
"lightseagreen": "#20b2aa",
|
||||
"lightskyblue": "#87cefa",
|
||||
"lightslategray": "#778899",
|
||||
"lightslategrey": "#778899",
|
||||
"lightsteelblue": "#b0c4de",
|
||||
"lightyellow": "#ffffe0",
|
||||
"lime": "#00ff00",
|
||||
"limegreen": "#32cd32",
|
||||
"linen": "#faf0e6",
|
||||
"magenta": "#ff00ff",
|
||||
"maroon": "#800000",
|
||||
"mediumaquamarine": "#66cdaa",
|
||||
"mediumblue": "#0000cd",
|
||||
"mediumorchid": "#ba55d3",
|
||||
"mediumpurple": "#9370db",
|
||||
"mediumseagreen": "#3cb371",
|
||||
"mediumslateblue": "#7b68ee",
|
||||
"mediumspringgreen": "#00fa9a",
|
||||
"mediumturquoise": "#48d1cc",
|
||||
"mediumvioletred": "#c71585",
|
||||
"midnightblue": "#191970",
|
||||
"mintcream": "#f5fffa",
|
||||
"mistyrose": "#ffe4e1",
|
||||
"moccasin": "#ffe4b5",
|
||||
"navajowhite": "#ffdead",
|
||||
"navy": "#000080",
|
||||
"oldlace": "#fdf5e6",
|
||||
"olive": "#808000",
|
||||
"olivedrab": "#6b8e23",
|
||||
"orange": "#ffa500",
|
||||
"orangered": "#ff4500",
|
||||
"orchid": "#da70d6",
|
||||
"palegoldenrod": "#eee8aa",
|
||||
"palegreen": "#98fb98",
|
||||
"paleturquoise": "#afeeee",
|
||||
"palevioletred": "#db7093",
|
||||
"papayawhip": "#ffefd5",
|
||||
"peachpuff": "#ffdab9",
|
||||
"peru": "#cd853f",
|
||||
"pink": "#ffc0cb",
|
||||
"plum": "#dda0dd",
|
||||
"powderblue": "#b0e0e6",
|
||||
"purple": "#800080",
|
||||
"red": "#ff0000",
|
||||
"rosybrown": "#bc8f8f",
|
||||
"royalblue": "#4169e1",
|
||||
"saddlebrown": "#8b4513",
|
||||
"salmon": "#fa8072",
|
||||
"sandybrown": "#f4a460",
|
||||
"seagreen": "#2e8b57",
|
||||
"seashell": "#fff5ee",
|
||||
"sienna": "#a0522d",
|
||||
"silver": "#c0c0c0",
|
||||
"skyblue": "#87ceeb",
|
||||
"slateblue": "#6a5acd",
|
||||
"slategray": "#708090",
|
||||
"slategrey": "#708090",
|
||||
"snow": "#fffafa",
|
||||
"springgreen": "#00ff7f",
|
||||
"steelblue": "#4682b4",
|
||||
"tan": "#d2b48c",
|
||||
"teal": "#008080",
|
||||
"thistle": "#d8bfd8",
|
||||
"tomato": "#ff6347",
|
||||
"turquoise": "#40e0d0",
|
||||
"violet": "#ee82ee",
|
||||
"wheat": "#f5deb3",
|
||||
"white": "#ffffff",
|
||||
"whitesmoke": "#f5f5f5",
|
||||
"yellow": "#ffff00",
|
||||
"yellowgreen": "#9acd32",
|
||||
}
|
||||
|
||||
|
||||
def htmlThemeDesigner(cssCache: {}, baseDir: str,
|
||||
nickname: str, domain: str,
|
||||
translate: {}, defaultTimeline: str,
|
||||
themeName: str, accessKeys: {}) -> str:
|
||||
"""Edit theme settings
|
||||
"""
|
||||
themeFilename = baseDir + '/theme/' + themeName + '/theme.json'
|
||||
themeJson = {}
|
||||
if os.path.isfile(themeFilename):
|
||||
themeJson = loadJson(themeFilename)
|
||||
|
||||
# set custom theme parameters
|
||||
customVariablesFile = baseDir + '/accounts/theme.json'
|
||||
if os.path.isfile(customVariablesFile):
|
||||
customThemeParams = loadJson(customVariablesFile, 0)
|
||||
if customThemeParams:
|
||||
for variableName, value in customThemeParams.items():
|
||||
themeJson[variableName] = value
|
||||
|
||||
themeForm = ''
|
||||
cssFilename = baseDir + '/epicyon-profile.css'
|
||||
if os.path.isfile(baseDir + '/epicyon.css'):
|
||||
cssFilename = baseDir + '/epicyon.css'
|
||||
|
||||
instanceTitle = \
|
||||
getConfigParam(baseDir, 'instanceTitle')
|
||||
themeForm = \
|
||||
htmlHeaderWithExternalStyle(cssFilename, instanceTitle, None)
|
||||
bannerFile, bannerFilename = \
|
||||
getBannerFile(baseDir, nickname, domain, themeName)
|
||||
themeForm += \
|
||||
'<a href="/users/' + nickname + '/' + defaultTimeline + '" ' + \
|
||||
'accesskey="' + accessKeys['menuTimeline'] + '">' + \
|
||||
'<img loading="lazy" class="timeline-banner" ' + \
|
||||
'title="' + translate['Switch to timeline view'] + '" ' + \
|
||||
'alt="' + translate['Switch to timeline view'] + '" ' + \
|
||||
'src="/users/' + nickname + '/' + bannerFile + '" /></a>\n'
|
||||
themeForm += '<div class="container">\n'
|
||||
|
||||
themeForm += \
|
||||
' <h1>' + translate['Theme Designer'] + '</h1>\n'
|
||||
|
||||
themeForm += ' <form method="POST" action="' + \
|
||||
'/users/' + nickname + '/changeThemeSettings">\n'
|
||||
|
||||
resetKey = accessKeys['menuLogout']
|
||||
submitKey = accessKeys['submitButton']
|
||||
themeForm += \
|
||||
' <center>\n' + \
|
||||
' <button type="submit" class="button" ' + \
|
||||
'name="submitThemeDesignerReset" ' + \
|
||||
'accesskey="' + resetKey + '">' + \
|
||||
translate['Reset'] + '</button>\n' + \
|
||||
' <button type="submit" class="button" ' + \
|
||||
'name="submitThemeDesigner" accesskey="' + submitKey + '">' + \
|
||||
translate['Submit'] + '</button>\n </center>\n'
|
||||
|
||||
themeForm += ' <table class="accesskeys">\n'
|
||||
themeForm += ' <colgroup>\n'
|
||||
themeForm += ' <col span="1" class="accesskeys-left">\n'
|
||||
themeForm += ' <col span="1" class="accesskeys-center">\n'
|
||||
themeForm += ' </colgroup>\n'
|
||||
themeForm += ' <tbody>\n'
|
||||
|
||||
for variableName, value in themeJson.items():
|
||||
# only use colors defined as hex
|
||||
if not value.startswith('#'):
|
||||
if color_to_hex.get(value):
|
||||
value = color_to_hex[value]
|
||||
else:
|
||||
continue
|
||||
if variableName.endswith('-color') or \
|
||||
variableName.endswith('-text'):
|
||||
variableNameStr = variableName.replace('-', ' ')
|
||||
if variableNameStr.endswith(' color'):
|
||||
variableNameStr = variableNameStr.replace(' color', '')
|
||||
if variableNameStr.endswith(' bg'):
|
||||
variableNameStr = variableNameStr.replace(' bg', ' background')
|
||||
elif variableNameStr.endswith(' fg'):
|
||||
variableNameStr = variableNameStr.replace(' fg', ' foreground')
|
||||
variableNameStr = variableNameStr.title()
|
||||
themeForm += \
|
||||
' <tr><td><label class="labels">' + \
|
||||
variableNameStr + '</label></td>'
|
||||
themeForm += \
|
||||
'<td><input type="color" name="themeSetting_' + \
|
||||
variableName + '" value="' + str(value) + \
|
||||
'" title="' + variableNameStr + '"></p></td></tr>\n'
|
||||
|
||||
themeForm += ' </table>\n'
|
||||
themeForm += ' </form>\n'
|
||||
themeForm += '</div>\n'
|
||||
themeForm += htmlFooter()
|
||||
return themeForm
|
|
@ -10,6 +10,7 @@ __module_group__ = "Timeline"
|
|||
import os
|
||||
import time
|
||||
from shutil import copyfile
|
||||
from utils import isArtist
|
||||
from utils import dangerousMarkup
|
||||
from utils import getConfigParam
|
||||
from utils import getFullDomain
|
||||
|
@ -430,7 +431,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
twitterReplacementDomain: str,
|
||||
showPublishedDateOnly: bool,
|
||||
newswire: {}, moderator: bool,
|
||||
editor: bool,
|
||||
editor: bool, artist: bool,
|
||||
positiveVoting: bool,
|
||||
showPublishAsIcon: bool,
|
||||
fullWidthTimelineButtonHeader: bool,
|
||||
|
@ -744,7 +745,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
leftColumnStr = \
|
||||
getLeftColumnContent(baseDir, nickname, domainFull,
|
||||
httpPrefix, translate,
|
||||
editor, False, None, rssIconAtTop,
|
||||
editor, artist, False, None, rssIconAtTop,
|
||||
True, False, theme, accessKeys,
|
||||
sharedItemsFederatedDomains)
|
||||
tlStr += ' <td valign="top" class="col-left" ' + \
|
||||
|
@ -1146,6 +1147,7 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
|||
"""
|
||||
manuallyApproveFollowers = \
|
||||
followerApprovalActive(baseDir, nickname, domain)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
|
@ -1159,7 +1161,7 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1200,6 +1202,7 @@ def htmlWanted(cssCache: {}, defaultTimeline: str,
|
|||
"""
|
||||
manuallyApproveFollowers = \
|
||||
followerApprovalActive(baseDir, nickname, domain)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
|
@ -1213,7 +1216,7 @@ def htmlWanted(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1255,6 +1258,7 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|||
"""
|
||||
manuallyApproveFollowers = \
|
||||
followerApprovalActive(baseDir, nickname, domain)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
|
@ -1268,7 +1272,7 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1310,6 +1314,7 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|||
"""
|
||||
manuallyApproveFollowers = \
|
||||
followerApprovalActive(baseDir, nickname, domain)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
|
@ -1323,7 +1328,7 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1363,6 +1368,7 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|||
CWlists: {}, listsEnabled: str) -> str:
|
||||
"""Show the DM timeline as html
|
||||
"""
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -1373,7 +1379,7 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False, positiveVoting,
|
||||
newswire, False, False, artist, positiveVoting,
|
||||
showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1413,6 +1419,7 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|||
CWlists: {}, listsEnabled: str) -> str:
|
||||
"""Show the replies timeline as html
|
||||
"""
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -1424,7 +1431,7 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1464,6 +1471,7 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|||
CWlists: {}, listsEnabled: str) -> str:
|
||||
"""Show the media timeline as html
|
||||
"""
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -1475,7 +1483,7 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1515,6 +1523,7 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|||
CWlists: {}, listsEnabled: str) -> str:
|
||||
"""Show the blogs timeline as html
|
||||
"""
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -1526,7 +1535,7 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1578,7 +1587,7 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False,
|
||||
newswire, False, False, False,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1601,7 +1610,7 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain: str,
|
||||
twitterReplacementDomain: str,
|
||||
showPublishedDateOnly: bool,
|
||||
newswire: {}, moderator: bool, editor: bool,
|
||||
newswire: {}, moderator: bool, editor: bool, artist: bool,
|
||||
positiveVoting: bool, showPublishAsIcon: bool,
|
||||
fullWidthTimelineButtonHeader: bool,
|
||||
iconsAsButtons: bool,
|
||||
|
@ -1629,7 +1638,7 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, moderator, editor,
|
||||
newswire, moderator, editor, artist,
|
||||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
|
@ -1671,6 +1680,7 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|||
"""
|
||||
manuallyApproveFollowers = \
|
||||
followerApprovalActive(baseDir, nickname, domain)
|
||||
artist = isArtist(baseDir, nickname)
|
||||
return htmlTimeline(cssCache, defaultTimeline,
|
||||
recentPostsCache, maxRecentPosts,
|
||||
translate, pageNumber,
|
||||
|
@ -1682,7 +1692,7 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|||
YTReplacementDomain,
|
||||
twitterReplacementDomain,
|
||||
showPublishedDateOnly,
|
||||
newswire, False, False, positiveVoting,
|
||||
newswire, False, False, artist, positiveVoting,
|
||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized, None, theme, peertubeInstances,
|
||||
|
|