mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main
commit
2c4fbbcef6
21
daemon.py
21
daemon.py
|
|
@ -1744,7 +1744,9 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
divertToLoginScreen = False
|
||||
else:
|
||||
if self.path.endswith('/following') or \
|
||||
'/following?page=' in self.path or \
|
||||
self.path.endswith('/followers') or \
|
||||
'/followers?page=' in self.path or \
|
||||
self.path.endswith('/skills') or \
|
||||
self.path.endswith('/roles') or \
|
||||
self.path.endswith('/shares'):
|
||||
|
|
@ -3444,6 +3446,13 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
|
||||
# get an individual post from the path /@nickname/statusnumber
|
||||
if '/@' in self.path:
|
||||
likedBy = None
|
||||
if '?likedBy=' in self.path:
|
||||
likedBy = self.path.split('?likedBy=')[1].strip()
|
||||
if '?' in likedBy:
|
||||
likedBy = likedBy.split('?')[0]
|
||||
self.path = self.path.split('?likedBy=')[0]
|
||||
|
||||
namedStatus = self.path.split('/@')[1]
|
||||
if '/' not in namedStatus:
|
||||
# show actor
|
||||
|
|
@ -3504,7 +3513,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
postJsonObject,
|
||||
httpPrefix,
|
||||
projectVersion)
|
||||
projectVersion,
|
||||
likedBy)
|
||||
msg = msg.encode('utf-8')
|
||||
self._set_headers('text/html', len(msg),
|
||||
cookie, callingDomain)
|
||||
|
|
@ -3897,6 +3907,12 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
# get an individual post from the path
|
||||
# /users/nickname/statuses/number
|
||||
if '/statuses/' in self.path and '/users/' in self.path:
|
||||
likedBy = None
|
||||
if '?likedBy=' in self.path:
|
||||
likedBy = self.path.split('?likedBy=')[1].strip()
|
||||
if '?' in likedBy:
|
||||
likedBy = likedBy.split('?')[0]
|
||||
self.path = self.path.split('?likedBy=')[0]
|
||||
namedStatus = self.path.split('/users/')[1]
|
||||
if '/' in namedStatus:
|
||||
postSections = namedStatus.split('/')
|
||||
|
|
@ -3957,7 +3973,8 @@ class PubServer(BaseHTTPRequestHandler):
|
|||
authorized,
|
||||
postJsonObject,
|
||||
httpPrefix,
|
||||
projectVersion)
|
||||
projectVersion,
|
||||
likedBy)
|
||||
msg = msg.encode('utf-8')
|
||||
self._set_headers('text/html',
|
||||
len(msg),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This can be called from a crontab entry to send notifications
|
||||
# when Epicyon events occur
|
||||
# when Epicyon events occur. You will need to have
|
||||
# sendxmpp+prosody or Synapse (matrix) installed.
|
||||
#
|
||||
# Something like:
|
||||
#
|
||||
# */1 * * * * root /usr/local/bin/epicyon-notification --epicyon yes
|
||||
#
|
||||
# License
|
||||
# =======
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ def removeFromFollowRejects(baseDir: str,
|
|||
|
||||
def isFollowingActor(baseDir: str,
|
||||
nickname: str, domain: str, actor: str) -> bool:
|
||||
"""Is the given actor a follower of the given nickname?
|
||||
"""Is the given nickname following the given actor?
|
||||
"""
|
||||
if ':' in domain:
|
||||
domain = domain.split(':')[0]
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.1 KiB |
48
inbox.py
48
inbox.py
|
|
@ -1032,11 +1032,16 @@ def receiveLike(recentPostsCache: {},
|
|||
if debug:
|
||||
print('DEBUG: liked post found in inbox')
|
||||
|
||||
updateLikesCollection(recentPostsCache, baseDir, postFilename,
|
||||
messageJson['object'],
|
||||
messageJson['actor'], domain, debug)
|
||||
likeNotify(baseDir, domain, onionDomain, handle,
|
||||
messageJson['actor'], messageJson['object'])
|
||||
if not alreadyLiked(baseDir,
|
||||
handle.split('@')[0],
|
||||
handle.split('@')[1],
|
||||
messageJson['object'],
|
||||
messageJson['actor']):
|
||||
updateLikesCollection(recentPostsCache, baseDir, postFilename,
|
||||
messageJson['object'],
|
||||
messageJson['actor'], domain, debug)
|
||||
likeNotify(baseDir, domain, onionDomain, handle,
|
||||
messageJson['actor'], messageJson['object'])
|
||||
return True
|
||||
|
||||
|
||||
|
|
@ -1706,6 +1711,37 @@ def dmNotify(baseDir: str, handle: str, url: str) -> None:
|
|||
fp.write(url)
|
||||
|
||||
|
||||
def alreadyLiked(baseDir: str, nickname: str, domain: str,
|
||||
postUrl: str, likerActor: str) -> bool:
|
||||
"""Is the given post already liked by the given handle?
|
||||
"""
|
||||
postFilename = \
|
||||
locatePost(baseDir, nickname, domain, postUrl)
|
||||
if not postFilename:
|
||||
return False
|
||||
postJsonObject = loadJson(postFilename, 1)
|
||||
if not postJsonObject:
|
||||
return False
|
||||
if not postJsonObject.get('object'):
|
||||
return False
|
||||
if not isinstance(postJsonObject['object'], dict):
|
||||
return False
|
||||
if not postJsonObject['object'].get('likes'):
|
||||
return False
|
||||
if not postJsonObject['object']['likes'].get('items'):
|
||||
return False
|
||||
for like in postJsonObject['object']['likes']['items']:
|
||||
if not like.get('type'):
|
||||
continue
|
||||
if not like.get('actor'):
|
||||
continue
|
||||
if like['type'] != 'Like':
|
||||
continue
|
||||
if like['actor'] == likerActor:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def likeNotify(baseDir: str, domain: str, onionDomain: str,
|
||||
handle: str, actor: str, url: str) -> None:
|
||||
"""Creates a notification that a like has arrived
|
||||
|
|
@ -1739,7 +1775,7 @@ def likeNotify(baseDir: str, domain: str, onionDomain: str,
|
|||
str(likerNickname) + '@' + str(likerDomain))
|
||||
likerHandle = actor
|
||||
if likerHandle != handle:
|
||||
likeStr = likerHandle + ' ' + url
|
||||
likeStr = likerHandle + ' ' + url + '?likedBy=' + actor
|
||||
prevLikeFile = accountDir + '/.prevLike'
|
||||
# was there a previous like notification?
|
||||
if os.path.isfile(prevLikeFile):
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "غير متوفره",
|
||||
"The server is busy. Please try again later": "الخادم مشغول. الرجاء معاودة المحاولة في وقت لاحق",
|
||||
"Receive calendar events from this account": "تلقي أحداث التقويم من هذا الحساب",
|
||||
"Grayscale": "درجات الرمادي"
|
||||
"Grayscale": "درجات الرمادي",
|
||||
"Liked by": "نال إعجاب"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "No disponible",
|
||||
"The server is busy. Please try again later": "El servidor està ocupat. Siusplau, intenta-ho més tard",
|
||||
"Receive calendar events from this account": "Rep esdeveniments del calendari des d’aquest compte",
|
||||
"Grayscale": "Escala de grisos"
|
||||
"Grayscale": "Escala de grisos",
|
||||
"Liked by": "M'agrada"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Ddim ar gael",
|
||||
"The server is busy. Please try again later": "Mae'r gweinydd yn brysur. Rho gynnig Arni eto'n hwyrach",
|
||||
"Receive calendar events from this account": "Derbyn digwyddiadau calendr o'r cyfrif hwn",
|
||||
"Grayscale": "Graddlwyd"
|
||||
"Grayscale": "Graddlwyd",
|
||||
"Liked by": "Hoffi"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Nicht verfügbar",
|
||||
"The server is busy. Please try again later": "Der Server ist beschäftigt. Bitte versuchen Sie es später noch einmal",
|
||||
"Receive calendar events from this account": "Erhalten Sie Kalenderereignisse von diesem Konto",
|
||||
"Grayscale": "Graustufen"
|
||||
"Grayscale": "Graustufen",
|
||||
"Liked by": "Gefallen von"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Unavailable",
|
||||
"The server is busy. Please try again later": "The server is busy. Please try again later",
|
||||
"Receive calendar events from this account": "Receive calendar events from this account",
|
||||
"Grayscale": "Grayscale"
|
||||
"Grayscale": "Grayscale",
|
||||
"Liked by": "Liked by"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Indisponible",
|
||||
"The server is busy. Please try again later": "El servidor esta ocupado. Por favor, inténtelo de nuevo más tarde",
|
||||
"Receive calendar events from this account": "Recibe eventos de calendario de esta cuenta",
|
||||
"Grayscale": "Escala de grises"
|
||||
"Grayscale": "Escala de grises",
|
||||
"Liked by": "Apreciado por"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Indisponible",
|
||||
"The server is busy. Please try again later": "Le serveur est occupé. Veuillez réessayer plus tard",
|
||||
"Receive calendar events from this account": "Recevoir des événements d'agenda de ce compte",
|
||||
"Grayscale": "Niveaux de gris"
|
||||
"Grayscale": "Niveaux de gris",
|
||||
"Liked by": "Aimé par"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Níl sé ar fáil",
|
||||
"The server is busy. Please try again later": "Tá an freastalaí gnóthach. Bain triail eile as níos déanaí",
|
||||
"Receive calendar events from this account": "Faigh imeachtaí féilire ón gcuntas seo",
|
||||
"Grayscale": "Liathscála"
|
||||
"Grayscale": "Liathscála",
|
||||
"Liked by": "Thaitin"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "अनुपलब्ध",
|
||||
"The server is busy. Please try again later": "सर्वर व्यस्त है। बाद में पुन: प्रयास करें",
|
||||
"Receive calendar events from this account": "इस खाते से कैलेंडर ईवेंट प्राप्त करें",
|
||||
"Grayscale": "ग्रेस्केल"
|
||||
"Grayscale": "ग्रेस्केल",
|
||||
"Liked by": "द्वारा पसंद किया गया"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "non disponibile",
|
||||
"The server is busy. Please try again later": "Il server è occupato. Per favore riprova più tardi",
|
||||
"Receive calendar events from this account": "Ricevi eventi di calendario da questo account",
|
||||
"Grayscale": "Scala di grigi"
|
||||
"Grayscale": "Scala di grigi",
|
||||
"Liked by": "Mi è piaciuto"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "利用できません",
|
||||
"The server is busy. Please try again later": "サーバーはビジーです。 後でもう一度やり直してください",
|
||||
"Receive calendar events from this account": "このアカウントからカレンダーイベントを受信します",
|
||||
"Grayscale": "グレースケール"
|
||||
"Grayscale": "グレースケール",
|
||||
"Liked by": "好き"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -247,5 +247,6 @@
|
|||
"Unavailable": "Unavailable",
|
||||
"The server is busy. Please try again later": "The server is busy. Please try again later",
|
||||
"Receive calendar events from this account": "Receive calendar events from this account",
|
||||
"Grayscale": "Grayscale"
|
||||
"Grayscale": "Grayscale",
|
||||
"Liked by": "Liked by"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Indisponível",
|
||||
"The server is busy. Please try again later": "O servidor está ocupado. Por favor, tente novamente mais tarde",
|
||||
"Receive calendar events from this account": "Receba eventos da agenda desta conta",
|
||||
"Grayscale": "Escala de cinza"
|
||||
"Grayscale": "Escala de cinza",
|
||||
"Liked by": "Curtida por"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,5 +251,6 @@
|
|||
"Unavailable": "Недоступен",
|
||||
"The server is busy. Please try again later": "Сервер занят. Пожалуйста, попробуйте позже",
|
||||
"Receive calendar events from this account": "Получать события календаря от этого аккаунта",
|
||||
"Grayscale": "Оттенки серого"
|
||||
"Grayscale": "Оттенки серого",
|
||||
"Liked by": "Понравилось"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,5 +250,6 @@
|
|||
"Unavailable": "不可用",
|
||||
"The server is busy. Please try again later": "服务器忙。 请稍后再试",
|
||||
"Receive calendar events from this account": "从该帐户接收日历事件",
|
||||
"Grayscale": "灰阶"
|
||||
"Grayscale": "灰阶",
|
||||
"Liked by": "喜欢的人"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2821,7 +2821,7 @@ def htmlProfile(defaultTimeline: str,
|
|||
domain, port, session,
|
||||
wfRequest, personCache, extraJson,
|
||||
projectVersion, ["unfollow"], selected,
|
||||
actor, pageNumber, maxItemsPerPage)
|
||||
usersPath, pageNumber, maxItemsPerPage)
|
||||
if selected == 'followers':
|
||||
profileStr += \
|
||||
htmlProfileFollowing(translate, baseDir, httpPrefix,
|
||||
|
|
@ -2829,7 +2829,7 @@ def htmlProfile(defaultTimeline: str,
|
|||
domain, port, session,
|
||||
wfRequest, personCache, extraJson,
|
||||
projectVersion, ["block"],
|
||||
selected, actor, pageNumber,
|
||||
selected, usersPath, pageNumber,
|
||||
maxItemsPerPage)
|
||||
if selected == 'roles':
|
||||
profileStr += \
|
||||
|
|
@ -4983,11 +4983,44 @@ def htmlIndividualPost(recentPostsCache: {}, maxRecentPosts: int,
|
|||
baseDir: str, session, wfRequest: {}, personCache: {},
|
||||
nickname: str, domain: str, port: int, authorized: bool,
|
||||
postJsonObject: {}, httpPrefix: str,
|
||||
projectVersion: str) -> str:
|
||||
projectVersion: str, likedBy: str) -> str:
|
||||
"""Show an individual post as html
|
||||
"""
|
||||
iconsDir = getIconsDir(baseDir)
|
||||
postStr = \
|
||||
postStr = ''
|
||||
if likedBy:
|
||||
likedByNickname = getNicknameFromActor(likedBy)
|
||||
likedByDomain, likedByPort = getDomainFromActor(likedBy)
|
||||
if likedByPort:
|
||||
if likedByPort != 80 and likedByPort != 443:
|
||||
likedByDomain += ':' + str(likedByPort)
|
||||
likedByHandle = likedByNickname + '@' + likedByDomain
|
||||
postStr += \
|
||||
'<p>' + translate['Liked by'] + \
|
||||
' <a href="' + likedBy + '">@' + \
|
||||
likedByHandle + '</a>'
|
||||
|
||||
domainFull = domain
|
||||
if port:
|
||||
if port != 80 and port != 443:
|
||||
domainFull = domain + ':' + str(port)
|
||||
actor = '/users/' + nickname
|
||||
followStr = ' <form method="POST" ' + \
|
||||
'accept-charset="UTF-8" action="' + actor + '/searchhandle">'
|
||||
followStr += \
|
||||
' <input type="hidden" name="actor" value="' + actor + '">'
|
||||
followStr += \
|
||||
' <input type="hidden" name="searchtext" value="' + \
|
||||
likedByHandle + '">'
|
||||
if not isFollowingActor(baseDir, nickname, domainFull, likedBy):
|
||||
followStr += ' <button type="submit" class="button" ' + \
|
||||
'name="submitSearch">' + translate['Follow'] + '</button>'
|
||||
followStr += ' <button type="submit" class="button" ' + \
|
||||
'name="submitBack">' + translate['Go Back'] + '</button>'
|
||||
followStr += ' </form>'
|
||||
postStr += followStr + '</p>\n'
|
||||
|
||||
postStr += \
|
||||
individualPostAsHtml(recentPostsCache, maxRecentPosts,
|
||||
iconsDir, translate, None,
|
||||
baseDir, session, wfRequest, personCache,
|
||||
|
|
|
|||
Loading…
Reference in New Issue