mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon
commit
c23bbdff2e
|
|
@ -26,6 +26,7 @@ from posts import getPersonBox
|
||||||
from utils import loadJson
|
from utils import loadJson
|
||||||
from utils import saveJson
|
from utils import saveJson
|
||||||
from utils import isAccountDir
|
from utils import isAccountDir
|
||||||
|
from utils import getUserPaths
|
||||||
from acceptreject import createAccept
|
from acceptreject import createAccept
|
||||||
from acceptreject import createReject
|
from acceptreject import createReject
|
||||||
from webfinger import webfingerHandle
|
from webfinger import webfingerHandle
|
||||||
|
|
@ -221,7 +222,7 @@ def isFollowerOfPerson(baseDir: str, nickname: str, domain: str,
|
||||||
if handle in followersStr:
|
if handle in followersStr:
|
||||||
alreadyFollowing = True
|
alreadyFollowing = True
|
||||||
else:
|
else:
|
||||||
paths = ('/profile/', '/channel/', '/accounts/', '/u/')
|
paths = getUserPaths()
|
||||||
for userPath in paths:
|
for userPath in paths:
|
||||||
url = '://' + followerDomain + userPath + followerNickname
|
url = '://' + followerDomain + userPath + followerNickname
|
||||||
if url in followersStr:
|
if url in followersStr:
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ from follow import removeFromFollowRequests
|
||||||
from utils import loadJson
|
from utils import loadJson
|
||||||
from utils import removeDomainPort
|
from utils import removeDomainPort
|
||||||
from utils import getPortFromDomain
|
from utils import getPortFromDomain
|
||||||
|
from utils import getUserPaths
|
||||||
|
|
||||||
|
|
||||||
def manualDenyFollowRequest(session, baseDir: str,
|
def manualDenyFollowRequest(session, baseDir: str,
|
||||||
|
|
@ -111,7 +112,7 @@ def manualApproveFollowRequest(session, baseDir: str,
|
||||||
reqNick = approveHandle.split('@')[0]
|
reqNick = approveHandle.split('@')[0]
|
||||||
reqDomain = approveHandle.split('@')[1].strip()
|
reqDomain = approveHandle.split('@')[1].strip()
|
||||||
reqPrefix = httpPrefix + '://' + reqDomain
|
reqPrefix = httpPrefix + '://' + reqDomain
|
||||||
paths = ('/profile/', '/channel/', '/accounts/', '/u/')
|
paths = getUserPaths()
|
||||||
for userPath in paths:
|
for userPath in paths:
|
||||||
if reqPrefix + userPath + reqNick in approveFollowsStr:
|
if reqPrefix + userPath + reqNick in approveFollowsStr:
|
||||||
exists = True
|
exists = True
|
||||||
|
|
|
||||||
13
person.py
13
person.py
|
|
@ -50,6 +50,7 @@ from utils import getProtocolPrefixes
|
||||||
from utils import hasUsersPath
|
from utils import hasUsersPath
|
||||||
from utils import getImageExtensions
|
from utils import getImageExtensions
|
||||||
from utils import isImageFile
|
from utils import isImageFile
|
||||||
|
from utils import getUserPaths
|
||||||
from session import createSession
|
from session import createSession
|
||||||
from session import getJson
|
from session import getJson
|
||||||
from webfinger import webfingerHandle
|
from webfinger import webfingerHandle
|
||||||
|
|
@ -1211,9 +1212,7 @@ def getActorJson(hostDomain: str, handle: str, http: bool, gnunet: bool,
|
||||||
for prefix in prefixes:
|
for prefix in prefixes:
|
||||||
handle = handle.replace(prefix, '')
|
handle = handle.replace(prefix, '')
|
||||||
handle = handle.replace('/@', '/users/')
|
handle = handle.replace('/@', '/users/')
|
||||||
paths = (
|
paths = getUserPaths()
|
||||||
'/users/', '/profile/', '/channel/', '/accounts/', '/u/'
|
|
||||||
)
|
|
||||||
userPathFound = False
|
userPathFound = False
|
||||||
for userPath in paths:
|
for userPath in paths:
|
||||||
if userPath in handle:
|
if userPath in handle:
|
||||||
|
|
@ -1302,11 +1301,9 @@ def getActorJson(hostDomain: str, handle: str, http: bool, gnunet: bool,
|
||||||
if not personUrl:
|
if not personUrl:
|
||||||
personUrl = getUserUrl(wfRequest, 0, debug)
|
personUrl = getUserUrl(wfRequest, 0, debug)
|
||||||
if nickname == domain:
|
if nickname == domain:
|
||||||
personUrl = personUrl.replace('/users/', '/actor/')
|
paths = getUserPaths()
|
||||||
personUrl = personUrl.replace('/accounts/', '/actor/')
|
for userPath in paths:
|
||||||
personUrl = personUrl.replace('/channel/', '/actor/')
|
personUrl = personUrl.replace(userPath, '/actor/')
|
||||||
personUrl = personUrl.replace('/profile/', '/actor/')
|
|
||||||
personUrl = personUrl.replace('/u/', '/actor/')
|
|
||||||
if not personUrl:
|
if not personUrl:
|
||||||
# try single user instance
|
# try single user instance
|
||||||
personUrl = httpPrefix + '://' + domain + '/' + nickname
|
personUrl = httpPrefix + '://' + domain + '/' + nickname
|
||||||
|
|
|
||||||
307
utils.py
307
utils.py
|
|
@ -842,7 +842,7 @@ def getNicknameFromActor(actor: str) -> str:
|
||||||
"""
|
"""
|
||||||
if actor.startswith('@'):
|
if actor.startswith('@'):
|
||||||
actor = actor[1:]
|
actor = actor[1:]
|
||||||
usersPaths = ('/users/', '/profile/', '/channel/', '/accounts/', '/u/')
|
usersPaths = getUserPaths()
|
||||||
for possiblePath in usersPaths:
|
for possiblePath in usersPaths:
|
||||||
if possiblePath in actor:
|
if possiblePath in actor:
|
||||||
nickStr = actor.split(possiblePath)[1].replace('@', '')
|
nickStr = actor.split(possiblePath)[1].replace('@', '')
|
||||||
|
|
@ -872,6 +872,12 @@ def getNicknameFromActor(actor: str) -> str:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def getUserPaths() -> []:
|
||||||
|
"""Returns possible user paths
|
||||||
|
"""
|
||||||
|
return ('/users/', '/profile/', '/accounts/', '/channel/', '/u/')
|
||||||
|
|
||||||
|
|
||||||
def getDomainFromActor(actor: str) -> (str, int):
|
def getDomainFromActor(actor: str) -> (str, int):
|
||||||
"""Returns the domain name from an actor url
|
"""Returns the domain name from an actor url
|
||||||
"""
|
"""
|
||||||
|
|
@ -879,7 +885,7 @@ def getDomainFromActor(actor: str) -> (str, int):
|
||||||
actor = actor[1:]
|
actor = actor[1:]
|
||||||
port = None
|
port = None
|
||||||
prefixes = getProtocolPrefixes()
|
prefixes = getProtocolPrefixes()
|
||||||
usersPaths = ('/users/', '/profile/', '/accounts/', '/channel/', '/u/')
|
usersPaths = getUserPaths()
|
||||||
for possiblePath in usersPaths:
|
for possiblePath in usersPaths:
|
||||||
if possiblePath in actor:
|
if possiblePath in actor:
|
||||||
domain = actor.split(possiblePath)[0]
|
domain = actor.split(possiblePath)[0]
|
||||||
|
|
@ -1222,125 +1228,193 @@ def _isReplyToBlogPost(baseDir: str, nickname: str, domain: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def _deletePostRemoveReplies(baseDir: str, nickname: str, domain: str,
|
||||||
|
httpPrefix: str, postFilename: str,
|
||||||
|
recentPostsCache: {}, debug: bool) -> None:
|
||||||
|
"""Removes replies when deleting a post
|
||||||
|
"""
|
||||||
|
repliesFilename = postFilename.replace('.json', '.replies')
|
||||||
|
if not os.path.isfile(repliesFilename):
|
||||||
|
return
|
||||||
|
if debug:
|
||||||
|
print('DEBUG: removing replies to ' + postFilename)
|
||||||
|
with open(repliesFilename, 'r') as f:
|
||||||
|
for replyId in f:
|
||||||
|
replyFile = locatePost(baseDir, nickname, domain, replyId)
|
||||||
|
if not replyFile:
|
||||||
|
continue
|
||||||
|
if os.path.isfile(replyFile):
|
||||||
|
deletePost(baseDir, httpPrefix,
|
||||||
|
nickname, domain, replyFile, debug,
|
||||||
|
recentPostsCache)
|
||||||
|
# remove the replies file
|
||||||
|
os.remove(repliesFilename)
|
||||||
|
|
||||||
|
|
||||||
|
def _isBookmarked(baseDir: str, nickname: str, domain: str,
|
||||||
|
postFilename: str) -> bool:
|
||||||
|
"""Returns True if the given post is bookmarked
|
||||||
|
"""
|
||||||
|
bookmarksIndexFilename = \
|
||||||
|
baseDir + '/accounts/' + nickname + '@' + domain + \
|
||||||
|
'/bookmarks.index'
|
||||||
|
if os.path.isfile(bookmarksIndexFilename):
|
||||||
|
bookmarkIndex = postFilename.split('/')[-1] + '\n'
|
||||||
|
if bookmarkIndex in open(bookmarksIndexFilename).read():
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def removePostFromCache(postJsonObject: {}, recentPostsCache: {}) -> None:
|
||||||
|
""" if the post exists in the recent posts cache then remove it
|
||||||
|
"""
|
||||||
|
if not recentPostsCache:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not postJsonObject.get('id'):
|
||||||
|
return
|
||||||
|
|
||||||
|
if not recentPostsCache.get('index'):
|
||||||
|
return
|
||||||
|
|
||||||
|
postId = postJsonObject['id']
|
||||||
|
if '#' in postId:
|
||||||
|
postId = postId.split('#', 1)[0]
|
||||||
|
postId = removeIdEnding(postId).replace('/', '#')
|
||||||
|
if postId not in recentPostsCache['index']:
|
||||||
|
return
|
||||||
|
|
||||||
|
if recentPostsCache.get('index'):
|
||||||
|
if postId in recentPostsCache['index']:
|
||||||
|
recentPostsCache['index'].remove(postId)
|
||||||
|
|
||||||
|
if recentPostsCache.get('json'):
|
||||||
|
if recentPostsCache['json'].get(postId):
|
||||||
|
del recentPostsCache['json'][postId]
|
||||||
|
|
||||||
|
if recentPostsCache.get('html'):
|
||||||
|
if recentPostsCache['html'].get(postId):
|
||||||
|
del recentPostsCache['html'][postId]
|
||||||
|
|
||||||
|
|
||||||
|
def _deleteCachedHtml(baseDir: str, nickname: str, domain: str,
|
||||||
|
postJsonObject: {}):
|
||||||
|
"""Removes cached html file for the given post
|
||||||
|
"""
|
||||||
|
cachedPostFilename = \
|
||||||
|
getCachedPostFilename(baseDir, nickname, domain, postJsonObject)
|
||||||
|
if cachedPostFilename:
|
||||||
|
if os.path.isfile(cachedPostFilename):
|
||||||
|
os.remove(cachedPostFilename)
|
||||||
|
|
||||||
|
|
||||||
|
def _deleteHashtagsOnPost(baseDir: str, postJsonObject: {}) -> None:
|
||||||
|
"""Removes hashtags when a post is deleted
|
||||||
|
"""
|
||||||
|
removeHashtagIndex = False
|
||||||
|
if hasObjectDict(postJsonObject):
|
||||||
|
if postJsonObject['object'].get('content'):
|
||||||
|
if '#' in postJsonObject['object']['content']:
|
||||||
|
removeHashtagIndex = True
|
||||||
|
|
||||||
|
if not removeHashtagIndex:
|
||||||
|
return
|
||||||
|
|
||||||
|
if not postJsonObject['object'].get('id') or \
|
||||||
|
not postJsonObject['object'].get('tag'):
|
||||||
|
return
|
||||||
|
|
||||||
|
# get the id of the post
|
||||||
|
postId = removeIdEnding(postJsonObject['object']['id'])
|
||||||
|
for tag in postJsonObject['object']['tag']:
|
||||||
|
if tag['type'] != 'Hashtag':
|
||||||
|
continue
|
||||||
|
if not tag.get('name'):
|
||||||
|
continue
|
||||||
|
# find the index file for this tag
|
||||||
|
tagIndexFilename = baseDir + '/tags/' + tag['name'][1:] + '.txt'
|
||||||
|
if not os.path.isfile(tagIndexFilename):
|
||||||
|
continue
|
||||||
|
# remove postId from the tag index file
|
||||||
|
lines = None
|
||||||
|
with open(tagIndexFilename, "r") as f:
|
||||||
|
lines = f.readlines()
|
||||||
|
if not lines:
|
||||||
|
continue
|
||||||
|
newlines = ''
|
||||||
|
for fileLine in lines:
|
||||||
|
if postId in fileLine:
|
||||||
|
# skip over the deleted post
|
||||||
|
continue
|
||||||
|
newlines += fileLine
|
||||||
|
if not newlines.strip():
|
||||||
|
# if there are no lines then remove the hashtag file
|
||||||
|
os.remove(tagIndexFilename)
|
||||||
|
else:
|
||||||
|
# write the new hashtag index without the given post in it
|
||||||
|
with open(tagIndexFilename, "w+") as f:
|
||||||
|
f.write(newlines)
|
||||||
|
|
||||||
|
|
||||||
def deletePost(baseDir: str, httpPrefix: str,
|
def deletePost(baseDir: str, httpPrefix: str,
|
||||||
nickname: str, domain: str, postFilename: str,
|
nickname: str, domain: str, postFilename: str,
|
||||||
debug: bool, recentPostsCache: {}) -> None:
|
debug: bool, recentPostsCache: {}) -> None:
|
||||||
"""Recursively deletes a post and its replies and attachments
|
"""Recursively deletes a post and its replies and attachments
|
||||||
"""
|
"""
|
||||||
postJsonObject = loadJson(postFilename, 1)
|
postJsonObject = loadJson(postFilename, 1)
|
||||||
if postJsonObject:
|
if not postJsonObject:
|
||||||
# don't allow deletion of bookmarked posts
|
# remove any replies
|
||||||
bookmarksIndexFilename = \
|
_deletePostRemoveReplies(baseDir, nickname, domain,
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain + \
|
httpPrefix, postFilename,
|
||||||
'/bookmarks.index'
|
recentPostsCache, debug)
|
||||||
if os.path.isfile(bookmarksIndexFilename):
|
# finally, remove the post itself
|
||||||
bookmarkIndex = postFilename.split('/')[-1] + '\n'
|
os.remove(postFilename)
|
||||||
if bookmarkIndex in open(bookmarksIndexFilename).read():
|
return
|
||||||
return
|
|
||||||
|
|
||||||
# don't remove replies to blog posts
|
# don't allow deletion of bookmarked posts
|
||||||
if _isReplyToBlogPost(baseDir, nickname, domain,
|
if _isBookmarked(baseDir, nickname, domain, postFilename):
|
||||||
postJsonObject):
|
return
|
||||||
return
|
|
||||||
|
|
||||||
# remove from recent posts cache in memory
|
# don't remove replies to blog posts
|
||||||
if recentPostsCache:
|
if _isReplyToBlogPost(baseDir, nickname, domain,
|
||||||
postId = \
|
postJsonObject):
|
||||||
removeIdEnding(postJsonObject['id']).replace('/', '#')
|
return
|
||||||
if recentPostsCache.get('index'):
|
|
||||||
if postId in recentPostsCache['index']:
|
|
||||||
recentPostsCache['index'].remove(postId)
|
|
||||||
if recentPostsCache.get('json'):
|
|
||||||
if recentPostsCache['json'].get(postId):
|
|
||||||
del recentPostsCache['json'][postId]
|
|
||||||
if recentPostsCache.get('html'):
|
|
||||||
if recentPostsCache['html'].get(postId):
|
|
||||||
del recentPostsCache['html'][postId]
|
|
||||||
|
|
||||||
# remove any attachment
|
# remove from recent posts cache in memory
|
||||||
_removeAttachment(baseDir, httpPrefix, domain, postJsonObject)
|
removePostFromCache(postJsonObject, recentPostsCache)
|
||||||
|
|
||||||
extensions = ('votes', 'arrived', 'muted', 'tts', 'reject')
|
# remove any attachment
|
||||||
for ext in extensions:
|
_removeAttachment(baseDir, httpPrefix, domain, postJsonObject)
|
||||||
extFilename = postFilename + '.' + ext
|
|
||||||
if os.path.isfile(extFilename):
|
|
||||||
os.remove(extFilename)
|
|
||||||
|
|
||||||
# remove cached html version of the post
|
extensions = ('votes', 'arrived', 'muted', 'tts', 'reject')
|
||||||
cachedPostFilename = \
|
for ext in extensions:
|
||||||
getCachedPostFilename(baseDir, nickname, domain, postJsonObject)
|
extFilename = postFilename + '.' + ext
|
||||||
if cachedPostFilename:
|
if os.path.isfile(extFilename):
|
||||||
if os.path.isfile(cachedPostFilename):
|
os.remove(extFilename)
|
||||||
os.remove(cachedPostFilename)
|
|
||||||
# removePostFromCache(postJsonObject,recentPostsCache)
|
|
||||||
|
|
||||||
hasObject = False
|
# remove cached html version of the post
|
||||||
if postJsonObject.get('object'):
|
_deleteCachedHtml(baseDir, nickname, domain, postJsonObject)
|
||||||
hasObject = True
|
|
||||||
|
|
||||||
# remove from moderation index file
|
hasObject = False
|
||||||
if hasObject:
|
if postJsonObject.get('object'):
|
||||||
if isinstance(postJsonObject['object'], dict):
|
hasObject = True
|
||||||
if postJsonObject['object'].get('moderationStatus'):
|
|
||||||
if postJsonObject.get('id'):
|
|
||||||
postId = removeIdEnding(postJsonObject['id'])
|
|
||||||
removeModerationPostFromIndex(baseDir, postId, debug)
|
|
||||||
|
|
||||||
# remove any hashtags index entries
|
# remove from moderation index file
|
||||||
removeHashtagIndex = False
|
if hasObject:
|
||||||
if hasObject:
|
if isinstance(postJsonObject['object'], dict):
|
||||||
if hasObject and isinstance(postJsonObject['object'], dict):
|
if postJsonObject['object'].get('moderationStatus'):
|
||||||
if postJsonObject['object'].get('content'):
|
if postJsonObject.get('id'):
|
||||||
if '#' in postJsonObject['object']['content']:
|
postId = removeIdEnding(postJsonObject['id'])
|
||||||
removeHashtagIndex = True
|
removeModerationPostFromIndex(baseDir, postId, debug)
|
||||||
if removeHashtagIndex:
|
|
||||||
if postJsonObject['object'].get('id') and \
|
# remove any hashtags index entries
|
||||||
postJsonObject['object'].get('tag'):
|
if hasObject:
|
||||||
# get the id of the post
|
_deleteHashtagsOnPost(baseDir, postJsonObject)
|
||||||
postId = removeIdEnding(postJsonObject['object']['id'])
|
|
||||||
for tag in postJsonObject['object']['tag']:
|
|
||||||
if tag['type'] != 'Hashtag':
|
|
||||||
continue
|
|
||||||
if not tag.get('name'):
|
|
||||||
continue
|
|
||||||
# find the index file for this tag
|
|
||||||
tagIndexFilename = \
|
|
||||||
baseDir + '/tags/' + tag['name'][1:] + '.txt'
|
|
||||||
if not os.path.isfile(tagIndexFilename):
|
|
||||||
continue
|
|
||||||
# remove postId from the tag index file
|
|
||||||
lines = None
|
|
||||||
with open(tagIndexFilename, "r") as f:
|
|
||||||
lines = f.readlines()
|
|
||||||
if lines:
|
|
||||||
newlines = ''
|
|
||||||
for fileLine in lines:
|
|
||||||
if postId in fileLine:
|
|
||||||
continue
|
|
||||||
newlines += fileLine
|
|
||||||
if not newlines.strip():
|
|
||||||
# if there are no lines then remove the
|
|
||||||
# hashtag file
|
|
||||||
os.remove(tagIndexFilename)
|
|
||||||
else:
|
|
||||||
with open(tagIndexFilename, "w+") as f:
|
|
||||||
f.write(newlines)
|
|
||||||
|
|
||||||
# remove any replies
|
# remove any replies
|
||||||
repliesFilename = postFilename.replace('.json', '.replies')
|
_deletePostRemoveReplies(baseDir, nickname, domain,
|
||||||
if os.path.isfile(repliesFilename):
|
httpPrefix, postFilename,
|
||||||
if debug:
|
recentPostsCache, debug)
|
||||||
print('DEBUG: removing replies to ' + postFilename)
|
|
||||||
with open(repliesFilename, 'r') as f:
|
|
||||||
for replyId in f:
|
|
||||||
replyFile = locatePost(baseDir, nickname, domain, replyId)
|
|
||||||
if replyFile:
|
|
||||||
if os.path.isfile(replyFile):
|
|
||||||
deletePost(baseDir, httpPrefix,
|
|
||||||
nickname, domain, replyFile, debug,
|
|
||||||
recentPostsCache)
|
|
||||||
# remove the replies file
|
|
||||||
os.remove(repliesFilename)
|
|
||||||
# finally, remove the post itself
|
# finally, remove the post itself
|
||||||
os.remove(postFilename)
|
os.remove(postFilename)
|
||||||
|
|
||||||
|
|
@ -1543,29 +1617,6 @@ def getCachedPostFilename(baseDir: str, nickname: str, domain: str,
|
||||||
return cachedPostFilename + '.html'
|
return cachedPostFilename + '.html'
|
||||||
|
|
||||||
|
|
||||||
def removePostFromCache(postJsonObject: {}, recentPostsCache: {}):
|
|
||||||
""" if the post exists in the recent posts cache then remove it
|
|
||||||
"""
|
|
||||||
if not postJsonObject.get('id'):
|
|
||||||
return
|
|
||||||
|
|
||||||
if not recentPostsCache.get('index'):
|
|
||||||
return
|
|
||||||
|
|
||||||
postId = postJsonObject['id']
|
|
||||||
if '#' in postId:
|
|
||||||
postId = postId.split('#', 1)[0]
|
|
||||||
postId = removeIdEnding(postId).replace('/', '#')
|
|
||||||
if postId not in recentPostsCache['index']:
|
|
||||||
return
|
|
||||||
|
|
||||||
if recentPostsCache['json'].get(postId):
|
|
||||||
del recentPostsCache['json'][postId]
|
|
||||||
if recentPostsCache['html'].get(postId):
|
|
||||||
del recentPostsCache['html'][postId]
|
|
||||||
recentPostsCache['index'].remove(postId)
|
|
||||||
|
|
||||||
|
|
||||||
def updateRecentPostsCache(recentPostsCache: {}, maxRecentPosts: int,
|
def updateRecentPostsCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
postJsonObject: {}, htmlStr: str) -> None:
|
postJsonObject: {}, htmlStr: str) -> None:
|
||||||
"""Store recent posts in memory so that they can be quickly recalled
|
"""Store recent posts in memory so that they can be quickly recalled
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue