diff --git a/newsdaemon.py b/newsdaemon.py
index fda1debc6..ffb5a5abf 100644
--- a/newsdaemon.py
+++ b/newsdaemon.py
@@ -74,6 +74,120 @@ def _removeControlCharacters(content: str) -> str:
return content
+def _hashtagLogicalNot(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ NOT
+ """
+ if len(tree) != 2:
+ return False
+ if isinstance(tree[1], str):
+ return tree[1] not in hashtags
+ elif isinstance(tree[1], list):
+ return not hashtagRuleResolve(tree[1], hashtags,
+ moderated, content, url)
+ return False
+
+
+def _hashtagLogicalContains(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ Contains
+ """
+ if len(tree) != 2:
+ return False
+ matchStr = None
+ if isinstance(tree[1], str):
+ matchStr = tree[1]
+ elif isinstance(tree[1], list):
+ matchStr = tree[1][0]
+ if matchStr:
+ if matchStr.startswith('"') and matchStr.endswith('"'):
+ matchStr = matchStr[1:]
+ matchStr = matchStr[:len(matchStr) - 1]
+ matchStrLower = matchStr.lower()
+ contentWithoutTags = content.replace('#' + matchStrLower, '')
+ return matchStrLower in contentWithoutTags
+ return False
+
+
+def _hashtagLogicalFrom(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ FROM
+ """
+ if len(tree) != 2:
+ return False
+ matchStr = None
+ if isinstance(tree[1], str):
+ matchStr = tree[1]
+ elif isinstance(tree[1], list):
+ matchStr = tree[1][0]
+ if matchStr:
+ if matchStr.startswith('"') and matchStr.endswith('"'):
+ matchStr = matchStr[1:]
+ matchStr = matchStr[:len(matchStr) - 1]
+ return matchStr.lower() in url
+ return False
+
+
+def _hashtagLogicalAnd(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ AND
+ """
+ if len(tree) < 3:
+ return False
+ for argIndex in range(1, len(tree)):
+ argValue = False
+ if isinstance(tree[argIndex], str):
+ argValue = (tree[argIndex] in hashtags)
+ elif isinstance(tree[argIndex], list):
+ argValue = hashtagRuleResolve(tree[argIndex],
+ hashtags, moderated,
+ content, url)
+ if not argValue:
+ return False
+ return True
+
+
+def _hashtagLogicalOr(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ OR
+ """
+ if len(tree) < 3:
+ return False
+ for argIndex in range(1, len(tree)):
+ argValue = False
+ if isinstance(tree[argIndex], str):
+ argValue = (tree[argIndex] in hashtags)
+ elif isinstance(tree[argIndex], list):
+ argValue = hashtagRuleResolve(tree[argIndex],
+ hashtags, moderated,
+ content, url)
+ if argValue:
+ return True
+ return False
+
+
+def _hashtagLogicalXor(tree: [], hashtags: [], moderated: bool,
+ content: str, url: str) -> bool:
+ """ XOR
+ """
+ if len(tree) < 3:
+ return False
+ trueCtr = 0
+ for argIndex in range(1, len(tree)):
+ argValue = False
+ if isinstance(tree[argIndex], str):
+ argValue = (tree[argIndex] in hashtags)
+ elif isinstance(tree[argIndex], list):
+ argValue = hashtagRuleResolve(tree[argIndex],
+ hashtags, moderated,
+ content, url)
+ if argValue:
+ trueCtr += 1
+ if trueCtr == 1:
+ return True
+ return False
+
+
def hashtagRuleResolve(tree: [], hashtags: [], moderated: bool,
content: str, url: str) -> bool:
"""Returns whether the tree for a hashtag rule evaluates to true or false
@@ -82,79 +196,17 @@ def hashtagRuleResolve(tree: [], hashtags: [], moderated: bool,
return False
if tree[0] == 'not':
- if len(tree) == 2:
- if isinstance(tree[1], str):
- return tree[1] not in hashtags
- elif isinstance(tree[1], list):
- return not hashtagRuleResolve(tree[1], hashtags, moderated,
- content, url)
+ return _hashtagLogicalNot(tree, hashtags, moderated, content, url)
elif tree[0] == 'contains':
- if len(tree) == 2:
- matchStr = None
- if isinstance(tree[1], str):
- matchStr = tree[1]
- elif isinstance(tree[1], list):
- matchStr = tree[1][0]
- if matchStr:
- if matchStr.startswith('"') and matchStr.endswith('"'):
- matchStr = matchStr[1:]
- matchStr = matchStr[:len(matchStr) - 1]
- matchStrLower = matchStr.lower()
- contentWithoutTags = content.replace('#' + matchStrLower, '')
- return matchStrLower in contentWithoutTags
+ return _hashtagLogicalContains(tree, hashtags, moderated, content, url)
elif tree[0] == 'from':
- if len(tree) == 2:
- matchStr = None
- if isinstance(tree[1], str):
- matchStr = tree[1]
- elif isinstance(tree[1], list):
- matchStr = tree[1][0]
- if matchStr:
- if matchStr.startswith('"') and matchStr.endswith('"'):
- matchStr = matchStr[1:]
- matchStr = matchStr[:len(matchStr) - 1]
- return matchStr.lower() in url
+ return _hashtagLogicalFrom(tree, hashtags, moderated, content, url)
elif tree[0] == 'and':
- if len(tree) >= 3:
- for argIndex in range(1, len(tree)):
- argValue = False
- if isinstance(tree[argIndex], str):
- argValue = (tree[argIndex] in hashtags)
- elif isinstance(tree[argIndex], list):
- argValue = hashtagRuleResolve(tree[argIndex],
- hashtags, moderated,
- content, url)
- if not argValue:
- return False
- return True
+ return _hashtagLogicalAnd(tree, hashtags, moderated, content, url)
elif tree[0] == 'or':
- if len(tree) >= 3:
- for argIndex in range(1, len(tree)):
- argValue = False
- if isinstance(tree[argIndex], str):
- argValue = (tree[argIndex] in hashtags)
- elif isinstance(tree[argIndex], list):
- argValue = hashtagRuleResolve(tree[argIndex],
- hashtags, moderated,
- content, url)
- if argValue:
- return True
- return False
+ return _hashtagLogicalOr(tree, hashtags, moderated, content, url)
elif tree[0] == 'xor':
- if len(tree) >= 3:
- trueCtr = 0
- for argIndex in range(1, len(tree)):
- argValue = False
- if isinstance(tree[argIndex], str):
- argValue = (tree[argIndex] in hashtags)
- elif isinstance(tree[argIndex], list):
- argValue = hashtagRuleResolve(tree[argIndex],
- hashtags, moderated,
- content, url)
- if argValue:
- trueCtr += 1
- if trueCtr == 1:
- return True
+ return _hashtagLogicalXor(tree, hashtags, moderated, content, url)
elif tree[0].startswith('#') and len(tree) == 1:
return tree[0] in hashtags
elif tree[0].startswith('moderated'):
@@ -225,6 +277,87 @@ def hashtagRuleTree(operators: [],
return tree
+def _hashtagAdd(baseDir: str, httpPrefix: str, domainFull: str,
+ postJsonObject: {},
+ actionStr: str, hashtags: []) -> None:
+ """Adds a hashtag via a hashtag rule
+ """
+ addHashtag = actionStr.split('add ', 1)[1].strip()
+ if not addHashtag.startswith('#'):
+ return
+
+ if addHashtag not in hashtags:
+ hashtags.append(addHashtag)
+ htId = addHashtag.replace('#', '')
+ if not validHashTag(htId):
+ return
+
+ hashtagUrl = httpPrefix + "://" + domainFull + "/tags/" + htId
+ newTag = {
+ 'href': hashtagUrl,
+ 'name': addHashtag,
+ 'type': 'Hashtag'
+ }
+ # does the tag already exist?
+ addTagObject = None
+ for t in postJsonObject['object']['tag']:
+ if t.get('type') and t.get('name'):
+ if t['type'] == 'Hashtag' and \
+ t['name'] == addHashtag:
+ addTagObject = t
+ break
+ # append the tag if it wasn't found
+ if not addTagObject:
+ postJsonObject['object']['tag'].append(newTag)
+ # add corresponding html to the post content
+ hashtagHtml = \
+ " #" + htId + ""
+ content = postJsonObject['object']['content']
+ if hashtagHtml in content:
+ return
+
+ if content.endswith('
'):
+ content = \
+ content[:len(content) - len('')] + \
+ hashtagHtml + ''
+ else:
+ content += hashtagHtml
+ postJsonObject['object']['content'] = content
+ storeHashTags(baseDir, 'news', postJsonObject)
+
+
+def _hashtagRemove(httpPrefix: str, domainFull: str, postJsonObject: {},
+ actionStr: str, hashtags: []) -> None:
+ """Removes a hashtag via a hashtag rule
+ """
+ rmHashtag = actionStr.split('remove ', 1)[1].strip()
+ if not rmHashtag.startswith('#'):
+ return
+
+ if rmHashtag in hashtags:
+ hashtags.remove(rmHashtag)
+ htId = rmHashtag.replace('#', '')
+ hashtagUrl = httpPrefix + "://" + domainFull + "/tags/" + htId
+ # remove tag html from the post content
+ hashtagHtml = \
+ "#" + htId + ""
+ content = postJsonObject['object']['content']
+ if hashtagHtml in content:
+ content = content.replace(hashtagHtml, '').replace(' ', ' ')
+ postJsonObject['object']['content'] = content
+ rmTagObject = None
+ for t in postJsonObject['object']['tag']:
+ if t.get('type') and t.get('name'):
+ if t['type'] == 'Hashtag' and \
+ t['name'] == rmHashtag:
+ rmTagObject = t
+ break
+ if rmTagObject:
+ postJsonObject['object']['tag'].remove(rmTagObject)
+
+
def _newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
hashtags: [], httpPrefix: str,
domain: str, port: int,
@@ -273,83 +406,16 @@ def _newswireHashtagProcessing(session, baseDir: str, postJsonObject: {},
# the condition matches, so do something
actionStr = ruleStr.split(' then ')[1].strip()
- # add a hashtag
if actionStr.startswith('add '):
- addHashtag = actionStr.split('add ', 1)[1].strip()
- if addHashtag.startswith('#'):
- if addHashtag not in hashtags:
- hashtags.append(addHashtag)
- htId = addHashtag.replace('#', '')
- if validHashTag(htId):
- hashtagUrl = \
- httpPrefix + "://" + domainFull + "/tags/" + htId
- newTag = {
- 'href': hashtagUrl,
- 'name': addHashtag,
- 'type': 'Hashtag'
- }
- # does the tag already exist?
- addTagObject = None
- for t in postJsonObject['object']['tag']:
- if t.get('type') and t.get('name'):
- if t['type'] == 'Hashtag' and \
- t['name'] == addHashtag:
- addTagObject = t
- break
- # append the tag if it wasn't found
- if not addTagObject:
- postJsonObject['object']['tag'].append(newTag)
- # add corresponding html to the post content
- hashtagHtml = \
- " #" + \
- htId + ""
- content = postJsonObject['object']['content']
- if hashtagHtml not in content:
- if content.endswith(''):
- content = \
- content[:len(content) - len('')] + \
- hashtagHtml + ''
- else:
- content += hashtagHtml
- postJsonObject['object']['content'] = content
- storeHashTags(baseDir, 'news', postJsonObject)
- # actionOccurred = True
-
- # remove a hashtag
- if actionStr.startswith('remove '):
- rmHashtag = actionStr.split('remove ', 1)[1].strip()
- if rmHashtag.startswith('#'):
- if rmHashtag in hashtags:
- hashtags.remove(rmHashtag)
- htId = rmHashtag.replace('#', '')
- hashtagUrl = \
- httpPrefix + "://" + domainFull + "/tags/" + htId
- # remove tag html from the post content
- hashtagHtml = \
- "#" + \
- htId + ""
- content = postJsonObject['object']['content']
- if hashtagHtml in content:
- content = \
- content.replace(hashtagHtml, '').replace(' ', ' ')
- postJsonObject['object']['content'] = content
- rmTagObject = None
- for t in postJsonObject['object']['tag']:
- if t.get('type') and t.get('name'):
- if t['type'] == 'Hashtag' and \
- t['name'] == rmHashtag:
- rmTagObject = t
- break
- if rmTagObject:
- postJsonObject['object']['tag'].remove(rmTagObject)
- # actionOccurred = True
-
- # Block this item
- if actionStr.startswith('block') or actionStr.startswith('drop'):
+ # add a hashtag
+ _hashtagAdd(baseDir, httpPrefix, domainFull,
+ postJsonObject, actionStr, hashtags)
+ elif actionStr.startswith('remove '):
+ # remove a hashtag
+ _hashtagRemove(httpPrefix, domainFull, postJsonObject,
+ actionStr, hashtags)
+ elif actionStr.startswith('block') or actionStr.startswith('drop'):
+ # Block this item
return False
return True
diff --git a/newswire.py b/newswire.py
index 57b37eb69..544d17577 100644
--- a/newswire.py
+++ b/newswire.py
@@ -47,21 +47,25 @@ def rss2Header(httpPrefix: str,
title: str, translate: {}) -> str:
"""Header for an RSS 2.0 feed
"""
- rssStr = ""
- rssStr += ""
- rssStr += ''
+ rssStr = \
+ "" + \
+ "" + \
+ ''
if title.startswith('News'):
- rssStr += ' Newswire'
- rssStr += ' ' + httpPrefix + '://' + domainFull + \
+ rssStr += \
+ ' Newswire' + \
+ ' ' + httpPrefix + '://' + domainFull + \
'/newswire.xml' + ''
elif title.startswith('Site'):
- rssStr += ' ' + domainFull + ''
- rssStr += ' ' + httpPrefix + '://' + domainFull + \
+ rssStr += \
+ ' ' + domainFull + '' + \
+ ' ' + httpPrefix + '://' + domainFull + \
'/blog/rss.xml' + ''
else:
- rssStr += ' ' + translate[title] + ''
- rssStr += ' ' + httpPrefix + '://' + domainFull + \
+ rssStr += \
+ ' ' + translate[title] + '' + \
+ ' ' + httpPrefix + '://' + domainFull + \
'/users/' + nickname + '/rss.xml' + ''
return rssStr
@@ -69,8 +73,7 @@ def rss2Header(httpPrefix: str,
def rss2Footer() -> str:
"""Footer for an RSS 2.0 feed
"""
- rssStr = ''
- rssStr += ''
+ rssStr = ''
return rssStr
@@ -815,8 +818,9 @@ def getRSSfromDict(baseDir: str, newswire: {},
except Exception as e:
print('WARN: Unable to convert date ' + published + ' ' + str(e))
continue
- rssStr += '- \n'
- rssStr += ' ' + fields[0] + '\n'
+ rssStr += \
+ '
- \n' + \
+ ' ' + fields[0] + '\n'
description = removeHtml(firstParagraphFromString(fields[4]))
rssStr += ' ' + description + '\n'
url = fields[1]
@@ -826,8 +830,9 @@ def getRSSfromDict(baseDir: str, newswire: {},
rssStr += ' ' + url + '\n'
rssDateStr = pubDate.strftime("%a, %d %b %Y %H:%M:%S UT")
- rssStr += ' ' + rssDateStr + '\n'
- rssStr += '
\n'
+ rssStr += \
+ ' ' + rssDateStr + '\n' + \
+ ' \n'
rssStr += rss2Footer()
return rssStr
diff --git a/outbox.py b/outbox.py
index 156de5ace..779c92da0 100644
--- a/outbox.py
+++ b/outbox.py
@@ -311,8 +311,7 @@ def postMessageToOutbox(session, translate: {},
permittedOutboxTypes = ('Create', 'Announce', 'Like', 'Follow', 'Undo',
'Update', 'Add', 'Remove', 'Block', 'Delete',
- 'Skill', 'Add', 'Remove', 'Event',
- 'Ignore')
+ 'Skill', 'Ignore')
if messageJson['type'] not in permittedOutboxTypes:
if debug:
print('DEBUG: POST to outbox - ' + messageJson['type'] +
@@ -369,14 +368,12 @@ def postMessageToOutbox(session, translate: {},
if os.path.isfile(citationsFilename):
os.remove(citationsFilename)
- if messageJson['type'] == 'Create' or \
- messageJson['type'] == 'Question' or \
- messageJson['type'] == 'Note' or \
- messageJson['type'] == 'EncryptedMessage' or \
- messageJson['type'] == 'Article' or \
- messageJson['type'] == 'Event' or \
- messageJson['type'] == 'Patch' or \
- messageJson['type'] == 'Announce':
+ # The following activity types get added to the index files
+ indexedActivities = (
+ 'Create', 'Question', 'Note', 'EncryptedMessage', 'Article',
+ 'Patch', 'Announce'
+ )
+ if messageJson['type'] in indexedActivities:
indexes = [outboxName, "inbox"]
selfActor = \
httpPrefix + '://' + domainFull + '/users/' + postToNickname
diff --git a/person.py b/person.py
index ce426680f..f0db12612 100644
--- a/person.py
+++ b/person.py
@@ -49,6 +49,7 @@ from utils import refreshNewswire
from utils import getProtocolPrefixes
from utils import hasUsersPath
from utils import getImageExtensions
+from utils import isImageFile
from session import createSession
from session import getJson
from webfinger import webfingerHandle
@@ -84,11 +85,7 @@ def setProfileImage(baseDir: str, httpPrefix: str, nickname: str, domain: str,
image for the given person
"""
imageFilename = imageFilename.replace('\n', '').replace('\r', '')
- if not (imageFilename.endswith('.png') or
- imageFilename.endswith('.jpg') or
- imageFilename.endswith('.jpeg') or
- imageFilename.endswith('.svg') or
- imageFilename.endswith('.gif')):
+ if not isImageFile(imageFilename):
print('Profile image must be png, jpg, gif or svg format')
return False
@@ -119,10 +116,16 @@ def setProfileImage(baseDir: str, httpPrefix: str, nickname: str, domain: str,
imageFilename.endswith('.jpeg'):
mediaType = 'image/jpeg'
iconFilename = iconFilenameBase + '.jpg'
- if imageFilename.endswith('.gif'):
+ elif imageFilename.endswith('.gif'):
mediaType = 'image/gif'
iconFilename = iconFilenameBase + '.gif'
- if imageFilename.endswith('.svg'):
+ elif imageFilename.endswith('.webp'):
+ mediaType = 'image/webp'
+ iconFilename = iconFilenameBase + '.webp'
+ elif imageFilename.endswith('.avif'):
+ mediaType = 'image/avif'
+ iconFilename = iconFilenameBase + '.avif'
+ elif imageFilename.endswith('.svg'):
mediaType = 'image/svg+xml'
iconFilename = iconFilenameBase + '.svg'
profileFilename = baseDir + '/accounts/' + handle + '/' + iconFilename
@@ -593,17 +596,15 @@ def personUpgradeActor(baseDir: str, personJson: {},
# if the older skills format is being used then switch
# to the new one
if not personJson.get('hasOccupation'):
- personJson['hasOccupation'] = [
- {
- '@type': 'Occupation',
- 'name': occupationName,
- "occupationLocation": {
- "@type": "City",
- "name": "Fediverse"
- },
- 'skills': []
- }
- ]
+ personJson['hasOccupation'] = [{
+ '@type': 'Occupation',
+ 'name': occupationName,
+ "occupationLocation": {
+ "@type": "City",
+ "name": "Fediverse"
+ },
+ 'skills': []
+ }]
updateActor = True
# remove the old skills format
@@ -618,17 +619,15 @@ def personUpgradeActor(baseDir: str, personJson: {},
updateActor = True
if not isinstance(personJson['hasOccupation'], list):
- personJson['hasOccupation'] = [
- {
- '@type': 'Occupation',
- 'name': occupationName,
- 'occupationLocation': {
- '@type': 'City',
- 'name': 'Fediverse'
- },
- 'skills': []
- }
- ]
+ personJson['hasOccupation'] = [{
+ '@type': 'Occupation',
+ 'name': occupationName,
+ 'occupationLocation': {
+ '@type': 'City',
+ 'name': 'Fediverse'
+ },
+ 'skills': []
+ }]
updateActor = True
else:
# add location if it is missing
@@ -1212,27 +1211,17 @@ def getActorJson(hostDomain: str, handle: str, http: bool, gnunet: bool,
for prefix in prefixes:
handle = handle.replace(prefix, '')
handle = handle.replace('/@', '/users/')
- if '/users/' in handle:
- nickname = handle.split('/users/')[1]
- nickname = nickname.replace('\n', '').replace('\r', '')
- domain = handle.split('/users/')[0]
- elif '/profile/' in handle:
- nickname = handle.split('/profile/')[1]
- nickname = nickname.replace('\n', '').replace('\r', '')
- domain = handle.split('/profile/')[0]
- elif '/channel/' in handle:
- nickname = handle.split('/channel/')[1]
- nickname = nickname.replace('\n', '').replace('\r', '')
- domain = handle.split('/channel/')[0]
- elif '/accounts/' in handle:
- nickname = handle.split('/accounts/')[1]
- nickname = nickname.replace('\n', '').replace('\r', '')
- domain = handle.split('/accounts/')[0]
- elif '/u/' in handle:
- nickname = handle.split('/u/')[1]
- nickname = nickname.replace('\n', '').replace('\r', '')
- domain = handle.split('/u/')[0]
- elif '://' in originalHandle:
+ paths = (
+ '/users/', '/profile/', '/channel/', '/accounts/', '/u/'
+ )
+ userPathFound = False
+ for userPath in paths:
+ if userPath in handle:
+ nickname = handle.split(userPath)[1]
+ nickname = nickname.replace('\n', '').replace('\r', '')
+ domain = handle.split(userPath)[0]
+ break
+ if not userPathFound and '://' in originalHandle:
domain = originalHandle.split('://')[1]
if '/' in domain:
domain = domain.split('/')[0]
diff --git a/posts.py b/posts.py
index 0751b9048..fa0f2c682 100644
--- a/posts.py
+++ b/posts.py
@@ -492,9 +492,9 @@ def _updateWordFrequency(content: str, wordFrequency: {}) -> None:
that they appear
"""
plainText = removeHtml(content)
- plainText = plainText.replace('.', ' ')
- plainText = plainText.replace(';', ' ')
- plainText = plainText.replace('?', ' ')
+ removeChars = ('.', ';', '?')
+ for ch in removeChars:
+ plainText = plainText.replace(ch, ' ')
wordsList = plainText.split(' ')
commonWords = (
'that', 'some', 'about', 'then', 'they', 'were',
@@ -1656,29 +1656,30 @@ def getMentionedPeople(baseDir: str, httpPrefix: str,
mentions = []
words = content.split(' ')
for wrd in words:
- if wrd.startswith('@'):
- handle = wrd[1:]
- if debug:
- print('DEBUG: mentioned handle ' + handle)
- if '@' not in handle:
- handle = handle + '@' + domain
- if not os.path.isdir(baseDir + '/accounts/' + handle):
- continue
- else:
- externalDomain = handle.split('@')[1]
- if not ('.' in externalDomain or
- externalDomain == 'localhost'):
- continue
- mentionedNickname = handle.split('@')[0]
- mentionedDomain = handle.split('@')[1].strip('\n').strip('\r')
- if ':' in mentionedDomain:
- mentionedDomain = removeDomainPort(mentionedDomain)
- if not validNickname(mentionedDomain, mentionedNickname):
+ if not wrd.startswith('@'):
+ continue
+ handle = wrd[1:]
+ if debug:
+ print('DEBUG: mentioned handle ' + handle)
+ if '@' not in handle:
+ handle = handle + '@' + domain
+ if not os.path.isdir(baseDir + '/accounts/' + handle):
continue
- actor = \
- httpPrefix + '://' + handle.split('@')[1] + \
- '/users/' + mentionedNickname
- mentions.append(actor)
+ else:
+ externalDomain = handle.split('@')[1]
+ if not ('.' in externalDomain or
+ externalDomain == 'localhost'):
+ continue
+ mentionedNickname = handle.split('@')[0]
+ mentionedDomain = handle.split('@')[1].strip('\n').strip('\r')
+ if ':' in mentionedDomain:
+ mentionedDomain = removeDomainPort(mentionedDomain)
+ if not validNickname(mentionedDomain, mentionedNickname):
+ continue
+ actor = \
+ httpPrefix + '://' + handle.split('@')[1] + \
+ '/users/' + mentionedNickname
+ mentions.append(actor)
return mentions
@@ -2140,14 +2141,15 @@ def groupFollowersByDomain(baseDir: str, nickname: str, domain: str) -> {}:
grouped = {}
with open(followersFilename, "r") as f:
for followerHandle in f:
- if '@' in followerHandle:
- fHandle = \
- followerHandle.strip().replace('\n', '').replace('\r', '')
- followerDomain = fHandle.split('@')[1]
- if not grouped.get(followerDomain):
- grouped[followerDomain] = [fHandle]
- else:
- grouped[followerDomain].append(fHandle)
+ if '@' not in followerHandle:
+ continue
+ fHandle = \
+ followerHandle.strip().replace('\n', '').replace('\r', '')
+ followerDomain = fHandle.split('@')[1]
+ if not grouped.get(followerDomain):
+ grouped[followerDomain] = [fHandle]
+ else:
+ grouped[followerDomain].append(fHandle)
return grouped
@@ -2174,9 +2176,9 @@ def _addFollowersToPublicPost(postJsonObject: {}) -> None:
return
if len(postJsonObject['object']['to']) > 1:
return
- if len(postJsonObject['object']['to']) == 0:
+ elif len(postJsonObject['object']['to']) == 0:
return
- if not postJsonObject['object']['to'][0].endswith('#Public'):
+ elif not postJsonObject['object']['to'][0].endswith('#Public'):
return
if postJsonObject['object'].get('cc'):
return
@@ -2403,6 +2405,20 @@ def addToField(activityType: str, postJsonObject: {},
return postJsonObject, False
+def _isProfileUpdate(postJsonObject: {}) -> bool:
+ """Is the given post a profile update?
+ for actor updates there is no 'to' within the object
+ """
+ if postJsonObject['object'].get('type') and postJsonObject.get('type'):
+ if (postJsonObject['type'] == 'Update' and
+ (postJsonObject['object']['type'] == 'Person' or
+ postJsonObject['object']['type'] == 'Application' or
+ postJsonObject['object']['type'] == 'Group' or
+ postJsonObject['object']['type'] == 'Service')):
+ return True
+ return False
+
+
def sendToNamedAddresses(session, baseDir: str,
nickname: str, domain: str,
onionDomain: str, i2pDomain: str, port: int,
@@ -2420,16 +2436,10 @@ def sendToNamedAddresses(session, baseDir: str,
return
isProfileUpdate = False
if isinstance(postJsonObject['object'], dict):
- # for actor updates there is no 'to' within the object
- if postJsonObject['object'].get('type') and postJsonObject.get('type'):
- if (postJsonObject['type'] == 'Update' and
- (postJsonObject['object']['type'] == 'Person' or
- postJsonObject['object']['type'] == 'Application' or
- postJsonObject['object']['type'] == 'Group' or
- postJsonObject['object']['type'] == 'Service')):
- # use the original object, which has a 'to'
- recipientsObject = postJsonObject
- isProfileUpdate = True
+ if _isProfileUpdate(postJsonObject):
+ # use the original object, which has a 'to'
+ recipientsObject = postJsonObject
+ isProfileUpdate = True
if not isProfileUpdate:
if not postJsonObject['object'].get('to'):