mirror of https://gitlab.com/bashrc2/epicyon
Tidying
parent
a6dc579aca
commit
fc2732a5ed
|
@ -58,9 +58,13 @@ def createAcceptReject(baseDir: str,federationList: [], \
|
|||
def createAccept(baseDir: str,federationList: [], \
|
||||
nickname: str,domain: str,port: int, \
|
||||
toUrl: str,ccUrl: str,httpPrefix: str, \
|
||||
objectJson: {},acceptedCaps=["inbox:write","objects:read"]) -> {}:
|
||||
objectJson: {}, \
|
||||
acceptedCaps=["inbox:write","objects:read"]) -> {}:
|
||||
# create capabilities accept
|
||||
ocapNew=capabilitiesAccept(baseDir,httpPrefix,nickname,domain,port,toUrl,True,acceptedCaps)
|
||||
ocapNew= \
|
||||
capabilitiesAccept(baseDir,httpPrefix, \
|
||||
nickname,domain,port, \
|
||||
toUrl,True,acceptedCaps)
|
||||
return createAcceptReject(baseDir,federationList, \
|
||||
nickname,domain,port, \
|
||||
toUrl,ccUrl,httpPrefix, \
|
||||
|
@ -126,7 +130,7 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
print('DEBUG: nickname not found in '+thisActor)
|
||||
return
|
||||
if acceptedPort:
|
||||
if not '/'+acceptedDomain+':'+str(acceptedPort)+'/users/'+nickname in thisActor:
|
||||
if '/'+acceptedDomain+':'+str(acceptedPort)+'/users/'+nickname not in thisActor:
|
||||
if debug:
|
||||
print('Port: '+str(acceptedPort))
|
||||
print('Expected: /'+acceptedDomain+':'+str(acceptedPort)+'/users/'+nickname)
|
||||
|
@ -134,7 +138,7 @@ def acceptFollow(baseDir: str,domain : str,messageJson: {}, \
|
|||
print('DEBUG: unrecognized actor '+thisActor)
|
||||
return
|
||||
else:
|
||||
if not '/'+acceptedDomain+'/users/'+nickname in thisActor:
|
||||
if '/'+acceptedDomain+'/users/'+nickname not in thisActor:
|
||||
if debug:
|
||||
print('Expected: /'+acceptedDomain+'/users/'+nickname)
|
||||
print('Actual: '+thisActor)
|
||||
|
|
13
announce.py
13
announce.py
|
@ -62,7 +62,8 @@ def outboxAnnounce(baseDir: str,messageJson: {},debug: bool) -> bool:
|
|||
return True
|
||||
return False
|
||||
|
||||
def undoAnnounceCollectionEntry(postFilename: str,actor: str,debug: bool) -> None:
|
||||
def undoAnnounceCollectionEntry(postFilename: str,actor: str, \
|
||||
debug: bool) -> None:
|
||||
"""Undoes an announce for a particular actor by removing it from the "shares"
|
||||
collection within a post. Note that the "shares" collection has no relation
|
||||
to shared items in shares.py. It's shares of posts, not shares of physical objects.
|
||||
|
@ -102,14 +103,15 @@ def undoAnnounceCollectionEntry(postFilename: str,actor: str,debug: bool) -> Non
|
|||
print('DEBUG: shares (announcements) was removed from post')
|
||||
del postJsonObject['object']['shares']
|
||||
else:
|
||||
postJsonObject['object']['shares']['totalItems']=len(postJsonObject['object']['shares']['items'])
|
||||
postJsonObject['object']['shares']['totalItems']= \
|
||||
len(postJsonObject['object']['shares']['items'])
|
||||
with open(postFilename, 'w') as fp:
|
||||
commentjson.dump(postJsonObject, fp, indent=4, sort_keys=True)
|
||||
|
||||
def updateAnnounceCollection(postFilename: str,actor: str,debug: bool) -> None:
|
||||
"""Updates the announcements collection within a post
|
||||
Confusingly this is known as "shares", but isn't the same as shared items within shares.py
|
||||
It's shares of posts, not shares of physical objects.
|
||||
Confusingly this is known as "shares", but isn't the same as shared
|
||||
items within shares.py. It's shares of posts, not shares of physical objects.
|
||||
"""
|
||||
with open(postFilename, 'r') as fp:
|
||||
postJsonObject=commentjson.load(fp)
|
||||
|
@ -146,7 +148,8 @@ def updateAnnounceCollection(postFilename: str,actor: str,debug: bool) -> None:
|
|||
'actor': actor
|
||||
}
|
||||
postJsonObject['object']['shares']['items'].append(newAnnounce)
|
||||
postJsonObject['object']['shares']['totalItems']=len(postJsonObject['object']['shares']['items'])
|
||||
postJsonObject['object']['shares']['totalItems']= \
|
||||
len(postJsonObject['object']['shares']['items'])
|
||||
else:
|
||||
if debug:
|
||||
print('DEBUG: shares (announcements) section of post has no items list')
|
||||
|
|
|
@ -46,7 +46,8 @@ def getAvailability(baseDir: str,nickname: str,domain: str) -> str:
|
|||
return actorJson['availability']
|
||||
return None
|
||||
|
||||
def outboxAvailability(baseDir: str,nickname: str,messageJson: {},debug: bool) -> bool:
|
||||
def outboxAvailability(baseDir: str,nickname: str,messageJson: {}, \
|
||||
debug: bool) -> bool:
|
||||
"""Handles receiving an availability update
|
||||
"""
|
||||
if not messageJson.get('type'):
|
||||
|
|
11
cache.py
11
cache.py
|
@ -11,7 +11,8 @@ import time
|
|||
import datetime
|
||||
import commentjson
|
||||
|
||||
def storePersonInCache(baseDir: str,personUrl: str,personJson: {},personCache: {}) -> None:
|
||||
def storePersonInCache(baseDir: str,personUrl: str, \
|
||||
personJson: {},personCache: {}) -> None:
|
||||
"""Store an actor in the cache
|
||||
"""
|
||||
currTime=datetime.datetime.utcnow()
|
||||
|
@ -35,7 +36,8 @@ def getPersonFromCache(baseDir: str,personUrl: str,personCache: {}) -> {}:
|
|||
# if the actor is not in memory then try to load it from file
|
||||
loadedFromFile=False
|
||||
if not personCache.get(personUrl):
|
||||
cacheFilename=baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json'
|
||||
cacheFilename= \
|
||||
baseDir+'/cache/actors/'+personUrl.replace('/','#')+'.json'
|
||||
if os.path.isfile(cacheFilename):
|
||||
personJson=None
|
||||
try:
|
||||
|
@ -52,11 +54,12 @@ def getPersonFromCache(baseDir: str,personUrl: str,personCache: {}) -> {}:
|
|||
if not loadedFromFile:
|
||||
# update the timestamp for the last time the actor was retrieved
|
||||
currTime=datetime.datetime.utcnow()
|
||||
personCache[personUrl]['timestamp']=currTime.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
personCache[personUrl]['timestamp']= \
|
||||
currTime.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||
return personCache[personUrl]['actor']
|
||||
return None
|
||||
|
||||
def expirePersonCache(personCache: {}):
|
||||
def expirePersonCache(personCache: {}) -> None:
|
||||
"""Expires old entries from the cache in memory
|
||||
"""
|
||||
currTime=datetime.datetime.utcnow()
|
||||
|
|
|
@ -15,7 +15,8 @@ from auth import createPassword
|
|||
from utils import getNicknameFromActor
|
||||
from utils import getDomainFromActor
|
||||
|
||||
def getOcapFilename(baseDir :str,nickname: str,domain: str,actor :str,subdir: str) -> str:
|
||||
def getOcapFilename(baseDir :str,nickname: str,domain: str, \
|
||||
actor :str,subdir: str) -> str:
|
||||
"""Returns the filename for a particular capability accepted or granted
|
||||
Also creates directories as needed
|
||||
"""
|
||||
|
@ -40,7 +41,8 @@ def getOcapFilename(baseDir :str,nickname: str,domain: str,actor :str,subdir: st
|
|||
if not os.path.isdir(ocDir):
|
||||
os.mkdir(ocDir)
|
||||
|
||||
return baseDir+'/accounts/'+nickname+'@'+domain+'/ocap/'+subdir+'/'+actor.replace('/','#')+'.json'
|
||||
return baseDir+'/accounts/'+nickname+'@'+domain+'/ocap/'+ \
|
||||
subdir+'/'+actor.replace('/','#')+'.json'
|
||||
|
||||
def CapablePost(postJson: {}, capabilityList: [], debug :bool) -> bool:
|
||||
"""Determines whether a post arriving in the inbox
|
||||
|
@ -120,7 +122,8 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str, \
|
|||
fullDomain=domain+':'+str(port)
|
||||
|
||||
# make directories to store capabilities
|
||||
ocapFilename=getOcapFilename(baseDir,nickname,fullDomain,acceptedActor,'accept')
|
||||
ocapFilename= \
|
||||
getOcapFilename(baseDir,nickname,fullDomain,acceptedActor,'accept')
|
||||
if not ocapFilename:
|
||||
return None
|
||||
ocapAccept=None
|
||||
|
@ -137,9 +140,11 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str, \
|
|||
return None
|
||||
acceptedActorDomain,acceptedActorPort=getDomainFromActor(acceptedActor)
|
||||
if acceptedActorPort:
|
||||
ocapId=acceptedActorNickname+'@'+acceptedActorDomain+':'+str(acceptedActorPort)+'#'+createPassword(32)
|
||||
ocapId=acceptedActorNickname+'@'+acceptedActorDomain+':'+ \
|
||||
str(acceptedActorPort)+'#'+createPassword(32)
|
||||
else:
|
||||
ocapId=acceptedActorNickname+'@'+acceptedActorDomain+'#'+createPassword(32)
|
||||
ocapId=acceptedActorNickname+'@'+acceptedActorDomain+'#'+ \
|
||||
createPassword(32)
|
||||
ocapAccept = {
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"id": httpPrefix+"://"+fullDomain+"/caps/"+ocapId,
|
||||
|
@ -156,13 +161,15 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str, \
|
|||
commentjson.dump(ocapAccept, fp, indent=4, sort_keys=False)
|
||||
return ocapAccept
|
||||
|
||||
def capabilitiesGrantedSave(baseDir :str,nickname :str,domain :str,ocap: {}) -> bool:
|
||||
def capabilitiesGrantedSave(baseDir :str, \
|
||||
nickname :str,domain :str,ocap: {}) -> bool:
|
||||
"""A capabilities accept is received, so stor it for
|
||||
reference when sending to the actor
|
||||
"""
|
||||
if not ocap.get('actor'):
|
||||
return False
|
||||
ocapFilename=getOcapFilename(baseDir,nickname,domain,ocap['actor'],'granted')
|
||||
ocapFilename= \
|
||||
getOcapFilename(baseDir,nickname,domain,ocap['actor'],'granted')
|
||||
if not ocapFilename:
|
||||
return False
|
||||
with open(ocapFilename, 'w') as fp:
|
||||
|
@ -189,7 +196,8 @@ def capabilitiesUpdate(baseDir: str,httpPrefix: str, \
|
|||
fullDomain=domain+':'+str(port)
|
||||
|
||||
# Get the filename of the capability
|
||||
ocapFilename=getOcapFilename(baseDir,nickname,fullDomain,updateActor,'accept')
|
||||
ocapFilename= \
|
||||
getOcapFilename(baseDir,nickname,fullDomain,updateActor,'accept')
|
||||
if not ocapFilename:
|
||||
return None
|
||||
|
||||
|
@ -221,7 +229,8 @@ def capabilitiesUpdate(baseDir: str,httpPrefix: str, \
|
|||
return None
|
||||
updateActorDomain,updateActorPort=getDomainFromActor(updateActor)
|
||||
if updateActorPort:
|
||||
ocapId=updateActorNickname+'@'+updateActorDomain+':'+str(updateActorPort)+'#'+createPassword(32)
|
||||
ocapId=updateActorNickname+'@'+updateActorDomain+':'+ \
|
||||
str(updateActorPort)+'#'+createPassword(32)
|
||||
else:
|
||||
ocapId=updateActorNickname+'@'+updateActorDomain+'#'+createPassword(32)
|
||||
ocapJson['id']=httpPrefix+"://"+fullDomain+"/caps/"+ocapId
|
||||
|
|
|
@ -32,7 +32,7 @@ def setConfigParam(baseDir: str, variableName: str, variableValue) -> None:
|
|||
with open(configFilename, 'w') as fp:
|
||||
commentjson.dump(configJson, fp, indent=4, sort_keys=True)
|
||||
|
||||
def getConfigParam(baseDir: str, variableName: str):
|
||||
def getConfigParam(baseDir: str, variableName: str) -> None:
|
||||
"""Gets a configuration value
|
||||
"""
|
||||
createConfig(baseDir)
|
||||
|
|
79
content.py
79
content.py
|
@ -30,13 +30,17 @@ def addMusicTag(content: str,tag: str) -> str:
|
|||
def addWebLinks(content: str) -> str:
|
||||
"""Adds markup for web links
|
||||
"""
|
||||
if not ('https://' in content or 'http://' in content or 'dat://' in content):
|
||||
if not ('https://' in content or \
|
||||
'http://' in content or \
|
||||
'dat://' in content):
|
||||
return content
|
||||
|
||||
words=content.replace('\n',' --linebreak--').split(' ')
|
||||
replaceDict={}
|
||||
for w in words:
|
||||
if w.startswith('https://') or w.startswith('http://') or w.startswith('dat://'):
|
||||
if w.startswith('https://') or \
|
||||
w.startswith('http://') or \
|
||||
w.startswith('dat://'):
|
||||
if w.endswith('.') or w.endswith(';'):
|
||||
w=w[:-1]
|
||||
markup='<a href="'+w+'" rel="nofollow noopener" target="_blank">'
|
||||
|
@ -46,7 +50,9 @@ def addWebLinks(content: str) -> str:
|
|||
markup+='<span class="invisible">http://</span>'
|
||||
elif w.startswith('dat://'):
|
||||
markup+='<span class="invisible">dat://</span>'
|
||||
markup+='<span class="ellipsis">'+w.replace('https://','').replace('http://','').replace('dat://','')+'</span></a>'
|
||||
markup+='<span class="ellipsis">'+ \
|
||||
w.replace('https://','').replace('http://','').replace('dat://','')+ \
|
||||
'</span></a>'
|
||||
replaceDict[w]=markup
|
||||
for url,markup in replaceDict.items():
|
||||
content=content.replace(url,markup)
|
||||
|
@ -56,12 +62,15 @@ def addWebLinks(content: str) -> str:
|
|||
def validHashTag(hashtag: str) -> bool:
|
||||
"""Returns true if the give hashtag contains valid characters
|
||||
"""
|
||||
validChars = set('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
||||
validChars = \
|
||||
set('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
|
||||
if set(hashtag).issubset(validChars):
|
||||
return True
|
||||
return False
|
||||
|
||||
def addHashTags(wordStr: str,httpPrefix: str,domain: str,replaceHashTags: {},postHashtags: {}) -> bool:
|
||||
def addHashTags(wordStr: str, \
|
||||
httpPrefix: str,domain: str, \
|
||||
replaceHashTags: {},postHashtags: {}) -> bool:
|
||||
"""Detects hashtags and adds them to the replacements dict
|
||||
Also updates the hashtags list to be added to the post
|
||||
"""
|
||||
|
@ -81,7 +90,9 @@ def addHashTags(wordStr: str,httpPrefix: str,domain: str,replaceHashTags: {},pos
|
|||
'type': 'Hashtag'
|
||||
}
|
||||
replaceHashTags[wordStr]= \
|
||||
"<a href=\""+hashtagUrl+"\" class=\"mention hashtag\" rel=\"tag\">#<span>"+hashtag+"</span></a>"
|
||||
"<a href=\""+hashtagUrl+ \
|
||||
"\" class=\"mention hashtag\" rel=\"tag\">#<span>"+ \
|
||||
hashtag+"</span></a>"
|
||||
return True
|
||||
|
||||
def loadEmojiDict(emojiDataFilename: str,emojiDict: {}) -> None:
|
||||
|
@ -104,12 +115,15 @@ def loadEmojiDict(emojiDataFilename: str,emojiDict: {}) -> None:
|
|||
continue
|
||||
if '..' in emojiUnicode:
|
||||
emojiUnicode=emojiUnicode.split('..')[0]
|
||||
emojiName=line.split(')',1)[1].strip().replace('\n','').replace(' ','').replace('-','')
|
||||
emojiName= \
|
||||
line.split(')',1)[1].strip().replace('\n','').replace(' ','').replace('-','')
|
||||
if '..' in emojiName:
|
||||
emojiName=emojiName.split('..')[0]
|
||||
emojiDict[emojiName.lower()]=emojiUnicode
|
||||
|
||||
def addEmoji(baseDir: str,wordStr: str,httpPrefix: str,domain: str,replaceEmoji: {},postTags: {},emojiDict: {}) -> bool:
|
||||
def addEmoji(baseDir: str,wordStr: str, \
|
||||
httpPrefix: str,domain: str, \
|
||||
replaceEmoji: {},postTags: {},emojiDict: {}) -> bool:
|
||||
"""Detects Emoji and adds them to the replacements dict
|
||||
Also updates the tags list to be added to the post
|
||||
"""
|
||||
|
@ -142,7 +156,9 @@ def addEmoji(baseDir: str,wordStr: str,httpPrefix: str,domain: str,replaceEmoji:
|
|||
}
|
||||
return True
|
||||
|
||||
def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},recipients: [],tags: {}) -> bool:
|
||||
def addMention(wordStr: str, \
|
||||
httpPrefix: str,following: str, \
|
||||
replaceMentions: {},recipients: [],tags: {}) -> bool:
|
||||
"""Detects mentions and adds them to the replacements dict and recipients list
|
||||
"""
|
||||
if not wordStr.startswith('@'):
|
||||
|
@ -158,7 +174,8 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
|
|||
for follow in following:
|
||||
if follow.startswith(possibleNickname+'@'):
|
||||
replaceDomain=follow.replace('\n','').split('@')[1]
|
||||
recipientActor=httpPrefix+"://"+replaceDomain+"/users/"+possibleNickname
|
||||
recipientActor= \
|
||||
httpPrefix+"://"+replaceDomain+"/users/"+possibleNickname
|
||||
if recipientActor not in recipients:
|
||||
recipients.append(recipientActor)
|
||||
tags[wordStr]={
|
||||
|
@ -166,7 +183,11 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
|
|||
'name': wordStr,
|
||||
'type': 'Mention'
|
||||
}
|
||||
replaceMentions[wordStr]="<span class=\"h-card\"><a href=\""+httpPrefix+"://"+replaceDomain+"/@"+possibleNickname+"\" class=\"u-url mention\">@<span>"+possibleNickname+"</span></a></span>"
|
||||
replaceMentions[wordStr]= \
|
||||
"<span class=\"h-card\"><a href=\""+httpPrefix+ \
|
||||
"://"+replaceDomain+"/@"+possibleNickname+ \
|
||||
"\" class=\"u-url mention\">@<span>"+ \
|
||||
possibleNickname+"</span></a></span>"
|
||||
return True
|
||||
return False
|
||||
possibleNickname=possibleHandle.split('@')[0]
|
||||
|
@ -175,7 +196,8 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
|
|||
for follow in following:
|
||||
if follow.replace('\n','')!=possibleHandle:
|
||||
continue
|
||||
recipientActor=httpPrefix+"://"+possibleDomain+"/users/"+possibleNickname
|
||||
recipientActor= \
|
||||
httpPrefix+"://"+possibleDomain+"/users/"+possibleNickname
|
||||
if recipientActor not in recipients:
|
||||
recipients.append(recipientActor)
|
||||
tags[wordStr]={
|
||||
|
@ -183,13 +205,18 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
|
|||
'name': wordStr,
|
||||
'type': 'Mention'
|
||||
}
|
||||
replaceMentions[wordStr]="<span class=\"h-card\"><a href=\""+httpPrefix+"://"+possibleDomain+"/@"+possibleNickname+"\" class=\"u-url mention\">@<span>"+possibleNickname+"</span></a></span>"
|
||||
replaceMentions[wordStr]= \
|
||||
"<span class=\"h-card\"><a href=\""+httpPrefix+ \
|
||||
"://"+possibleDomain+"/@"+possibleNickname+ \
|
||||
"\" class=\"u-url mention\">@<span>"+possibleNickname+ \
|
||||
"</span></a></span>"
|
||||
return True
|
||||
# @nick@domain
|
||||
if '@' in possibleHandle:
|
||||
if not (possibleDomain=='localhost' or '.' in possibleDomain):
|
||||
return False
|
||||
recipientActor=httpPrefix+"://"+possibleDomain+"/users/"+possibleNickname
|
||||
recipientActor= \
|
||||
httpPrefix+"://"+possibleDomain+"/users/"+possibleNickname
|
||||
if recipientActor not in recipients:
|
||||
recipients.append(recipientActor)
|
||||
tags[wordStr]={
|
||||
|
@ -197,7 +224,11 @@ def addMention(wordStr: str,httpPrefix: str,following: str,replaceMentions: {},r
|
|||
'name': wordStr,
|
||||
'type': 'Mention'
|
||||
}
|
||||
replaceMentions[wordStr]="<span class=\"h-card\"><a href=\""+httpPrefix+"://"+possibleDomain+"/@"+possibleNickname+"\" class=\"u-url mention\">@<span>"+possibleNickname+"</span></a></span>"
|
||||
replaceMentions[wordStr]= \
|
||||
"<span class=\"h-card\"><a href=\""+httpPrefix+ \
|
||||
"://"+possibleDomain+"/@"+possibleNickname+ \
|
||||
"\" class=\"u-url mention\">@<span>"+possibleNickname+ \
|
||||
"</span></a></span>"
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -244,22 +275,27 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
|
|||
|
||||
# extract mentions and tags from words
|
||||
for wordStr in words:
|
||||
if addMention(wordStr,httpPrefix,following,replaceMentions,recipients,hashtags):
|
||||
if addMention(wordStr,httpPrefix,following, \
|
||||
replaceMentions,recipients,hashtags):
|
||||
continue
|
||||
if addHashTags(wordStr,httpPrefix,originalDomain,replaceHashTags,hashtags):
|
||||
if addHashTags(wordStr,httpPrefix,originalDomain, \
|
||||
replaceHashTags,hashtags):
|
||||
continue
|
||||
if len(wordStr)>2 and wordStr.startswith(':') and wordStr.endswith(':') and not emojiDict:
|
||||
if len(wordStr)>2 and wordStr.startswith(':') and \
|
||||
wordStr.endswith(':') and not emojiDict:
|
||||
print('Loading emoji lookup')
|
||||
|
||||
# emoji.json is generated so that it can be customized and the changes
|
||||
# will be retained even if default_emoji.json is subsequently updated
|
||||
if not os.path.isfile(baseDir+'/emoji/emoji.json'):
|
||||
copyfile(baseDir+'/emoji/default_emoji.json',baseDir+'/emoji/emoji.json')
|
||||
copyfile(baseDir+'/emoji/default_emoji.json', \
|
||||
baseDir+'/emoji/emoji.json')
|
||||
|
||||
with open(baseDir+'/emoji/emoji.json', 'r') as fp:
|
||||
emojiDict=commentjson.load(fp)
|
||||
|
||||
addEmoji(baseDir,wordStr,httpPrefix,originalDomain,replaceEmoji,hashtags,emojiDict)
|
||||
addEmoji(baseDir,wordStr,httpPrefix,originalDomain, \
|
||||
replaceEmoji,hashtags,emojiDict)
|
||||
|
||||
# replace words with their html versions
|
||||
for wordStr,replaceStr in replaceMentions.items():
|
||||
|
@ -273,7 +309,8 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
|
|||
content=content.replace(' --linebreak-- ','</p><p>')
|
||||
return '<p>'+content+'</p>'
|
||||
|
||||
def getMentionsFromHtml(htmlText: str,matchStr="<span class=\"h-card\"><a href=\"") -> []:
|
||||
def getMentionsFromHtml(htmlText: str, \
|
||||
matchStr="<span class=\"h-card\"><a href=\"") -> []:
|
||||
"""Extracts mentioned actors from the given html content string
|
||||
"""
|
||||
mentions=[]
|
||||
|
|
13
inbox.py
13
inbox.py
|
@ -132,7 +132,8 @@ def inboxMessageHasParams(messageJson: {}) -> bool:
|
|||
return False
|
||||
return True
|
||||
|
||||
def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> bool:
|
||||
def inboxPermittedMessage(domain: str,messageJson: {}, \
|
||||
federationList: []) -> bool:
|
||||
""" check that we are receiving from a permitted domain
|
||||
"""
|
||||
testParam='actor'
|
||||
|
@ -160,7 +161,7 @@ def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> boo
|
|||
|
||||
return True
|
||||
|
||||
def validPublishedDate(published) -> bool:
|
||||
def validPublishedDate(published: str) -> bool:
|
||||
currTime=datetime.datetime.utcnow()
|
||||
pubDate=datetime.datetime.strptime(published,"%Y-%m-%dT%H:%M:%SZ")
|
||||
daysSincePublished = (currTime - pubTime).days
|
||||
|
@ -387,7 +388,9 @@ def inboxPostRecipientsAdd(baseDir :str,httpPrefix :str,toList :[], \
|
|||
followerRecipients=True
|
||||
return followerRecipients,recipientsDict
|
||||
|
||||
def inboxPostRecipients(baseDir :str,postJsonObject :{},httpPrefix :str,domain : str,port :int, debug :bool) -> ([],[]):
|
||||
def inboxPostRecipients(baseDir :str,postJsonObject :{}, \
|
||||
httpPrefix :str,domain : str,port :int, \
|
||||
debug :bool) -> ([],[]):
|
||||
"""Returns dictionaries containing the recipients of the given post
|
||||
The shared dictionary contains followers
|
||||
"""
|
||||
|
@ -1052,8 +1055,8 @@ def inboxAfterCapabilities(session,keyId: str,handle: str,messageJson: {}, \
|
|||
postLog: [],cachedWebfingers: {},personCache: {}, \
|
||||
queue: [],domain: str,port: int,useTor: bool, \
|
||||
federationList: [],ocapAlways: bool,debug: bool, \
|
||||
acceptedCaps: [],
|
||||
queueFilename :str,destinationFilename :str,
|
||||
acceptedCaps: [], \
|
||||
queueFilename :str,destinationFilename :str, \
|
||||
maxReplies: int,allowDeletion: bool) -> bool:
|
||||
""" Anything which needs to be done after capabilities checks have passed
|
||||
"""
|
||||
|
|
91
posts.py
91
posts.py
|
@ -372,7 +372,8 @@ def getPosts(session,outboxUrl: str,maxPosts: int, \
|
|||
break
|
||||
return personPosts
|
||||
|
||||
def deleteAllPosts(baseDir: str,nickname: str, domain: str,boxname: str) -> None:
|
||||
def deleteAllPosts(baseDir: str, \
|
||||
nickname: str, domain: str,boxname: str) -> None:
|
||||
"""Deletes all posts for a person from inbox or outbox
|
||||
"""
|
||||
if boxname!='inbox' and boxname!='outbox':
|
||||
|
@ -656,8 +657,9 @@ def outboxMessageCreateWrap(httpPrefix: str, \
|
|||
httpPrefix+'://'+domain+'/users/'+nickname+'/statuses/'+statusNumber
|
||||
return newPost
|
||||
|
||||
def postIsAddressedToFollowers(baseDir: str,
|
||||
nickname: str, domain: str, port: int,httpPrefix: str,
|
||||
def postIsAddressedToFollowers(baseDir: str, \
|
||||
nickname: str,domain: str, \
|
||||
port: int,httpPrefix: str, \
|
||||
postJsonObject: {}) -> bool:
|
||||
"""Returns true if the given post is addressed to followers of the nickname
|
||||
"""
|
||||
|
@ -816,13 +818,15 @@ def getMentionedPeople(baseDir: str,httpPrefix: str, \
|
|||
mentions.append(actor)
|
||||
return mentions
|
||||
|
||||
def createDirectMessagePost(baseDir: str,
|
||||
nickname: str, domain: str, port: int,httpPrefix: str, \
|
||||
content: str, followersOnly: bool, saveToFile: bool,
|
||||
def createDirectMessagePost(baseDir: str, \
|
||||
nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, \
|
||||
content: str,followersOnly: bool,saveToFile: bool,
|
||||
clientToServer: bool,\
|
||||
attachImageFilename: str,mediaType: str, \
|
||||
imageDescription: str,useBlurhash: bool, \
|
||||
inReplyTo=None, inReplyToAtomUri=None, subject=None,debug=False) -> {}:
|
||||
inReplyTo=None,inReplyToAtomUri=None, \
|
||||
subject=None,debug=False) -> {}:
|
||||
"""Direct Message post
|
||||
"""
|
||||
mentionedPeople=getMentionedPeople(baseDir,httpPrefix,content,domain,debug)
|
||||
|
@ -840,9 +844,9 @@ def createDirectMessagePost(baseDir: str,
|
|||
imageDescription,useBlurhash, \
|
||||
False,inReplyTo, inReplyToAtomUri, subject)
|
||||
|
||||
def createReportPost(baseDir: str,
|
||||
nickname: str, domain: str, port: int,httpPrefix: str, \
|
||||
content: str, followersOnly: bool, saveToFile: bool,
|
||||
def createReportPost(baseDir: str, \
|
||||
nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
content: str, followersOnly: bool, saveToFile: bool, \
|
||||
clientToServer: bool,\
|
||||
attachImageFilename: str,mediaType: str, \
|
||||
imageDescription: str,useBlurhash: bool, \
|
||||
|
@ -915,8 +919,9 @@ def createReportPost(baseDir: str,
|
|||
True,None, None, subject)
|
||||
return postJsonObject
|
||||
|
||||
def threadSendPost(session,postJsonStr: str,federationList: [],\
|
||||
inboxUrl: str, baseDir: str,signatureHeaderJson: {},postLog: [],
|
||||
def threadSendPost(session,postJsonStr: str,federationList: [], \
|
||||
inboxUrl: str, baseDir: str, \
|
||||
signatureHeaderJson: {},postLog: [], \
|
||||
debug :bool) -> None:
|
||||
"""Sends a post with exponential backoff
|
||||
"""
|
||||
|
@ -955,15 +960,17 @@ def threadSendPost(session,postJsonStr: str,federationList: [],\
|
|||
tries+=1
|
||||
|
||||
def sendPost(projectVersion: str, \
|
||||
session,baseDir: str,nickname: str, domain: str, port: int, \
|
||||
toNickname: str, toDomain: str, toPort: int, cc: str, \
|
||||
httpPrefix: str, content: str, followersOnly: bool, \
|
||||
saveToFile: bool, clientToServer: bool, \
|
||||
session,baseDir: str,nickname: str,domain: str,port: int, \
|
||||
toNickname: str,toDomain: str,toPort: int,cc: str, \
|
||||
httpPrefix: str,content: str,followersOnly: bool, \
|
||||
saveToFile: bool,clientToServer: bool, \
|
||||
attachImageFilename: str,mediaType: str, \
|
||||
imageDescription: str,useBlurhash: bool, \
|
||||
federationList: [],\
|
||||
sendThreads: [], postLog: [], cachedWebfingers: {},personCache: {}, \
|
||||
debug=False,inReplyTo=None,inReplyToAtomUri=None,subject=None) -> int:
|
||||
federationList: [], \
|
||||
sendThreads: [],postLog: [], \
|
||||
cachedWebfingers: {},personCache: {}, \
|
||||
debug=False,inReplyTo=None, \
|
||||
inReplyToAtomUri=None,subject=None) -> int:
|
||||
"""Post to another inbox
|
||||
"""
|
||||
withDigest=True
|
||||
|
@ -1061,7 +1068,8 @@ def sendPostViaServer(projectVersion: str, \
|
|||
attachImageFilename: str,mediaType: str, \
|
||||
imageDescription: str,useBlurhash: bool, \
|
||||
cachedWebfingers: {},personCache: {}, \
|
||||
debug=False,inReplyTo=None,inReplyToAtomUri=None,subject=None) -> int:
|
||||
debug=False,inReplyTo=None, \
|
||||
inReplyToAtomUri=None,subject=None) -> int:
|
||||
"""Send a post via a proxy (c2s)
|
||||
"""
|
||||
if not session:
|
||||
|
@ -1566,23 +1574,31 @@ def sendToFollowers(session,baseDir: str, \
|
|||
print('DEBUG: End of sendToFollowers')
|
||||
|
||||
|
||||
def createInbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
def createInbox(baseDir: str,nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool, \
|
||||
ocapAlways: bool,pageNumber=None) -> {}:
|
||||
return createBoxBase(baseDir,'inbox',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createDMTimeline(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
def createDMTimeline(baseDir: str,nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool, \
|
||||
ocapAlways: bool,pageNumber=None) -> {}:
|
||||
return createBoxBase(baseDir,'dm',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,True,ocapAlways,pageNumber)
|
||||
|
||||
def createOutbox(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,authorized: bool,pageNumber=None) -> {}:
|
||||
def createOutbox(baseDir: str,nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool, \
|
||||
authorized: bool,pageNumber=None) -> {}:
|
||||
return createBoxBase(baseDir,'outbox',nickname,domain,port,httpPrefix, \
|
||||
itemsPerPage,headerOnly,authorized,False,pageNumber)
|
||||
|
||||
def createModeration(baseDir: str,nickname: str,domain: str,port: int,httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool,ocapAlways: bool,pageNumber=None) -> {}:
|
||||
def createModeration(baseDir: str,nickname: str,domain: str,port: int, \
|
||||
httpPrefix: str, \
|
||||
itemsPerPage: int,headerOnly: bool, \
|
||||
ocapAlways: bool,pageNumber=None) -> {}:
|
||||
boxDir = createPersonDir(nickname,domain,baseDir,'inbox')
|
||||
boxname='moderation'
|
||||
|
||||
|
@ -1857,7 +1873,8 @@ def createBoxBase(baseDir: str,boxname: str, \
|
|||
return boxHeader
|
||||
return boxItems
|
||||
|
||||
def expireCache(baseDir: str,personCache: {},httpPrefix: str,archiveDir: str,maxPostsInBox=256):
|
||||
def expireCache(baseDir: str,personCache: {}, \
|
||||
httpPrefix: str,archiveDir: str,maxPostsInBox=256):
|
||||
"""Thread used to expire actors from the cache and archive old posts
|
||||
"""
|
||||
while True:
|
||||
|
@ -1866,7 +1883,8 @@ def expireCache(baseDir: str,personCache: {},httpPrefix: str,archiveDir: str,max
|
|||
expirePersonCache(basedir,personCache)
|
||||
archivePosts(baseDir,httpPrefix,archiveDir,maxPostsInBox)
|
||||
|
||||
def archivePosts(baseDir: str,httpPrefix: str,archiveDir: str,maxPostsInBox=256) -> None:
|
||||
def archivePosts(baseDir: str,httpPrefix: str, \
|
||||
archiveDir: str,maxPostsInBox=256) -> None:
|
||||
"""Archives posts for all accounts
|
||||
"""
|
||||
if archiveDir:
|
||||
|
@ -1899,8 +1917,10 @@ def archivePosts(baseDir: str,httpPrefix: str,archiveDir: str,maxPostsInBox=256)
|
|||
'outbox',archiveSubdir, \
|
||||
maxPostsInBox)
|
||||
|
||||
def archivePostsForPerson(httpPrefix: str,nickname: str,domain: str,baseDir: str, \
|
||||
boxname: str,archiveDir: str,maxPostsInBox=256) -> None:
|
||||
def archivePostsForPerson(httpPrefix: str,nickname: str,domain: str, \
|
||||
baseDir: str, \
|
||||
boxname: str,archiveDir: str, \
|
||||
maxPostsInBox=256) -> None:
|
||||
"""Retain a maximum number of posts within the given box
|
||||
Move any others to an archive directory
|
||||
"""
|
||||
|
@ -2005,8 +2025,11 @@ def sendCapabilitiesUpdate(session,baseDir: str,httpPrefix: str, \
|
|||
sendThreads,postLog,cachedWebfingers, \
|
||||
personCache,debug,projectVersion)
|
||||
|
||||
def populateRepliesJson(baseDir: str,nickname: str,domain: str,postRepliesFilename: str,authorized: bool,repliesJson: {}) -> None:
|
||||
# populate the items list with replies
|
||||
def populateRepliesJson(baseDir: str,nickname: str,domain: str, \
|
||||
postRepliesFilename: str,authorized: bool, \
|
||||
repliesJson: {}) -> None:
|
||||
"""populate the items list with replies
|
||||
"""
|
||||
repliesBoxes=['outbox','inbox']
|
||||
with open(postRepliesFilename,'r') as repliesFile:
|
||||
for messageId in repliesFile:
|
||||
|
|
Loading…
Reference in New Issue