mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main
commit
a9375537db
58
daemon.py
58
daemon.py
|
|
@ -120,6 +120,7 @@ from blocking import getDomainBlocklist
|
|||
from roles import setRole
|
||||
from roles import clearModeratorStatus
|
||||
from roles import clearEditorStatus
|
||||
from roles import clearCounselorStatus
|
||||
from blog import htmlBlogPageRSS2
|
||||
from blog import htmlBlogPageRSS3
|
||||
from blog import htmlBlogView
|
||||
|
|
@ -4728,6 +4729,63 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
'instance',
|
||||
'editor')
|
||||
|
||||
# change site counselors list
|
||||
if fields.get('counselors'):
|
||||
if path.startswith('/users/' +
|
||||
adminNickname + '/'):
|
||||
counselorsFile = \
|
||||
baseDir + \
|
||||
'/accounts/counselors.txt'
|
||||
clearCounselorStatus(baseDir)
|
||||
if ',' in fields['counselors']:
|
||||
# if the list was given as comma separated
|
||||
edFile = open(counselorsFile, "w+")
|
||||
eds = fields['counselors'].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['counselors'].split(',')
|
||||
for edNick in eds:
|
||||
edNick = edNick.strip()
|
||||
edDir = baseDir + \
|
||||
'/accounts/' + edNick + \
|
||||
'@' + domain
|
||||
if os.path.isdir(edDir):
|
||||
setRole(baseDir,
|
||||
edNick, domain,
|
||||
'instance', 'counselor')
|
||||
else:
|
||||
# nicknames on separate lines
|
||||
edFile = open(counselorsFile, "w+")
|
||||
eds = fields['counselors'].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['counselors'].split('\n')
|
||||
for edNick in eds:
|
||||
edNick = edNick.strip()
|
||||
edDir = \
|
||||
baseDir + \
|
||||
'/accounts/' + \
|
||||
edNick + '@' + \
|
||||
domain
|
||||
if os.path.isdir(edDir):
|
||||
setRole(baseDir,
|
||||
edNick, domain,
|
||||
'instance',
|
||||
'counselor')
|
||||
|
||||
# remove scheduled posts
|
||||
if fields.get('removeScheduledPosts'):
|
||||
if fields['removeScheduledPosts'] == 'on':
|
||||
|
|
|
|||
11
roles.py
11
roles.py
|
|
@ -51,6 +51,14 @@ def clearEditorStatus(baseDir: str) -> None:
|
|||
_clearRoleStatus(baseDir, 'editor')
|
||||
|
||||
|
||||
def clearCounselorStatus(baseDir: str) -> None:
|
||||
"""Removes counselor status from all accounts
|
||||
This could be slow if there are many users, but only happens
|
||||
rarely when counselors are appointed or removed
|
||||
"""
|
||||
_clearRoleStatus(baseDir, 'editor')
|
||||
|
||||
|
||||
def clearModeratorStatus(baseDir: str) -> None:
|
||||
"""Removes moderator status from all accounts
|
||||
This could be slow if there are many users, but only happens
|
||||
|
|
@ -119,7 +127,8 @@ def setRole(baseDir: str, nickname: str, domain: str,
|
|||
|
||||
roleFiles = {
|
||||
"moderator": "moderators.txt",
|
||||
"editor": "editors.txt"
|
||||
"editor": "editors.txt",
|
||||
"counselor": "counselors.txt"
|
||||
}
|
||||
|
||||
actorJson = loadJson(actorFilename)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
#
|
||||
# Something like:
|
||||
#
|
||||
# */1 * * * * root /usr/local/bin/epicyon-notification --epicyon yes
|
||||
# */1 * * * * root /usr/local/bin/epicyon-notification
|
||||
#
|
||||
# License
|
||||
# =======
|
||||
|
|
@ -29,6 +29,8 @@
|
|||
PROJECT_NAME=epicyon
|
||||
epicyonInstallDir=/opt/${PROJECT_NAME}
|
||||
|
||||
MY_EMAIL_ADDRESS="username@domain"
|
||||
|
||||
local_domain=$HOSTNAME
|
||||
if [ -f /var/lib/tor/hidden_service_epicyon/hostname ]; then
|
||||
local_domain=$(cat /var/lib/tor/hidden_service_epicyon/hostname)
|
||||
|
|
@ -38,18 +40,18 @@ fi
|
|||
function notification_translate_text {
|
||||
text="$1"
|
||||
if ! grep -q '"language":' "${epicyonInstallDir}/config.json"; then
|
||||
echo "$text"
|
||||
return
|
||||
echo "$text"
|
||||
return
|
||||
fi
|
||||
language=$(cat "${epicyonInstallDir}/config.json" | awk -F '"language":' '{print $2}' | awk -F '"' '{print $2}')
|
||||
translationsFilename="${epicyonInstallDir}/translations/${language}.json"
|
||||
if [ ! -f "$translationsFilename" ]; then
|
||||
echo "$text"
|
||||
return
|
||||
echo "$text"
|
||||
return
|
||||
fi
|
||||
if ! grep -q "\"$text\":" "$translationsFilename"; then
|
||||
echo "$text"
|
||||
return
|
||||
echo "$text"
|
||||
return
|
||||
fi
|
||||
grep "\"$text\":" "$translationsFilename" | awk -F '"' '{print $4}'
|
||||
}
|
||||
|
|
@ -111,25 +113,41 @@ function sendNotification {
|
|||
SUBJECT="$2"
|
||||
MESSAGE="$3"
|
||||
|
||||
hasSent=
|
||||
|
||||
if [ -d /etc/prosody ]; then
|
||||
if [ -f /usr/bin/sendxmpp ]; then
|
||||
# generate a random password for a temporary user account
|
||||
notification_user_password=$(openssl rand -base64 32 | tr -dc A-Za-z0-9 | head -c 30 ; echo -n '')
|
||||
# register a temporary xmpp user account to send the message
|
||||
if prosodyctl register "notification" "$local_domain" "$notification_user_password"; then
|
||||
if [[ "$SUBJECT" == *' Tor '* ]]; then
|
||||
MESSAGE="$SUBJECT"
|
||||
fi
|
||||
|
||||
if [ -f /usr/bin/sendxmpp ]; then
|
||||
# kill any existing message which hasn't sent
|
||||
kill_sendxmpp_process
|
||||
# send the xmpp notification using the temporary account
|
||||
echo "${MESSAGE}" | /usr/bin/sendxmpp -u notification -p "${notification_user_password}" -j localhost -o ${local_domain} --message-type=headline -n -t -s ${PROJECT_NAME} ${USERNAME}@${local_domain}
|
||||
hasSent=1
|
||||
fi
|
||||
fi
|
||||
# remove the temporary xmpp account
|
||||
prosodyctl deluser "notification@$local_domain"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d /etc/matrix ]; then
|
||||
matrix_server_message "${USERNAME}" "${USERNAME}" "$MESSAGE"
|
||||
hasSent=1
|
||||
fi
|
||||
|
||||
if [ ! "$hasSent" ]; then
|
||||
if [[ "$MY_EMAIL_ADDRESS" != "username@domain" ]]; then
|
||||
# send to a fixed email address for a single user instance
|
||||
echo "$MESSAGE" | /usr/bin/mail -s "$SUBJECT" "$MY_EMAIL_ADDRESS"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
@ -140,28 +158,28 @@ function notifications {
|
|||
fi
|
||||
|
||||
if [ ! -f "${epicyonInstallDir}/config.json" ]; then
|
||||
return
|
||||
return
|
||||
fi
|
||||
|
||||
# shellcheck disable=SC2002
|
||||
EPICYON_DOMAIN_NAME=$(cat "${epicyonInstallDir}/config.json" | awk -F '"domain":' '{print $2}' | awk -F '"' '{print $2}')
|
||||
for d in ${epicyonInstallDir}/accounts/*/ ; do
|
||||
if [[ "$d" != *'@'* ]]; then
|
||||
continue
|
||||
fi
|
||||
epicyonDir="${d::-1}"
|
||||
USERNAME=$(echo "$epicyonDir" | awk -F '/' '{print $5}' | awk -F '@' '{print $1}')
|
||||
if [[ "$d" != *'@'* ]]; then
|
||||
continue
|
||||
fi
|
||||
epicyonDir="${d::-1}"
|
||||
USERNAME=$(echo "$epicyonDir" | awk -F '/' '{print $5}' | awk -F '@' '{print $1}')
|
||||
|
||||
# send notifications for calendar events to XMPP/email users
|
||||
epicyonCalendarfile="$epicyonDir/.newCalendar"
|
||||
if [ -f "$epicyonCalendarfile" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonCalendarfile"; then
|
||||
epicyonCalendarmessage=$(notification_translate_text 'New calendar event')
|
||||
epicyonCalendarmessage=$(notification_translate_text 'Calendar')
|
||||
epicyonCalendarfileContent=$(echo "$epicyonCalendarmessage")" "$(cat "$epicyonCalendarfile")
|
||||
if [[ "$epicyonCalendarfileContent" == '/calendar'* ]]; then
|
||||
epicyonCalendarmessage="Epicyon: ${EPICYON_DOMAIN_NAME}/users/${USERNAME}${epicyonCalendarfileContent}"
|
||||
fi
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonCalendarmessage"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonCalendarmessage"
|
||||
echo "##sent##" >> "$epicyonCalendarfile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonCalendarfile"
|
||||
fi
|
||||
|
|
@ -171,12 +189,12 @@ function notifications {
|
|||
epicyonDMfile="$epicyonDir/.newDM"
|
||||
if [ -f "$epicyonDMfile" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonDMfile"; then
|
||||
epicyonDMmessage=$(notification_translate_text 'New direct message')
|
||||
epicyonDMmessage=$(notification_translate_text 'DM')
|
||||
epicyonDMfileContent=$(echo "$epicyonDMmessage")" "$(cat "$epicyonDMfile")
|
||||
if [[ "$epicyonDMfileContent" == *':'* ]]; then
|
||||
epicyonDMmessage="Epicyon: $epicyonDMfileContent"
|
||||
fi
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonDMmessage"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonDMmessage"
|
||||
echo "##sent##" > "$epicyonDMfile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonDMfile"
|
||||
fi
|
||||
|
|
@ -186,7 +204,7 @@ function notifications {
|
|||
epicyonLikeFile="$epicyonDir/.newLike"
|
||||
if [ -f "$epicyonLikeFile" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonLikeFile"; then
|
||||
epicyonLikeMessage=$(notification_translate_text 'liked your post')
|
||||
epicyonLikeMessage=$(notification_translate_text 'Liked by')
|
||||
epicyonLikeFileContent=$(cat "$epicyonLikeFile" | awk -F ' ' '{print $1}')" "$(echo "$epicyonLikeMessage")" "$(cat "$epicyonLikeFile" | awk -F ' ' '{print $2}')
|
||||
if [[ "$epicyonLikeFileContent" == *':'* ]]; then
|
||||
epicyonLikeMessage="Epicyon: $epicyonLikeFileContent"
|
||||
|
|
@ -201,12 +219,12 @@ function notifications {
|
|||
epicyonReplyFile="$epicyonDir/.newReply"
|
||||
if [ -f "$epicyonReplyFile" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonReplyFile"; then
|
||||
epicyonReplyMessage=$(notification_translate_text 'New reply')
|
||||
epicyonReplyMessage=$(notification_translate_text 'Replies')
|
||||
epicyonReplyFileContent=$(echo "$epicyonReplyMessage")" "$(cat "$epicyonReplyFile")
|
||||
if [[ "$epicyonReplyFileContent" == *':'* ]]; then
|
||||
epicyonReplyMessage="Epicyon: $epicyonReplyFileContent"
|
||||
fi
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonReplyMessage"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonReplyMessage"
|
||||
echo "##sent##" > "$epicyonReplyFile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonReplyFile"
|
||||
fi
|
||||
|
|
@ -216,18 +234,18 @@ function notifications {
|
|||
epicyonPatchFile="$epicyonDir/.newPatch"
|
||||
if [ -f "$epicyonPatchFile" ]; then
|
||||
if [ -f "${epicyonPatchFile}Content" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonPatchFile"; then
|
||||
epicyonPatchMessage=$(cat "$epicyonPatchFile")
|
||||
if [ "$epicyonPatchMessage" ]; then
|
||||
# notify the member
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonPatchMessage"
|
||||
echo "##sent##" > "$epicyonPatchFile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonPatchFile"
|
||||
# send the patch to them by email
|
||||
cat "${epicyonPatchFile}Content" | mail -s "[Epicyon] $epicyonPatchMessage" "${USERNAME}@${HOSTNAME}"
|
||||
rm "${epicyonPatchFile}Content"
|
||||
fi
|
||||
fi
|
||||
if ! grep -q "##sent##" "$epicyonPatchFile"; then
|
||||
epicyonPatchMessage=$(cat "$epicyonPatchFile")
|
||||
if [ "$epicyonPatchMessage" ]; then
|
||||
# notify the member
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonPatchMessage"
|
||||
echo "##sent##" > "$epicyonPatchFile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonPatchFile"
|
||||
# send the patch to them by email
|
||||
cat "${epicyonPatchFile}Content" | mail -s "[Epicyon] $epicyonPatchMessage" "${USERNAME}@${HOSTNAME}"
|
||||
rm "${epicyonPatchFile}Content"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
@ -235,12 +253,12 @@ function notifications {
|
|||
epicyonShareFile="$epicyonDir/.newShare"
|
||||
if [ -f "$epicyonShareFile" ]; then
|
||||
if ! grep -q "##sent##" "$epicyonShareFile"; then
|
||||
epicyonShareMessage=$(notification_translate_text 'New shared item')
|
||||
epicyonShareMessage=$(notification_translate_text 'Shares')
|
||||
epicyonShareFileContent=$(echo "$epicyonShareMessage")" "$(cat "$epicyonShareFile")
|
||||
if [[ "$epicyonShareFileContent" == *':'* ]]; then
|
||||
epicyonShareMessage="Epicyon: $epicyonShareFileContent"
|
||||
fi
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonShareMessage"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonShareMessage"
|
||||
echo "##sent##" > "$epicyonShareFile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonShareFile"
|
||||
fi
|
||||
|
|
@ -265,8 +283,8 @@ function notifications {
|
|||
cp "$epicyonFollowFile" "$epicyonFollowNotificationsFile"
|
||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonFollowNotificationsFile"
|
||||
|
||||
epicyonFollowMessage=$(notification_translate_text "New follow request")" ${EPICYON_DOMAIN_NAME}/users/${USERNAME}/followers"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonFollowMessage"
|
||||
epicyonFollowMessage=$(notification_translate_text 'Approve follower requests')" ${EPICYON_DOMAIN_NAME}/users/${USERNAME}/followers"
|
||||
sendNotification "$USERNAME" "Epicyon" "$epicyonFollowMessage"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
|
@ -380,6 +380,9 @@ def _postToSpeakerJson(baseDir: str, nickname: str, domain: str,
|
|||
content = urllib.parse.unquote_plus(postJsonObject['object']['content'])
|
||||
content = html.unescape(content)
|
||||
content = content.replace('<p>', '').replace('</p>', ' ')
|
||||
# replace some emoji before removing html
|
||||
if ' <3' in content:
|
||||
content = content.replace(' <3', ' ' + translate['heart'])
|
||||
content = removeHtml(htmlReplaceQuoteMarks(content))
|
||||
content = speakerReplaceLinks(content, translate, detectedLinks)
|
||||
content = _speakerPronounce(baseDir, content, translate)
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "التصفية والحظر",
|
||||
"Role Assignment": "تعيين الدور",
|
||||
"Contact Details": "بيانات المتصل",
|
||||
"Background Images": "صور الخلفية"
|
||||
"Background Images": "صور الخلفية",
|
||||
"heart": "قلب",
|
||||
"counselor": "مستشار",
|
||||
"Counselors": "المستشارين"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtratge i bloqueig",
|
||||
"Role Assignment": "Assignació de funcions",
|
||||
"Contact Details": "Detalls de contacte",
|
||||
"Background Images": "Imatges de fons"
|
||||
"Background Images": "Imatges de fons",
|
||||
"heart": "cor",
|
||||
"counselor": "conseller",
|
||||
"Counselors": "Consellers"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Hidlo a Blocio",
|
||||
"Role Assignment": "Aseiniad Rôl",
|
||||
"Background Images": "Delweddau Cefndir",
|
||||
"Contact Details": "Manylion cyswllt"
|
||||
"Contact Details": "Manylion cyswllt",
|
||||
"heart": "galon",
|
||||
"counselor": "cynghorydd",
|
||||
"Counselors": "Cynghorwyr"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtern und Blockieren",
|
||||
"Role Assignment": "Rollenzuweisung",
|
||||
"Background Images": "Hintergrundbilder",
|
||||
"Contact Details": "Kontaktdetails"
|
||||
"Contact Details": "Kontaktdetails",
|
||||
"heart": "herz",
|
||||
"counselor": "Beraterin",
|
||||
"Counselors": "Berater"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtering and Blocking",
|
||||
"Role Assignment": "Role Assignment",
|
||||
"Contact Details": "Contact Details",
|
||||
"Background Images": "Background Images"
|
||||
"Background Images": "Background Images",
|
||||
"heart": "heart",
|
||||
"counselor": "counselor",
|
||||
"Counselors": "Counselors"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtrado y bloqueo",
|
||||
"Role Assignment": "Asignación de roles",
|
||||
"Background Images": "Imágenes de fondo",
|
||||
"Contact Details": "Detalles de contacto"
|
||||
"Contact Details": "Detalles de contacto",
|
||||
"heart": "corazón",
|
||||
"counselor": "Consejera",
|
||||
"Counselors": "Consejeras"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtrage et blocage",
|
||||
"Role Assignment": "Attribution de rôle",
|
||||
"Background Images": "Images d'arrière-plan",
|
||||
"Contact Details": "Détails du contact"
|
||||
"Contact Details": "Détails du contact",
|
||||
"heart": "cœur",
|
||||
"counselor": "Conseillère",
|
||||
"Counselors": "Conseillères"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Scagadh agus Blocáil",
|
||||
"Role Assignment": "Sannadh Róil",
|
||||
"Background Images": "Íomhánna Cúlra",
|
||||
"Contact Details": "Sonraí Teagmhála"
|
||||
"Contact Details": "Sonraí Teagmhála",
|
||||
"heart": "chroí",
|
||||
"counselor": "Comhairleoir",
|
||||
"Counselors": "Comhairleoirí"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "छानना और अवरुद्ध करना",
|
||||
"Role Assignment": "भूमिका असाइनमेंट",
|
||||
"Background Images": "पृष्ठभूमि छवियों",
|
||||
"Contact Details": "सम्पर्क करने का विवरण"
|
||||
"Contact Details": "सम्पर्क करने का विवरण",
|
||||
"heart": "दिल",
|
||||
"counselor": "काउंसलर",
|
||||
"Counselors": "सलाहकार"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtraggio e blocco",
|
||||
"Role Assignment": "Assegnazione del ruolo",
|
||||
"Background Images": "Immagini di sfondo",
|
||||
"Contact Details": "Dettagli del contatto"
|
||||
"Contact Details": "Dettagli del contatto",
|
||||
"heart": "cuore",
|
||||
"counselor": "Consulente",
|
||||
"Counselors": "Consiglieri"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "フィルタリングとブロッキング",
|
||||
"Role Assignment": "役割の割り当て",
|
||||
"Background Images": "背景画像",
|
||||
"Contact Details": "連絡先の詳細"
|
||||
"Contact Details": "連絡先の詳細",
|
||||
"heart": "ハート",
|
||||
"counselor": "カウンセラー",
|
||||
"Counselors": "カウンセラー"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Fîlterkirin û Astengkirin",
|
||||
"Role Assignment": "Erk Rol",
|
||||
"Contact Details": "Agahdariyên Têkiliyê",
|
||||
"Background Images": "Wêneyên Paşê"
|
||||
"Background Images": "Wêneyên Paşê",
|
||||
"heart": "dil",
|
||||
"counselor": "Pêşnîyarvan",
|
||||
"Counselors": "Selêwirmendan"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,5 +392,8 @@
|
|||
"Filtering and Blocking": "Filtering and Blocking",
|
||||
"Role Assignment": "Role Assignment",
|
||||
"Background Images": "Background Images",
|
||||
"Contact Details": "Contact Details"
|
||||
"Contact Details": "Contact Details",
|
||||
"heart": "heart",
|
||||
"counselor": "Counselors",
|
||||
"Counselors": "Counselors"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Filtragem e Bloqueio",
|
||||
"Role Assignment": "Atribuição de Função",
|
||||
"Background Images": "Imagens de fundo",
|
||||
"Contact Details": "Detalhes do contato"
|
||||
"Contact Details": "Detalhes do contato",
|
||||
"heart": "coração",
|
||||
"counselor": "Conselheira",
|
||||
"Counselors": "Conselheiras"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "Фильтрация и блокировка",
|
||||
"Role Assignment": "Назначение ролей",
|
||||
"Background Images": "Фоновые изображения",
|
||||
"Contact Details": "Контактная информация"
|
||||
"Contact Details": "Контактная информация",
|
||||
"heart": "сердце",
|
||||
"counselor": "Советник",
|
||||
"Counselors": "Советники"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -396,5 +396,8 @@
|
|||
"Filtering and Blocking": "过滤和阻止",
|
||||
"Role Assignment": "角色分配",
|
||||
"Background Images": "背景图片",
|
||||
"Contact Details": "联系方式"
|
||||
"Contact Details": "联系方式",
|
||||
"heart": "心",
|
||||
"counselor": "顾问",
|
||||
"Counselors": "辅导员"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1387,6 +1387,20 @@ def htmlEditProfile(cssCache: {}, translate: {}, baseDir: str, path: str,
|
|||
' <textarea id="message" name="editors" placeholder="" ' + \
|
||||
'style="height:200px" spellcheck="false">' + \
|
||||
editors + '</textarea>'
|
||||
|
||||
# counselors
|
||||
counselors = ''
|
||||
counselorsFile = baseDir + '/accounts/counselors.txt'
|
||||
if os.path.isfile(counselorsFile):
|
||||
with open(counselorsFile, "r") as f:
|
||||
counselors = f.read()
|
||||
roleAssignStr += ' <b><label class="labels">' + \
|
||||
translate['Counselors'] + '</label></b><br>\n'
|
||||
roleAssignStr += \
|
||||
' <textarea id="message" name="counselors" ' + \
|
||||
'placeholder="" ' + \
|
||||
'style="height:200px" spellcheck="false">' + \
|
||||
counselors + '</textarea>'
|
||||
roleAssignStr += ' </div></details>\n'
|
||||
|
||||
# Video section
|
||||
|
|
|
|||
Loading…
Reference in New Issue