diff --git a/announce.py b/announce.py index 435cd911e..2b9a1cc64 100644 --- a/announce.py +++ b/announce.py @@ -40,7 +40,7 @@ def outboxAnnounce(recentPostsCache: {}, return False nickname = getNicknameFromActor(messageJson['actor']) if not nickname: - print('WARN: no nickname found in '+messageJson['actor']) + print('WARN: no nickname found in ' + messageJson['actor']) return False domain, port = getDomainFromActor(messageJson['actor']) postFilename = locatePost(baseDir, nickname, domain, @@ -49,7 +49,7 @@ def outboxAnnounce(recentPostsCache: {}, updateAnnounceCollection(recentPostsCache, baseDir, postFilename, messageJson['actor'], domain, debug) return True - if messageJson['type'] == 'Undo': + elif messageJson['type'] == 'Undo': if not isinstance(messageJson['object'], dict): return False if not messageJson['object'].get('type'): @@ -73,26 +73,15 @@ def outboxAnnounce(recentPostsCache: {}, return False -def announcedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool: +def announcedByPerson(isAnnounced: bool, postActor: str, + nickname: str, domainFull: str) -> bool: """Returns True if the given post is announced by the given person """ - if not postJsonObject.get('object'): + if not postActor: return False - if not isinstance(postJsonObject['object'], dict): - return False - # not to be confused with shared items - if not postJsonObject['object'].get('shares'): - return False - if not isinstance(postJsonObject['object']['shares'], dict): - return False - if not postJsonObject['object']['shares'].get('items'): - return False - if not isinstance(postJsonObject['object']['shares']['items'], list): - return False - actorMatch = domain + '/users/' + nickname - for item in postJsonObject['object']['shares']['items']: - if item['actor'].endswith(actorMatch): - return True + if isAnnounced and \ + postActor.endswith(domainFull + '/users/' + nickname): + return True return False @@ -124,7 +113,7 @@ def createAnnounce(session, baseDir: str, federationList: [], '/statuses/' + statusNumber newAnnounce = { "@context": "https://www.w3.org/ns/activitystreams", - 'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname, + 'actor': httpPrefix + '://' + fullDomain + '/users/' + nickname, 'atomUri': atomUriStr, 'cc': [], 'id': newAnnounceId + '/activity', diff --git a/utils.py b/utils.py index 763997b78..5b4ef6bd9 100644 --- a/utils.py +++ b/utils.py @@ -1985,63 +1985,64 @@ def updateAnnounceCollection(recentPostsCache: {}, It's shares of posts, not shares of physical objects. """ postJsonObject = loadJson(postFilename) - if postJsonObject: - # remove any cached version of this announce so that the announce - # icon is changed - nickname = getNicknameFromActor(actor) - cachedPostFilename = getCachedPostFilename(baseDir, nickname, domain, - postJsonObject) - if cachedPostFilename: - if os.path.isfile(cachedPostFilename): - os.remove(cachedPostFilename) - removePostFromCache(postJsonObject, recentPostsCache) - - if not postJsonObject.get('object'): - if debug: - pprint(postJsonObject) - print('DEBUG: post ' + postFilename + ' has no object') - return - if not isinstance(postJsonObject['object'], dict): - return - postUrl = removeIdEnding(postJsonObject['id']) + '/shares' - if not postJsonObject['object'].get('shares'): - if debug: - print('DEBUG: Adding initial shares (announcements) to ' + - postUrl) - announcementsJson = { - "@context": "https://www.w3.org/ns/activitystreams", - 'id': postUrl, - 'type': 'Collection', - "totalItems": 1, - 'items': [{ - 'type': 'Announce', - 'actor': actor - }] - } - postJsonObject['object']['shares'] = announcementsJson - else: - if postJsonObject['object']['shares'].get('items'): - sharesItems = postJsonObject['object']['shares']['items'] - for announceItem in sharesItems: - if announceItem.get('actor'): - if announceItem['actor'] == actor: - return - newAnnounce = { - 'type': 'Announce', - 'actor': actor - } - postJsonObject['object']['shares']['items'].append(newAnnounce) - itlen = len(postJsonObject['object']['shares']['items']) - postJsonObject['object']['shares']['totalItems'] = itlen - else: - if debug: - print('DEBUG: shares (announcements) section of post ' + - 'has no items list') + if not postJsonObject: + return + # remove any cached version of this announce so that the announce + # icon is changed + nickname = getNicknameFromActor(actor) + cachedPostFilename = getCachedPostFilename(baseDir, nickname, domain, + postJsonObject) + if cachedPostFilename: + if os.path.isfile(cachedPostFilename): + os.remove(cachedPostFilename) + removePostFromCache(postJsonObject, recentPostsCache) + if not postJsonObject.get('object'): if debug: - print('DEBUG: saving post with shares (announcements) added') pprint(postJsonObject) - saveJson(postJsonObject, postFilename) + print('DEBUG: post ' + postFilename + ' has no object') + return + if not isinstance(postJsonObject['object'], dict): + return + postUrl = removeIdEnding(postJsonObject['id']) + '/shares' + if not postJsonObject['object'].get('shares'): + if debug: + print('DEBUG: Adding initial shares (announcements) to ' + + postUrl) + announcementsJson = { + "@context": "https://www.w3.org/ns/activitystreams", + 'id': postUrl, + 'type': 'Collection', + "totalItems": 1, + 'items': [{ + 'type': 'Announce', + 'actor': actor + }] + } + postJsonObject['object']['shares'] = announcementsJson + else: + if postJsonObject['object']['shares'].get('items'): + sharesItems = postJsonObject['object']['shares']['items'] + for announceItem in sharesItems: + if announceItem.get('actor'): + if announceItem['actor'] == actor: + return + newAnnounce = { + 'type': 'Announce', + 'actor': actor + } + postJsonObject['object']['shares']['items'].append(newAnnounce) + itlen = len(postJsonObject['object']['shares']['items']) + postJsonObject['object']['shares']['totalItems'] = itlen + else: + if debug: + print('DEBUG: shares (announcements) section of post ' + + 'has no items list') + + if debug: + print('DEBUG: saving post with shares (announcements) added') + pprint(postJsonObject) + saveJson(postJsonObject, postFilename) def weekDayOfMonthStart(monthNumber: int, year: int) -> int: diff --git a/webapp_post.py b/webapp_post.py index 466ad63db..fb91b929f 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -21,6 +21,7 @@ from posts import postIsMuted from posts import getPersonBox from posts import downloadAnnounce from posts import populateRepliesJson +from utils import updateAnnounceCollection from utils import isPGPEncrypted from utils import isDM from utils import rejectPostId @@ -384,7 +385,9 @@ def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str, return editStr -def _getAnnounceIconHtml(nickname: str, domainFull: str, +def _getAnnounceIconHtml(isAnnounced: bool, + postActor: str, + nickname: str, domainFull: str, postJsonObject: {}, isPublicRepeat: bool, isModerationPost: bool, @@ -396,35 +399,43 @@ def _getAnnounceIconHtml(nickname: str, domainFull: str, """Returns html for announce icon/button """ announceStr = '' - if not isModerationPost and showRepeatIcon: - # don't allow announce/repeat of your own posts - announceIcon = 'repeat_inactive.png' - announceLink = 'repeat' - announceEmoji = '' + + if not showRepeatIcon: + return announceStr + + if isModerationPost: + return announceStr + + # don't allow announce/repeat of your own posts + announceIcon = 'repeat_inactive.png' + announceLink = 'repeat' + announceEmoji = '' + if not isPublicRepeat: + announceLink = 'repeatprivate' + announceTitle = translate['Repeat this post'] + + if announcedByPerson(isAnnounced, + postActor, nickname, domainFull): + announceIcon = 'repeat.png' + announceEmoji = '🔁 ' + announceLink = 'unrepeat' if not isPublicRepeat: - announceLink = 'repeatprivate' - announceTitle = translate['Repeat this post'] + announceLink = 'unrepeatprivate' + announceTitle = translate['Undo the repeat'] - if announcedByPerson(postJsonObject, nickname, domainFull): - announceIcon = 'repeat.png' - announceEmoji = '🔁 ' - if not isPublicRepeat: - announceLink = 'unrepeatprivate' - announceTitle = translate['Undo the repeat'] + announceStr = \ + ' \n' - announceStr = \ - ' \n' - - announceStr += \ - ' ' + \ - '' + announceEmoji + translate['Repeat this post'] + \
-            ' |\n' + announceStr += \ + ' ' + \ + '' + announceEmoji + announceTitle + \
+        ' |\n' return announceStr @@ -1295,21 +1306,27 @@ def individualPostAsHtml(allowDownloads: bool, return '' postJsonObject = postJsonAnnounce - if isRecentPost(postJsonObject): - announceFilename = \ - locatePost(baseDir, nickname, domain, - postJsonObject['id']) - if announceFilename and postJsonObject.get('actor'): - if not os.path.isfile(announceFilename + '.tts'): - updateSpeaker(baseDir, httpPrefix, - nickname, domain, domainFull, - postJsonObject, personCache, - translate, postJsonObject['actor'], - themeName) - ttsFile = open(announceFilename + '.tts', "w+") - if ttsFile: - ttsFile.write('\n') - ttsFile.close() + announceFilename = \ + locatePost(baseDir, nickname, domain, + postJsonObject['id']) + if announceFilename: + updateAnnounceCollection(recentPostsCache, + baseDir, announceFilename, + postActor, domainFull, False) + + # create a file for use by text-to-speech + if isRecentPost(postJsonObject): + if postJsonObject.get('actor'): + if not os.path.isfile(announceFilename + '.tts'): + updateSpeaker(baseDir, httpPrefix, + nickname, domain, domainFull, + postJsonObject, personCache, + translate, postJsonObject['actor'], + themeName) + ttsFile = open(announceFilename + '.tts', "w+") + if ttsFile: + ttsFile.write('\n') + ttsFile.close() isAnnounced = True @@ -1394,7 +1411,9 @@ def individualPostAsHtml(allowDownloads: bool, translate, isEvent) announceStr = \ - _getAnnounceIconHtml(nickname, domainFull, + _getAnnounceIconHtml(isAnnounced, + postActor, + nickname, domainFull, postJsonObject, isPublicRepeat, isModerationPost,