Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main
|
@ -226,7 +226,8 @@ To run a security audit:
|
|||
./security_audit
|
||||
```
|
||||
|
||||
Note that not all of the issues identified will necessarily be relevant to this project.
|
||||
Note that not all of the issues identified will necessarily be relevant to this project. Consider its output as a list of things which potentially can be investigated but usually will turn out not to be relevant.
|
||||
|
||||
|
||||
## Installing on Onion or i2p domains
|
||||
|
||||
|
@ -248,6 +249,11 @@ systemctl restart epicyon
|
|||
If you want to use your own favicon then copy your `favicon.ico` file to the base directory where you installed Epicyon.
|
||||
|
||||
|
||||
## Changing Themes
|
||||
|
||||
When changing themes you may need to ensure that your nginx cache is cleared (/var/www/cache/*) and that your local browser cache is cleared for the site (Shift + Reload). Otherwise images and icons from the previous theme may remain.
|
||||
|
||||
|
||||
## Adding Themes
|
||||
|
||||
If you want to add a new theme then first add the name of your theme to the translations files.
|
||||
|
|
120
daemon.py
|
@ -136,6 +136,7 @@ from webapp_timeline import htmlInboxBlogs
|
|||
from webapp_timeline import htmlInboxNews
|
||||
from webapp_timeline import htmlInboxFeatures
|
||||
from webapp_timeline import htmlOutbox
|
||||
from webapp_moderation import htmlAccountInfo
|
||||
from webapp_moderation import htmlModeration
|
||||
from webapp_moderation import htmlModerationInfo
|
||||
from webapp_create_post import htmlNewPost
|
||||
|
@ -1403,6 +1404,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
"""Actions on the moderator screeen
|
||||
"""
|
||||
usersPath = path.replace('/moderationaction', '')
|
||||
nickname = usersPath.replace('/users/', '')
|
||||
actorStr = httpPrefix + '://' + domainFull + usersPath
|
||||
|
||||
length = int(self.headers['Content-length'])
|
||||
|
@ -1439,9 +1441,26 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
moderationText = \
|
||||
urllib.parse.unquote_plus(modText.strip())
|
||||
elif moderationStr.startswith('submitInfo'):
|
||||
msg = htmlModerationInfo(self.server.cssCache,
|
||||
self.server.translate,
|
||||
baseDir, httpPrefix)
|
||||
searchHandle = moderationText
|
||||
if searchHandle:
|
||||
if '@' not in searchHandle:
|
||||
searchHandle = None
|
||||
if searchHandle:
|
||||
msg = \
|
||||
htmlAccountInfo(self.server.cssCache,
|
||||
self.server.translate,
|
||||
baseDir, httpPrefix,
|
||||
nickname,
|
||||
self.server.domain,
|
||||
self.server.port,
|
||||
searchHandle,
|
||||
self.server.debug)
|
||||
else:
|
||||
msg = \
|
||||
htmlModerationInfo(self.server.cssCache,
|
||||
self.server.translate,
|
||||
baseDir, httpPrefix,
|
||||
nickname)
|
||||
msg = msg.encode('utf-8')
|
||||
self._login_headers('text/html',
|
||||
len(msg), callingDomain)
|
||||
|
@ -3826,6 +3845,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.themeName = fields['themeDropdown']
|
||||
setTheme(baseDir, self.server.themeName, domain,
|
||||
allowLocalNetworkAccess)
|
||||
self.server.iconsCache = {}
|
||||
self.server.fontsCache = {}
|
||||
self.server.showPublishAsIcon = \
|
||||
getConfigParam(self.server.baseDir,
|
||||
'showPublishAsIcon')
|
||||
|
@ -4199,6 +4220,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.themeName = currTheme
|
||||
setTheme(baseDir, currTheme, domain,
|
||||
self.server.allowLocalNetworkAccess)
|
||||
self.server.iconsCache = {}
|
||||
self.server.fontsCache = {}
|
||||
self.server.showPublishAsIcon = \
|
||||
getConfigParam(self.server.baseDir,
|
||||
'showPublishAsIcon')
|
||||
|
@ -5329,6 +5352,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
debug,
|
||||
self.server.projectVersion)
|
||||
if announceJson:
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('repeat.png'):
|
||||
del self.server.iconsCache['repeat.png']
|
||||
self._postToOutboxThread(announceJson)
|
||||
self.server.GETbusy = False
|
||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
||||
|
@ -5419,6 +5445,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
'type': 'Announce'
|
||||
}
|
||||
}
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('repeat_inactive.png'):
|
||||
del self.server.iconsCache['repeat_inactive.png']
|
||||
self._postToOutboxThread(newUndoAnnounce)
|
||||
self.server.GETbusy = False
|
||||
actorAbsolute = httpPrefix + '://' + domainFull + actor
|
||||
|
@ -5700,6 +5729,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
likedPostFilename, likeUrl,
|
||||
likeActor, domain,
|
||||
debug)
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('like.png'):
|
||||
del self.server.iconsCache['like.png']
|
||||
else:
|
||||
print('WARN: unable to locate file for liked post ' +
|
||||
likeUrl)
|
||||
|
@ -5804,6 +5836,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
baseDir,
|
||||
likedPostFilename, likeUrl,
|
||||
undoActor, domain, debug)
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('like_inactive.png'):
|
||||
del self.server.iconsCache['like_inactive.png']
|
||||
# send out the undo like to followers
|
||||
self._postToOutbox(undoLikeJson, self.server.projectVersion)
|
||||
self.server.GETbusy = False
|
||||
|
@ -5895,6 +5930,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.cachedWebfingers,
|
||||
self.server.debug,
|
||||
self.server.projectVersion)
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('bookmark.png'):
|
||||
del self.server.iconsCache['bookmark.png']
|
||||
# self._postToOutbox(bookmarkJson, self.server.projectVersion)
|
||||
self.server.GETbusy = False
|
||||
actorAbsolute = \
|
||||
|
@ -5985,6 +6023,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.cachedWebfingers,
|
||||
debug,
|
||||
self.server.projectVersion)
|
||||
# clear the icon from the cache so that it gets updated
|
||||
if self.server.iconsCache.get('bookmark_inactive.png'):
|
||||
del self.server.iconsCache['bookmark_inactive.png']
|
||||
# self._postToOutbox(undoBookmarkJson, self.server.projectVersion)
|
||||
self.server.GETbusy = False
|
||||
actorAbsolute = \
|
||||
|
@ -8090,6 +8131,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.votingTimeMins)
|
||||
fullWidthTimelineButtonHeader = \
|
||||
self.server.fullWidthTimelineButtonHeader
|
||||
moderationActionStr = ''
|
||||
msg = \
|
||||
htmlModeration(self.server.cssCache,
|
||||
self.server.defaultTimeline,
|
||||
|
@ -8117,7 +8159,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
self.server.iconsAsButtons,
|
||||
self.server.rssIconAtTop,
|
||||
self.server.publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, moderationActionStr)
|
||||
msg = msg.encode('utf-8')
|
||||
self._set_headers('text/html', len(msg),
|
||||
cookie, callingDomain)
|
||||
|
@ -10954,6 +10996,74 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
'show blogs 2 done',
|
||||
'show shares 2 done')
|
||||
|
||||
# block a domain from htmlAccountInfo
|
||||
if authorized and '/users/' in self.path and \
|
||||
'/accountinfo?blockdomain=' in self.path and \
|
||||
'?handle=' in self.path:
|
||||
nickname = self.path.split('/users/')[1]
|
||||
if '/' in nickname:
|
||||
nickname = nickname.split('/')[0]
|
||||
if not isModerator(self.server.baseDir, nickname):
|
||||
self._400()
|
||||
return
|
||||
blockDomain = self.path.split('/accountinfo?blockdomain=')[1]
|
||||
searchHandle = blockDomain.split('?handle=')[1]
|
||||
searchHandle = urllib.parse.unquote_plus(searchHandle)
|
||||
blockDomain = blockDomain.split('?handle=')[0]
|
||||
blockDomain = urllib.parse.unquote_plus(blockDomain.strip())
|
||||
if '?' in blockDomain:
|
||||
blockDomain = blockDomain.split('?')[0]
|
||||
addGlobalBlock(self.server.baseDir, '*', blockDomain)
|
||||
self.server.GETbusy = False
|
||||
msg = \
|
||||
htmlAccountInfo(self.server.cssCache,
|
||||
self.server.translate,
|
||||
self.server.baseDir,
|
||||
self.server.httpPrefix,
|
||||
nickname,
|
||||
self.server.domain,
|
||||
self.server.port,
|
||||
searchHandle,
|
||||
self.server.debug)
|
||||
msg = msg.encode('utf-8')
|
||||
self._login_headers('text/html',
|
||||
len(msg), callingDomain)
|
||||
self._write(msg)
|
||||
return
|
||||
|
||||
# unblock a domain from htmlAccountInfo
|
||||
if authorized and '/users/' in self.path and \
|
||||
'/accountinfo?unblockdomain=' in self.path and \
|
||||
'?handle=' in self.path:
|
||||
nickname = self.path.split('/users/')[1]
|
||||
if '/' in nickname:
|
||||
nickname = nickname.split('/')[0]
|
||||
if not isModerator(self.server.baseDir, nickname):
|
||||
self._400()
|
||||
return
|
||||
blockDomain = self.path.split('/accountinfo?unblockdomain=')[1]
|
||||
searchHandle = blockDomain.split('?handle=')[1]
|
||||
searchHandle = urllib.parse.unquote_plus(searchHandle)
|
||||
blockDomain = blockDomain.split('?handle=')[0]
|
||||
blockDomain = urllib.parse.unquote_plus(blockDomain.strip())
|
||||
removeGlobalBlock(self.server.baseDir, '*', blockDomain)
|
||||
self.server.GETbusy = False
|
||||
msg = \
|
||||
htmlAccountInfo(self.server.cssCache,
|
||||
self.server.translate,
|
||||
self.server.baseDir,
|
||||
self.server.httpPrefix,
|
||||
nickname,
|
||||
self.server.domain,
|
||||
self.server.port,
|
||||
searchHandle,
|
||||
self.server.debug)
|
||||
msg = msg.encode('utf-8')
|
||||
self._login_headers('text/html',
|
||||
len(msg), callingDomain)
|
||||
self._write(msg)
|
||||
return
|
||||
|
||||
# get the bookmarks timeline for a given person
|
||||
if self.path.endswith('/tlbookmarks') or \
|
||||
'/tlbookmarks?page=' in self.path or \
|
||||
|
@ -11021,7 +11131,7 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
|
||||
# get the moderation feed for a moderator
|
||||
if self.path.endswith('/moderation') or \
|
||||
'/moderation?page=' in self.path:
|
||||
'/moderation?' in self.path:
|
||||
if self._showModTimeline(authorized,
|
||||
callingDomain, self.path,
|
||||
self.server.baseDir,
|
||||
|
|
|
@ -930,6 +930,10 @@ div.container {
|
|||
overflow: hidden;
|
||||
}
|
||||
|
||||
.accountInfoDomains {
|
||||
margin: 0 20%;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 400px) {
|
||||
body, html {
|
||||
background-color: var(--main-bg-color);
|
||||
|
|
|
@ -526,8 +526,8 @@ if args.posts:
|
|||
if args.postDomains:
|
||||
if '@' not in args.postDomains:
|
||||
if '/users/' in args.postDomains:
|
||||
postsNickname = getNicknameFromActor(args.posts)
|
||||
postsDomain, postsPort = getDomainFromActor(args.posts)
|
||||
postsNickname = getNicknameFromActor(args.postDomains)
|
||||
postsDomain, postsPort = getDomainFromActor(args.postDomains)
|
||||
args.postDomains = postsNickname + '@' + postsDomain
|
||||
if postsPort:
|
||||
if postsPort != 80 and postsPort != 443:
|
||||
|
@ -565,8 +565,9 @@ if args.postDomainsBlocked:
|
|||
# given handle but which are globally blocked on this instance
|
||||
if '@' not in args.postDomainsBlocked:
|
||||
if '/users/' in args.postDomainsBlocked:
|
||||
postsNickname = getNicknameFromActor(args.posts)
|
||||
postsDomain, postsPort = getDomainFromActor(args.posts)
|
||||
postsNickname = getNicknameFromActor(args.postDomainsBlocked)
|
||||
postsDomain, postsPort = \
|
||||
getDomainFromActor(args.postDomainsBlocked)
|
||||
args.postDomainsBlocked = postsNickname + '@' + postsDomain
|
||||
if postsPort:
|
||||
if postsPort != 80 and postsPort != 443:
|
||||
|
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 6.0 KiB |
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "حدد رمز التحرير لإضافة موجز ويب لـ RSS",
|
||||
"Select the edit icon to add web links": "حدد رمز التحرير لإضافة روابط الويب",
|
||||
"Hashtag Categories RSS Feed": "Hashtag Categories RSS Feed",
|
||||
"Ask about a shared item.": "اسأل عن عنصر مشترك."
|
||||
"Ask about a shared item.": "اسأل عن عنصر مشترك.",
|
||||
"Account Information": "معلومات الحساب",
|
||||
"This account interacts with the following instances": "يتفاعل هذا الحساب مع الحالات التالية"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Seleccioneu la icona d'edició per afegir canals RSS",
|
||||
"Select the edit icon to add web links": "Seleccioneu la icona d'edició per afegir enllaços web",
|
||||
"Hashtag Categories RSS Feed": "Feed RSS de categories de hashtag",
|
||||
"Ask about a shared item.": "Pregunteu sobre un element compartit."
|
||||
"Ask about a shared item.": "Pregunteu sobre un element compartit.",
|
||||
"Account Information": "Informació del compte",
|
||||
"This account interacts with the following instances": "Aquest compte interactua amb les instàncies següents"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Dewiswch yr eicon golygu i ychwanegu porthwyr RSS",
|
||||
"Select the edit icon to add web links": "Dewiswch yr eicon golygu i ychwanegu dolenni gwe",
|
||||
"Hashtag Categories RSS Feed": "Categorïau Hashtag RSS Feed",
|
||||
"Ask about a shared item.": "Gofynnwch am eitem a rennir."
|
||||
"Ask about a shared item.": "Gofynnwch am eitem a rennir.",
|
||||
"Account Information": "Gwybodaeth Gyfrif",
|
||||
"This account interacts with the following instances": "Mae'r cyfrif hwn yn rhyngweithio â'r achosion canlynol"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Wählen Sie das Bearbeitungssymbol, um RSS-Feeds hinzuzufügen",
|
||||
"Select the edit icon to add web links": "Wählen Sie das Bearbeitungssymbol, um Weblinks hinzuzufügen",
|
||||
"Hashtag Categories RSS Feed": "Hashtag Kategorien RSS Feed",
|
||||
"Ask about a shared item.": "Fragen Sie nach einem gemeinsamen Artikel."
|
||||
"Ask about a shared item.": "Fragen Sie nach einem gemeinsamen Artikel.",
|
||||
"Account Information": "Kontoinformationen",
|
||||
"This account interacts with the following instances": "Dieses Konto interagiert mit den folgenden Instanzen"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Select the edit icon to add RSS feeds",
|
||||
"Select the edit icon to add web links": "Select the edit icon to add web links",
|
||||
"Hashtag Categories RSS Feed": "Hashtag Categories RSS Feed",
|
||||
"Ask about a shared item.": "Ask about a shared item."
|
||||
"Ask about a shared item.": "Ask about a shared item.",
|
||||
"Account Information": "Account Information",
|
||||
"This account interacts with the following instances": "This account interacts with the following instances"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Seleccione el icono de edición para agregar fuentes RSS",
|
||||
"Select the edit icon to add web links": "Seleccione el icono de edición para agregar enlaces web",
|
||||
"Hashtag Categories RSS Feed": "Feed RSS de categorías de hashtags",
|
||||
"Ask about a shared item.": "Pregunte por un elemento compartido."
|
||||
"Ask about a shared item.": "Pregunte por un elemento compartido.",
|
||||
"Account Information": "Información de la cuenta",
|
||||
"This account interacts with the following instances": "Esta cuenta interactúa con las siguientes instancias"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Sélectionnez l'icône d'édition pour ajouter des flux RSS",
|
||||
"Select the edit icon to add web links": "Sélectionnez l'icône de modification pour ajouter des liens Web",
|
||||
"Hashtag Categories RSS Feed": "Flux RSS des catégories Hashtag",
|
||||
"Ask about a shared item.": "Renseignez-vous sur un élément partagé."
|
||||
"Ask about a shared item.": "Renseignez-vous sur un élément partagé.",
|
||||
"Account Information": "Information sur le compte",
|
||||
"This account interacts with the following instances": "Ce compte interagit avec les instances suivantes"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Roghnaigh an deilbhín eagar chun fothaí RSS a chur leis",
|
||||
"Select the edit icon to add web links": "Roghnaigh an deilbhín eagar chun naisc ghréasáin a chur leis",
|
||||
"Hashtag Categories RSS Feed": "Catagóirí Hashtag RSS Feed",
|
||||
"Ask about a shared item.": "Fiafraigh faoi earra roinnte."
|
||||
"Ask about a shared item.": "Fiafraigh faoi earra roinnte.",
|
||||
"Account Information": "Faisnéis Chuntais",
|
||||
"This account interacts with the following instances": "Idirghníomhaíonn an cuntas seo leis na cásanna seo a leanas"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "RSS फ़ीड जोड़ने के लिए संपादन आइकन का चयन करें",
|
||||
"Select the edit icon to add web links": "वेब लिंक जोड़ने के लिए संपादन आइकन का चयन करें",
|
||||
"Hashtag Categories RSS Feed": "हैशटैग श्रेणियाँ आरएसएस फ़ीड",
|
||||
"Ask about a shared item.": "एक साझा आइटम के बारे में पूछें।"
|
||||
"Ask about a shared item.": "एक साझा आइटम के बारे में पूछें।",
|
||||
"Account Information": "खाते की जानकारी",
|
||||
"This account interacts with the following instances": "यह खाता निम्नलिखित उदाहरणों के साथ सहभागिता करता है"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Seleziona l'icona di modifica per aggiungere feed RSS",
|
||||
"Select the edit icon to add web links": "Seleziona l'icona di modifica per aggiungere link web",
|
||||
"Hashtag Categories RSS Feed": "Feed RSS delle categorie hashtag",
|
||||
"Ask about a shared item.": "Chiedi informazioni su un elemento condiviso."
|
||||
"Ask about a shared item.": "Chiedi informazioni su un elemento condiviso.",
|
||||
"Account Information": "Informazioni account",
|
||||
"This account interacts with the following instances": "Questo account interagisce con le seguenti istanze"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "編集アイコンを選択してRSSフィードを追加します",
|
||||
"Select the edit icon to add web links": "編集アイコンを選択してWebリンクを追加します",
|
||||
"Hashtag Categories RSS Feed": "ハッシュタグカテゴリRSSフィード",
|
||||
"Ask about a shared item.": "共有アイテムについて質問します。"
|
||||
"Ask about a shared item.": "共有アイテムについて質問します。",
|
||||
"Account Information": "口座情報",
|
||||
"This account interacts with the following instances": "このアカウントは、次のインスタンスと相互作用します"
|
||||
}
|
||||
|
|
|
@ -335,5 +335,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Select the edit icon to add RSS feeds",
|
||||
"Select the edit icon to add web links": "Select the edit icon to add web links",
|
||||
"Hashtag Categories RSS Feed": "Hashtag Categories RSS Feed",
|
||||
"Ask about a shared item.": "Ask about a shared item."
|
||||
"Ask about a shared item.": "Ask about a shared item.",
|
||||
"Account Information": "Account Information",
|
||||
"This account interacts with the following instances": "This account interacts with the following instances"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Selecione o ícone de edição para adicionar feeds RSS",
|
||||
"Select the edit icon to add web links": "Selecione o ícone de edição para adicionar links da web",
|
||||
"Hashtag Categories RSS Feed": "Feed RSS das categorias de hashtag",
|
||||
"Ask about a shared item.": "Pergunte sobre um item compartilhado."
|
||||
"Ask about a shared item.": "Pergunte sobre um item compartilhado.",
|
||||
"Account Information": "Informação da conta",
|
||||
"This account interacts with the following instances": "Esta conta interage com as seguintes instâncias"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "Щелкните значок редактирования, чтобы добавить RSS-каналы",
|
||||
"Select the edit icon to add web links": "Щелкните значок редактирования, чтобы добавить веб-ссылки",
|
||||
"Hashtag Categories RSS Feed": "RSS-канал категорий хэштегов",
|
||||
"Ask about a shared item.": "Спросите об общем элементе."
|
||||
"Ask about a shared item.": "Спросите об общем элементе.",
|
||||
"Account Information": "Информация об аккаунте",
|
||||
"This account interacts with the following instances": "Этот аккаунт взаимодействует со следующими экземплярами"
|
||||
}
|
||||
|
|
|
@ -339,5 +339,7 @@
|
|||
"Select the edit icon to add RSS feeds": "选择编辑图标以添加RSS feed",
|
||||
"Select the edit icon to add web links": "选择编辑图标以添加Web链接",
|
||||
"Hashtag Categories RSS Feed": "标签类别RSS提要",
|
||||
"Ask about a shared item.": "询问共享项目。"
|
||||
"Ask about a shared item.": "询问共享项目。",
|
||||
"Account Information": "帐户信息",
|
||||
"This account interacts with the following instances": "此帐户与以下实例进行交互"
|
||||
}
|
||||
|
|
3
utils.py
|
@ -1148,7 +1148,8 @@ def validNickname(domain: str, nickname: str) -> bool:
|
|||
'channel', 'calendar',
|
||||
'tlreplies', 'tlmedia', 'tlblogs',
|
||||
'tlevents', 'tlblogs', 'tlfeatures',
|
||||
'moderation', 'activity', 'undo',
|
||||
'moderation', 'moderationaction',
|
||||
'activity', 'undo',
|
||||
'reply', 'replies', 'question', 'like',
|
||||
'likes', 'users', 'statuses', 'tags',
|
||||
'accounts', 'channels', 'profile',
|
||||
|
|
|
@ -215,7 +215,8 @@ def getLeftColumnContent(baseDir: str, nickname: str, domainFull: str,
|
|||
lineStr = lineStr[:len(lineStr)-1]
|
||||
# add link to the returned html
|
||||
htmlStr += \
|
||||
' <p><a href="' + linkStr + '">' + \
|
||||
' <p><a href="' + linkStr + \
|
||||
'" target="_blank" rel="noopener noreferrer">' + \
|
||||
lineStr + '</a></p>\n'
|
||||
linksFileContainsEntries = True
|
||||
else:
|
||||
|
|
|
@ -242,7 +242,8 @@ def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
|||
|
||||
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
||||
htmlStr += '<p class="newswireItemVotedOn">' + \
|
||||
'<a href="' + item[1] + '">' + \
|
||||
'<a href="' + item[1] + '" target="_blank" ' + \
|
||||
'rel="noopener noreferrer">' + \
|
||||
'<span class="newswireItemVotedOn">' + title + \
|
||||
'</span></a>' + totalVotesStr
|
||||
if moderator:
|
||||
|
@ -269,7 +270,8 @@ def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
|||
title = removeLongWords(item[0], 16, []).replace('\n', '<br>')
|
||||
if moderator and moderatedItem:
|
||||
htmlStr += '<p class="newswireItemModerated">' + \
|
||||
'<a href="' + item[1] + '">' + \
|
||||
'<a href="' + item[1] + '" target="_blank" ' + \
|
||||
'rel="noopener noreferrer">' + \
|
||||
title + '</a>' + totalVotesStr
|
||||
htmlStr += ' ' + dateShown
|
||||
htmlStr += '<a href="/users/' + nickname + \
|
||||
|
@ -280,7 +282,8 @@ def htmlNewswire(baseDir: str, newswire: {}, nickname: str, moderator: bool,
|
|||
htmlStr += '</p>\n'
|
||||
else:
|
||||
htmlStr += '<p class="newswireItem">' + \
|
||||
'<a href="' + item[1] + '">' + \
|
||||
'<a href="' + item[1] + '" target="_blank" ' + \
|
||||
'rel="noopener noreferrer">' + \
|
||||
title + '</a>' + \
|
||||
totalVotesStr
|
||||
htmlStr += ' <span class="newswireDate">'
|
||||
|
|
|
@ -7,9 +7,13 @@ __email__ = "bob@freedombone.net"
|
|||
__status__ = "Production"
|
||||
|
||||
import os
|
||||
from utils import getNicknameFromActor
|
||||
from utils import getDomainFromActor
|
||||
from posts import getPublicPostDomains
|
||||
from webapp_timeline import htmlTimeline
|
||||
from webapp_utils import htmlHeaderWithExternalStyle
|
||||
from webapp_utils import htmlFooter
|
||||
from blocking import isBlockedDomain
|
||||
|
||||
|
||||
def htmlModeration(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -27,7 +31,7 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
iconsAsButtons: bool,
|
||||
rssIconAtTop: bool,
|
||||
publishButtonAtTop: bool,
|
||||
authorized: bool) -> str:
|
||||
authorized: bool, moderationActionStr: str) -> str:
|
||||
"""Show the moderation feed as html
|
||||
This is what you see when selecting the "mod" timeline
|
||||
"""
|
||||
|
@ -41,15 +45,77 @@ def htmlModeration(cssCache: {}, defaultTimeline: str,
|
|||
newswire, False, False, positiveVoting,
|
||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, moderationActionStr)
|
||||
|
||||
|
||||
def htmlAccountInfo(cssCache: {}, translate: {},
|
||||
baseDir: str, httpPrefix: str,
|
||||
nickname: str, domain: str, port: int,
|
||||
searchHandle: str, debug: bool) -> str:
|
||||
"""Shows which domains a search handle interacts with.
|
||||
This screen is shown if a moderator enters a handle and selects info
|
||||
on the moderation screen
|
||||
"""
|
||||
msgStr1 = 'This account interacts with the following instances'
|
||||
|
||||
infoForm = ''
|
||||
cssFilename = baseDir + '/epicyon-profile.css'
|
||||
if os.path.isfile(baseDir + '/epicyon.css'):
|
||||
cssFilename = baseDir + '/epicyon.css'
|
||||
|
||||
infoForm = htmlHeaderWithExternalStyle(cssFilename)
|
||||
|
||||
searchNickname = getNicknameFromActor(searchHandle)
|
||||
searchDomain, searchPort = getDomainFromActor(searchHandle)
|
||||
|
||||
searchHandle = searchNickname + '@' + searchDomain
|
||||
infoForm += \
|
||||
'<center><h1><a href="/users/' + nickname + '/moderation">' + \
|
||||
translate['Account Information'] + ':</a> <a href="' + \
|
||||
httpPrefix + '://' + searchDomain + '/users/' + searchNickname + \
|
||||
'">' + searchHandle + '</a></h1><br>'
|
||||
|
||||
infoForm += translate[msgStr1] + '</center><br><br>'
|
||||
|
||||
proxyType = 'tor'
|
||||
domainList = []
|
||||
domainList = getPublicPostDomains(None,
|
||||
baseDir, searchNickname, searchDomain,
|
||||
proxyType, searchPort,
|
||||
httpPrefix, debug,
|
||||
__version__, domainList)
|
||||
infoForm += '<div class="accountInfoDomains">'
|
||||
usersPath = '/users/' + nickname + '/accountinfo'
|
||||
for postDomain in domainList:
|
||||
infoForm += '<a href="' + \
|
||||
httpPrefix + '://' + postDomain + '">' + postDomain + '</a> '
|
||||
if isBlockedDomain(baseDir, postDomain):
|
||||
infoForm += \
|
||||
'<a href="' + usersPath + '?unblockdomain=' + postDomain + \
|
||||
'?handle=' + searchHandle + '">'
|
||||
infoForm += '<button class="buttonhighlighted"><span>' + \
|
||||
translate['Unblock'] + '</span></button></a>'
|
||||
else:
|
||||
infoForm += \
|
||||
'<a href="' + usersPath + '?blockdomain=' + postDomain + \
|
||||
'?handle=' + searchHandle + '">'
|
||||
infoForm += '<button class="button"><span>' + \
|
||||
translate['Block'] + '</span></button></a>'
|
||||
infoForm += '<br>'
|
||||
|
||||
infoForm += '</div>'
|
||||
infoForm += htmlFooter()
|
||||
return infoForm
|
||||
|
||||
|
||||
def htmlModerationInfo(cssCache: {}, translate: {},
|
||||
baseDir: str, httpPrefix: str) -> str:
|
||||
baseDir: str, httpPrefix: str,
|
||||
nickname: str) -> str:
|
||||
msgStr1 = \
|
||||
'These are globally blocked for all accounts on this instance'
|
||||
msgStr2 = \
|
||||
'Any blocks or suspensions made by moderators will be shown here.'
|
||||
|
||||
infoForm = ''
|
||||
cssFilename = baseDir + '/epicyon-profile.css'
|
||||
if os.path.isfile(baseDir + '/epicyon.css'):
|
||||
|
@ -58,9 +124,9 @@ def htmlModerationInfo(cssCache: {}, translate: {},
|
|||
infoForm = htmlHeaderWithExternalStyle(cssFilename)
|
||||
|
||||
infoForm += \
|
||||
'<center><h1>' + \
|
||||
'<center><h1><a href="/users/' + nickname + '/moderation">' + \
|
||||
translate['Moderation Information'] + \
|
||||
'</h1></center>'
|
||||
'</a></h1></center><br>'
|
||||
|
||||
infoShown = False
|
||||
suspendedFilename = baseDir + '/accounts/suspended.txt'
|
||||
|
|
|
@ -58,7 +58,8 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
iconsAsButtons: bool,
|
||||
rssIconAtTop: bool,
|
||||
publishButtonAtTop: bool,
|
||||
authorized: bool) -> str:
|
||||
authorized: bool,
|
||||
moderationActionStr: str) -> str:
|
||||
"""Show the timeline as html
|
||||
"""
|
||||
enableTimingLog = False
|
||||
|
@ -441,8 +442,13 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
|||
idx = 'Nickname or URL. Block using *@domain or nickname@domain'
|
||||
tlStr += \
|
||||
' <b>' + translate[idx] + '</b><br>\n'
|
||||
tlStr += ' <input type="text" ' + \
|
||||
'name="moderationAction" value="" autofocus><br>\n'
|
||||
if moderationActionStr:
|
||||
tlStr += ' <input type="text" ' + \
|
||||
'name="moderationAction" value="' + \
|
||||
moderationActionStr + '" autofocus><br>\n'
|
||||
else:
|
||||
tlStr += ' <input type="text" ' + \
|
||||
'name="moderationAction" value="" autofocus><br>\n'
|
||||
tlStr += \
|
||||
' <input type="submit" title="' + \
|
||||
translate['Remove the above item'] + \
|
||||
|
@ -726,7 +732,7 @@ def htmlShares(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInbox(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -763,7 +769,7 @@ def htmlInbox(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -800,7 +806,7 @@ def htmlBookmarks(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlEvents(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -837,7 +843,7 @@ def htmlEvents(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -869,7 +875,7 @@ def htmlInboxDMs(cssCache: {}, defaultTimeline: str,
|
|||
showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -902,7 +908,7 @@ def htmlInboxReplies(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -935,7 +941,7 @@ def htmlInboxMedia(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -968,7 +974,7 @@ def htmlInboxBlogs(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1001,7 +1007,7 @@ def htmlInboxFeatures(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1034,7 +1040,7 @@ def htmlInboxNews(cssCache: {}, defaultTimeline: str,
|
|||
positiveVoting, showPublishAsIcon,
|
||||
fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
||||
|
||||
def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
||||
|
@ -1068,4 +1074,4 @@ def htmlOutbox(cssCache: {}, defaultTimeline: str,
|
|||
newswire, False, False, positiveVoting,
|
||||
showPublishAsIcon, fullWidthTimelineButtonHeader,
|
||||
iconsAsButtons, rssIconAtTop, publishButtonAtTop,
|
||||
authorized)
|
||||
authorized, None)
|
||||
|
|