From e6be96c492a065c9bfc0def8177644489b3df9e7 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 13:35:44 +0100 Subject: [PATCH 1/9] Unrepeat link --- webapp_post.py | 1 + 1 file changed, 1 insertion(+) diff --git a/webapp_post.py b/webapp_post.py index 466ad63db..ce1f516e4 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -408,6 +408,7 @@ def _getAnnounceIconHtml(nickname: str, domainFull: str, if announcedByPerson(postJsonObject, nickname, domainFull): announceIcon = 'repeat.png' announceEmoji = '🔁 ' + announceLink = 'unrepeat' if not isPublicRepeat: announceLink = 'unrepeatprivate' announceTitle = translate['Undo the repeat'] From 38c1d6881668ec9c829fcbb495e9742f95abdc39 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 13:42:01 +0100 Subject: [PATCH 2/9] Tidying --- webapp_post.py | 60 +++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/webapp_post.py b/webapp_post.py index ce1f516e4..4ec743f7f 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -396,36 +396,42 @@ 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(postJsonObject, 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 = '🔁 ' - announceLink = 'unrepeat' - if not isPublicRepeat: - announceLink = 'unrepeatprivate' - announceTitle = translate['Undo the repeat'] + announceStr = \ + ' \n' - announceStr = \ - ' \n' - - announceStr += \ - ' ' + \ - '' + announceEmoji + translate['Repeat this post'] + \
-            ' |\n' + announceStr += \ + ' ' + \ + '' + announceEmoji + translate['Repeat this post'] + \
+        ' |\n' return announceStr From 469e8304be7e52595f5780489dbed80ffa468edb Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 14:26:00 +0100 Subject: [PATCH 3/9] Check announces --- announce.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/announce.py b/announce.py index 435cd911e..ef946d5a3 100644 --- a/announce.py +++ b/announce.py @@ -76,9 +76,17 @@ def outboxAnnounce(recentPostsCache: {}, def announcedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool: """Returns True if the given post is announced by the given person """ + if not postJsonObject.get('type'): + return False if not postJsonObject.get('object'): return False - if not isinstance(postJsonObject['object'], dict): + if isinstance(postJsonObject['object'], str): + if postJsonObject['type'] == 'Announce' and \ + postJsonObject.get('actor'): + actorMatch = domain + '/users/' + nickname + if postJsonObject['actor'].endswith(actorMatch): + return True + elif not isinstance(postJsonObject['object'], dict): return False # not to be confused with shared items if not postJsonObject['object'].get('shares'): From 019f885c01a6255a8832a2c869af55740faa9b14 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 16:58:39 +0100 Subject: [PATCH 4/9] Tidying --- utils.py | 109 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 54 deletions(-) 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: From afedb302b0ccd9570c779574abb422622fe36a90 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 17:56:21 +0100 Subject: [PATCH 5/9] Tidying --- announce.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/announce.py b/announce.py index ef946d5a3..5ec2ee386 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'): @@ -132,7 +132,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', From 7c5317224a971353dc4ff5549a2bf89ae6865350 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 20:57:13 +0100 Subject: [PATCH 6/9] Check that share is added to announce post --- webapp_post.py | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/webapp_post.py b/webapp_post.py index 4ec743f7f..e965f484c 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 @@ -1302,21 +1303,26 @@ 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) + + 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 From e70a9b96c591d1094d6a37354b94cdf7a3055eb4 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 22:10:55 +0100 Subject: [PATCH 7/9] Showing announced posts --- announce.py | 31 ++++++------------------------- webapp_post.py | 10 +++++++--- 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/announce.py b/announce.py index 5ec2ee386..e42addf0d 100644 --- a/announce.py +++ b/announce.py @@ -73,34 +73,15 @@ def outboxAnnounce(recentPostsCache: {}, return False -def announcedByPerson(postJsonObject: {}, nickname: str, domain: str) -> bool: +def announcedByPerson(isAnnounced: bool, postJsonObject: {}, + nickname: str, domainFull: str) -> bool: """Returns True if the given post is announced by the given person """ - if not postJsonObject.get('type'): + if not postJsonObject.get('actor'): return False - if not postJsonObject.get('object'): - return False - if isinstance(postJsonObject['object'], str): - if postJsonObject['type'] == 'Announce' and \ - postJsonObject.get('actor'): - actorMatch = domain + '/users/' + nickname - if postJsonObject['actor'].endswith(actorMatch): - return True - elif 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 \ + postJsonObject['actor'].endswith(domainFull + '/users/' + nickname): + return True return False diff --git a/webapp_post.py b/webapp_post.py index e965f484c..98fc78074 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -385,7 +385,8 @@ def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str, return editStr -def _getAnnounceIconHtml(nickname: str, domainFull: str, +def _getAnnounceIconHtml(isAnnounced: bool, + nickname: str, domainFull: str, postJsonObject: {}, isPublicRepeat: bool, isModerationPost: bool, @@ -412,7 +413,8 @@ def _getAnnounceIconHtml(nickname: str, domainFull: str, announceLink = 'repeatprivate' announceTitle = translate['Repeat this post'] - if announcedByPerson(postJsonObject, nickname, domainFull): + if announcedByPerson(isAnnounced, + postJsonObject, nickname, domainFull): announceIcon = 'repeat.png' announceEmoji = '🔁 ' announceLink = 'unrepeat' @@ -1311,6 +1313,7 @@ def individualPostAsHtml(allowDownloads: bool, 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'): @@ -1407,7 +1410,8 @@ def individualPostAsHtml(allowDownloads: bool, translate, isEvent) announceStr = \ - _getAnnounceIconHtml(nickname, domainFull, + _getAnnounceIconHtml(isAnnounced, + nickname, domainFull, postJsonObject, isPublicRepeat, isModerationPost, From 539766b74d4d5aec20e275175684f9ba8a6226b2 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 23:07:26 +0100 Subject: [PATCH 8/9] Repeat strings --- webapp_post.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp_post.py b/webapp_post.py index 98fc78074..c2031c6f8 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -432,8 +432,8 @@ def _getAnnounceIconHtml(isAnnounced: bool, announceStr += \ ' ' + \ - '' + announceEmoji + translate['Repeat this post'] + \
+        '<img loading=\n' return announceStr From db3243724dc08e1d44ebd9f1615c46c3be51acb9 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 7 May 2021 23:49:04 +0100 Subject: [PATCH 9/9] Detecting announces --- announce.py | 6 +++--- webapp_post.py | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/announce.py b/announce.py index e42addf0d..2b9a1cc64 100644 --- a/announce.py +++ b/announce.py @@ -73,14 +73,14 @@ def outboxAnnounce(recentPostsCache: {}, return False -def announcedByPerson(isAnnounced: bool, postJsonObject: {}, +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('actor'): + if not postActor: return False if isAnnounced and \ - postJsonObject['actor'].endswith(domainFull + '/users/' + nickname): + postActor.endswith(domainFull + '/users/' + nickname): return True return False diff --git a/webapp_post.py b/webapp_post.py index c2031c6f8..fb91b929f 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -386,6 +386,7 @@ def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str, def _getAnnounceIconHtml(isAnnounced: bool, + postActor: str, nickname: str, domainFull: str, postJsonObject: {}, isPublicRepeat: bool, @@ -414,7 +415,7 @@ def _getAnnounceIconHtml(isAnnounced: bool, announceTitle = translate['Repeat this post'] if announcedByPerson(isAnnounced, - postJsonObject, nickname, domainFull): + postActor, nickname, domainFull): announceIcon = 'repeat.png' announceEmoji = '🔁 ' announceLink = 'unrepeat' @@ -1411,6 +1412,7 @@ def individualPostAsHtml(allowDownloads: bool, announceStr = \ _getAnnounceIconHtml(isAnnounced, + postActor, nickname, domainFull, postJsonObject, isPublicRepeat,