Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon

main
Bob Mottram 2021-05-17 21:50:06 +01:00
commit 4b0bdab223
22 changed files with 501 additions and 304 deletions

144
daemon.py
View File

@ -128,6 +128,7 @@ from roles import setRole
from roles import clearModeratorStatus
from roles import clearEditorStatus
from roles import clearCounselorStatus
from roles import clearArtistStatus
from blog import htmlBlogPageRSS2
from blog import htmlBlogPageRSS3
from blog import htmlBlogView
@ -213,6 +214,7 @@ from utils import hasUsersPath
from utils import getFullDomain
from utils import removeHtml
from utils import isEditor
from utils import isArtist
from utils import getImageExtensions
from utils import mediaFileMimeType
from utils import getCSS
@ -4268,6 +4270,38 @@ class PubServer(BaseHTTPRequestHandler):
if checkNameAndBio:
redirectPath = 'previewAvatar'
if nickname == adminNickname or \
isArtist(baseDir, nickname):
# change theme
if fields.get('themeDropdown'):
self.server.themeName = fields['themeDropdown']
setTheme(baseDir, self.server.themeName, domain,
allowLocalNetworkAccess, systemLanguage)
self.server.textModeBanner = \
getTextModeBanner(self.server.baseDir)
self.server.iconsCache = {}
self.server.fontsCache = {}
self.server.showPublishAsIcon = \
getConfigParam(self.server.baseDir,
'showPublishAsIcon')
self.server.fullWidthTimelineButtonHeader = \
getConfigParam(self.server.baseDir,
'fullWidthTimelineButtonHeader')
self.server.iconsAsButtons = \
getConfigParam(self.server.baseDir,
'iconsAsButtons')
self.server.rssIconAtTop = \
getConfigParam(self.server.baseDir,
'rssIconAtTop')
self.server.publishButtonAtTop = \
getConfigParam(self.server.baseDir,
'publishButtonAtTop')
setNewsAvatar(baseDir,
fields['themeDropdown'],
httpPrefix,
domain,
domainFull)
if nickname == adminNickname:
# change media instance status
if fields.get('mediaInstance'):
@ -4352,36 +4386,6 @@ class PubServer(BaseHTTPRequestHandler):
"blogsInstance",
self.server.blogsInstance)
# change theme
if fields.get('themeDropdown'):
self.server.themeName = fields['themeDropdown']
setTheme(baseDir, self.server.themeName, domain,
allowLocalNetworkAccess, systemLanguage)
self.server.textModeBanner = \
getTextModeBanner(self.server.baseDir)
self.server.iconsCache = {}
self.server.fontsCache = {}
self.server.showPublishAsIcon = \
getConfigParam(self.server.baseDir,
'showPublishAsIcon')
self.server.fullWidthTimelineButtonHeader = \
getConfigParam(self.server.baseDir,
'fullWidthTimelineButtonHeader')
self.server.iconsAsButtons = \
getConfigParam(self.server.baseDir,
'iconsAsButtons')
self.server.rssIconAtTop = \
getConfigParam(self.server.baseDir,
'rssIconAtTop')
self.server.publishButtonAtTop = \
getConfigParam(self.server.baseDir,
'publishButtonAtTop')
setNewsAvatar(baseDir,
fields['themeDropdown'],
httpPrefix,
domain,
domainFull)
# change instance title
if fields.get('instanceTitle'):
currInstanceTitle = \
@ -4872,6 +4876,62 @@ class PubServer(BaseHTTPRequestHandler):
edNick, domain,
'counselor')
# change site artists list
if fields.get('artists'):
if path.startswith('/users/' +
adminNickname + '/'):
artistsFile = \
baseDir + \
'/accounts/artists.txt'
clearArtistStatus(baseDir)
if ',' in fields['artists']:
# if the list was given as comma separated
edFile = open(artistsFile, "w+")
eds = fields['artists'].split(',')
for edNick in eds:
edNick = edNick.strip()
edDir = baseDir + \
'/accounts/' + edNick + \
'@' + domain
if os.path.isdir(edDir):
edFile.write(edNick + '\n')
edFile.close()
eds = fields['artists'].split(',')
for edNick in eds:
edNick = edNick.strip()
edDir = baseDir + \
'/accounts/' + edNick + \
'@' + domain
if os.path.isdir(edDir):
setRole(baseDir,
edNick, domain,
'artist')
else:
# nicknames on separate lines
edFile = open(artistsFile, "w+")
eds = fields['artists'].split('\n')
for edNick in eds:
edNick = edNick.strip()
edDir = \
baseDir + \
'/accounts/' + edNick + \
'@' + domain
if os.path.isdir(edDir):
edFile.write(edNick + '\n')
edFile.close()
eds = fields['artists'].split('\n')
for edNick in eds:
edNick = edNick.strip()
edDir = \
baseDir + \
'/accounts/' + \
edNick + '@' + \
domain
if os.path.isdir(edDir):
setRole(baseDir,
edNick, domain,
'artist')
# remove scheduled posts
if fields.get('removeScheduledPosts'):
if fields['removeScheduledPosts'] == 'on':
@ -4896,7 +4956,10 @@ class PubServer(BaseHTTPRequestHandler):
# remove a custom font
if fields.get('removeCustomFont'):
if fields['removeCustomFont'] == 'on':
if (fields['removeCustomFont'] == 'on' and
(isArtist(baseDir, nickname) or
path.startswith('/users/' +
adminNickname + '/'))):
fontExt = ('woff', 'woff2', 'otf', 'ttf')
for ext in fontExt:
if os.path.isfile(baseDir +
@ -4912,28 +4975,30 @@ class PubServer(BaseHTTPRequestHandler):
currTheme = getTheme(baseDir)
if currTheme:
self.server.themeName = currTheme
allowLocalNetworkAccess = \
self.server.allowLocalNetworkAccess
setTheme(baseDir, currTheme, domain,
self.server.allowLocalNetworkAccess,
allowLocalNetworkAccess,
systemLanguage)
self.server.textModeBanner = \
getTextModeBanner(self.server.baseDir)
getTextModeBanner(baseDir)
self.server.iconsCache = {}
self.server.fontsCache = {}
self.server.showPublishAsIcon = \
getConfigParam(self.server.baseDir,
getConfigParam(baseDir,
'showPublishAsIcon')
self.server.fullWidthTimelineButtonHeader = \
getConfigParam(self.server.baseDir,
getConfigParam(baseDir,
'fullWidthTimeline' +
'ButtonHeader')
self.server.iconsAsButtons = \
getConfigParam(self.server.baseDir,
getConfigParam(baseDir,
'iconsAsButtons')
self.server.rssIconAtTop = \
getConfigParam(self.server.baseDir,
getConfigParam(baseDir,
'rssIconAtTop')
self.server.publishButtonAtTop = \
getConfigParam(self.server.baseDir,
getConfigParam(baseDir,
'publishButtonAtTop')
# only receive DMs from accounts you follow
@ -5033,6 +5098,9 @@ class PubServer(BaseHTTPRequestHandler):
actorChanged = True
# grayscale theme
if path.startswith('/users/' +
adminNickname + '/') or \
isArtist(baseDir, nickname):
grayscale = False
if fields.get('grayscale'):
if fields['grayscale'] == 'on':

File diff suppressed because one or more lines are too long

View File

@ -54,6 +54,14 @@ def clearCounselorStatus(baseDir: str) -> None:
_clearRoleStatus(baseDir, 'editor')
def clearArtistStatus(baseDir: str) -> None:
"""Removes artist status from all accounts
This could be slow if there are many users, but only happens
rarely when artists are appointed or removed
"""
_clearRoleStatus(baseDir, 'artist')
def clearModeratorStatus(baseDir: str) -> None:
"""Removes moderator status from all accounts
This could be slow if there are many users, but only happens
@ -126,6 +134,8 @@ def _setActorRole(actorJson: {}, roleName: str) -> bool:
category = '27-3041.00'
elif 'counselor' in roleName:
category = '23-1022.00'
elif 'artist' in roleName:
category = '27-1024.00'
if not category:
return False
@ -225,7 +235,8 @@ def setRole(baseDir: str, nickname: str, domain: str,
roleFiles = {
"moderator": "moderators.txt",
"editor": "editors.txt",
"counselor": "counselors.txt"
"counselor": "counselors.txt",
"artist": "artists.txt"
}
actorJson = loadJson(actorFilename)

View File

@ -3706,6 +3706,7 @@ def testRoles() -> None:
assert actorHasRole(actorJson, "moderator")
assert not actorHasRole(actorJson, "editor")
assert not actorHasRole(actorJson, "counselor")
assert not actorHasRole(actorJson, "artist")
def runAllTests():

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "إظهار رقم الإصدار داخل البيانات الوصفية للمثيل",
"Joined": "تاريخ الانضمام",
"City for spoofed GPS image metadata": "مدينة للبيانات الوصفية لصور GPS المخادعة",
"Occupation": "الاحتلال"
"Occupation": "الاحتلال",
"Artists": "الفنانين",
"Graphic Design": "التصميم الجرافيكي"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Mostra el número de versió a les metadades de la instància",
"Joined": "Data d'unió",
"City for spoofed GPS image metadata": "Ciutat per a metadades d'imatges GPS falsificades",
"Occupation": "Ocupació"
"Occupation": "Ocupació",
"Artists": "Artistes",
"Graphic Design": "Disseny gràfic"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Dangos rhif y fersiwn o fewn metadata",
"Joined": "Dyddiad ymuno",
"City for spoofed GPS image metadata": "Dinas ar gyfer metadata delwedd GPS spoofed",
"Occupation": "Ngalwedigaeth"
"Occupation": "Ngalwedigaeth",
"Artists": "Artistiaid",
"Graphic Design": "Dylunio Graffig"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Versionsnummer in Instanzmetadaten anzeigen",
"Joined": "Verbundenes Datum",
"City for spoofed GPS image metadata": "Stadt für gefälschte GPS-Bildmetadaten",
"Occupation": "Besetzung"
"Occupation": "Besetzung",
"Artists": "Künstler",
"Graphic Design": "Grafikdesign"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Show version number within instance metadata",
"Joined": "Joined",
"City for spoofed GPS image metadata": "City for spoofed GPS image metadata",
"Occupation": "Occupation"
"Occupation": "Occupation",
"Artists": "Artists",
"Graphic Design": "Graphic Design"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Mostrar el número de versión dentro de los metadatos de la instancia",
"Joined": "Fecha unida",
"City for spoofed GPS image metadata": "Ciudad para metadatos de imagen GPS falsificados",
"Occupation": "Ocupación"
"Occupation": "Ocupación",
"Artists": "Artistas",
"Graphic Design": "Diseño gráfico"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Afficher le numéro de version dans les métadonnées de l'instance",
"Joined": "Joint",
"City for spoofed GPS image metadata": "Ville pour les métadonnées d'image GPS falsifiées",
"Occupation": "Occupation"
"Occupation": "Occupation",
"Artists": "Artistes",
"Graphic Design": "Conception graphique"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Taispeáin uimhir an leagain laistigh de mheiteashonraí",
"Joined": "Dáta comhcheangailte",
"City for spoofed GPS image metadata": "Cathair le haghaidh meiteashonraí íomhá GPS spoofed",
"Occupation": "Slí bheatha"
"Occupation": "Slí bheatha",
"Artists": "Ealaíontóirí",
"Graphic Design": "Dearadh grafach"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "उदाहरण मेटाडेटा के भीतर संस्करण संख्या दिखाएं",
"Joined": "दिनांक",
"City for spoofed GPS image metadata": "स्पूफ जीपीएस जीपीएस मेटाडेटा के लिए शहर",
"Occupation": "व्यवसाय"
"Occupation": "व्यवसाय",
"Artists": "कलाकार की",
"Graphic Design": "ग्राफ़िक डिज़ाइन"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Mostra il numero di versione nei metadati dell'istanza",
"Joined": "Unito",
"City for spoofed GPS image metadata": "Città per metadati di immagini GPS falsificate",
"Occupation": "Occupazione"
"Occupation": "Occupazione",
"Artists": "Artiste",
"Graphic Design": "Graphic design"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "インスタンスメタデータ内にバージョン番号を表示する",
"Joined": "参加日",
"City for spoofed GPS image metadata": "なりすましGPS画像メタデータの都市",
"Occupation": "職業"
"Occupation": "職業",
"Artists": "アーティスト",
"Graphic Design": "グラフィックデザイン"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Di nav metadata mînakê de nimreya guhertoyê nîşan bide",
"Joined": "Beşdarbûna Dîrokê",
"City for spoofed GPS image metadata": "Bajar ji bo metadata wêneya GPS ya xapînok",
"Occupation": "Sinet"
"Occupation": "Sinet",
"Artists": "Hunermend",
"Graphic Design": "Sêwirana grafîkî"
}

View File

@ -438,5 +438,7 @@
"Show version number within instance metadata": "Show version number within instance metadata",
"Joined": "Joined",
"City for spoofed GPS image metadata": "City for spoofed GPS image metadata",
"Occupation": "Occupation"
"Occupation": "Occupation",
"Artists": "Artists",
"Graphic Design": "Graphic Design"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Mostrar o número da versão nos metadados da instância",
"Joined": "Data juntada",
"City for spoofed GPS image metadata": "Cidade para metadados de imagem GPS falsificados",
"Occupation": "Ocupação"
"Occupation": "Ocupação",
"Artists": "Artistas",
"Graphic Design": "Design gráfico"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "Показать номер версии в метаданных экземпляра",
"Joined": "Присоединенная дата",
"City for spoofed GPS image metadata": "Город для поддельных метаданных изображения GPS",
"Occupation": "Занятие"
"Occupation": "Занятие",
"Artists": "Художники",
"Graphic Design": "Графический дизайн"
}

View File

@ -442,5 +442,7 @@
"Show version number within instance metadata": "在实例元数据中显示版本号",
"Joined": "加入日期",
"City for spoofed GPS image metadata": "欺骗性GPS影像元数据的城市",
"Occupation": "职业"
"Occupation": "职业",
"Artists": "艺人",
"Graphic Design": "平面设计"
}

View File

@ -194,6 +194,34 @@ def isEditor(baseDir: str, nickname: str) -> bool:
return False
def isArtist(baseDir: str, nickname: str) -> bool:
"""Returns true if the given nickname is an artist
"""
artistsFile = baseDir + '/accounts/artists.txt'
if not os.path.isfile(artistsFile):
adminName = getConfigParam(baseDir, 'admin')
if not adminName:
return False
if adminName == nickname:
return True
return False
with open(artistsFile, "r") as f:
lines = f.readlines()
if len(lines) == 0:
adminName = getConfigParam(baseDir, 'admin')
if not adminName:
return False
if adminName == nickname:
return True
for artist in lines:
artist = artist.strip('\n').strip('\r')
if artist == nickname:
return True
return False
def getImageExtensions() -> []:
"""Returns a list of the possible image file extensions
"""

View File

@ -12,6 +12,7 @@ from utils import getOccupationName
from utils import getLockedAccount
from utils import hasUsersPath
from utils import getFullDomain
from utils import isArtist
from utils import isDormant
from utils import getNicknameFromActor
from utils import getDomainFromActor
@ -1292,6 +1293,49 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
peertubeStr = ''
adminNickname = getConfigParam(baseDir, 'admin')
if isArtist(baseDir, nickname) or \
path.startswith('/users/' + str(adminNickname) + '/'):
graphicsStr = '<details><summary class="cw">' + \
translate['Graphic Design'] + '</summary>\n'
graphicsStr += '<div class="container">'
# Themes section
themes = getThemesList(baseDir)
themesDropdown += ' <label class="labels">' + \
translate['Theme'] + '</label><br>\n'
grayscaleFilename = \
baseDir + '/accounts/.grayscale'
grayscale = ''
if os.path.isfile(grayscaleFilename):
grayscale = 'checked'
themesDropdown += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="grayscale" ' + grayscale + \
'> ' + translate['Grayscale'] + '<br>'
themesDropdown += ' <select id="themeDropdown" ' + \
'name="themeDropdown" class="theme">'
for themeName in themes:
themesDropdown += ' <option value="' + \
themeName.lower() + '">' + \
translate[themeName] + '</option>'
themesDropdown += ' </select><br>'
if os.path.isfile(baseDir + '/fonts/custom.woff') or \
os.path.isfile(baseDir + '/fonts/custom.woff2') or \
os.path.isfile(baseDir + '/fonts/custom.otf') or \
os.path.isfile(baseDir + '/fonts/custom.ttf'):
themesDropdown += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="removeCustomFont"> ' + \
translate['Remove the custom font'] + '<br>'
themeName = getConfigParam(baseDir, 'theme')
themesDropdown = \
themesDropdown.replace('<option value="' + themeName + '">',
'<option value="' + themeName +
'" selected>')
graphicsStr += themesDropdown
graphicsStr += ' </div></details>\n'
if adminNickname:
if path.startswith('/users/' + adminNickname + '/'):
# Instance details section
@ -1346,40 +1390,6 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
' <input type="file" id="instanceLogo" name="instanceLogo"'
instanceStr += ' accept="' + imageFormats + '"><br>\n'
# Themes section
themes = getThemesList(baseDir)
themesDropdown += ' <br><label class="labels">' + \
translate['Theme'] + '</label><br>\n'
grayscaleFilename = \
baseDir + '/accounts/.grayscale'
grayscale = ''
if os.path.isfile(grayscaleFilename):
grayscale = 'checked'
themesDropdown += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="grayscale" ' + grayscale + \
'> ' + translate['Grayscale'] + '<br>'
themesDropdown += ' <select id="themeDropdown" ' + \
'name="themeDropdown" class="theme">'
for themeName in themes:
themesDropdown += ' <option value="' + \
themeName.lower() + '">' + \
translate[themeName] + '</option>'
themesDropdown += ' </select><br>'
if os.path.isfile(baseDir + '/fonts/custom.woff') or \
os.path.isfile(baseDir + '/fonts/custom.woff2') or \
os.path.isfile(baseDir + '/fonts/custom.otf') or \
os.path.isfile(baseDir + '/fonts/custom.ttf'):
themesDropdown += \
' <input type="checkbox" class="profilecheckbox" ' + \
'name="removeCustomFont"> ' + \
translate['Remove the custom font'] + '<br>'
themeName = getConfigParam(baseDir, 'theme')
themesDropdown = \
themesDropdown.replace('<option value="' + themeName + '">',
'<option value="' + themeName +
'" selected>')
instanceStr += themesDropdown
instanceStr += \
' <br><label class="labels">' + \
translate['Security'] + '</label><br>\n'
@ -1498,6 +1508,20 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
'placeholder="" ' + \
'style="height:200px" spellcheck="false">' + \
counselors + '</textarea>'
# artists
artists = ''
artistsFile = baseDir + '/accounts/artists.txt'
if os.path.isfile(artistsFile):
with open(artistsFile, "r") as f:
artists = f.read()
roleAssignStr += ' <b><label class="labels">' + \
translate['Artists'] + '</label></b><br>\n'
roleAssignStr += \
' <textarea id="message" name="artists" ' + \
'placeholder="" ' + \
'style="height:200px" spellcheck="false">' + \
artists + '</textarea>'
roleAssignStr += ' </div></details>\n'
# Video section
@ -1928,7 +1952,7 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
editProfileForm += ' <label class="labels">' + \
translate[idx] + '</label>\n'
editProfileForm += skillsStr
editProfileForm += roleAssignStr + peertubeStr + instanceStr
editProfileForm += roleAssignStr + peertubeStr + graphicsStr + instanceStr
# danger zone section
editProfileForm += ' <details><summary class="cw">' + \