From e819c28b037e58ca8318ecf498a2dbe0aa47cd17 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Fri, 3 Sep 2021 12:30:23 +0100 Subject: [PATCH] Create html for posts sent to the outbox --- daemon.py | 6 +- inbox.py | 5 +- outbox.py | 37 ++++++++++- schedule.py | 6 +- tests.py | 2 +- webapp_post.py | 174 ++++++++++++++++++++++++++++++++++++------------- 6 files changed, 178 insertions(+), 52 deletions(-) diff --git a/daemon.py b/daemon.py index e0e00afe5..98d0c32bd 100644 --- a/daemon.py +++ b/daemon.py @@ -1195,7 +1195,11 @@ class PubServer(BaseHTTPRequestHandler): self.server.sharedItemsFederatedDomains, self.server.sharedItemFederationTokens, self.server.lowBandwidth, - self.server.signingPrivateKeyPem) + self.server.signingPrivateKeyPem, + self.server.peertubeInstances, + self.server.themeName, + self.server.maxLikeCount, + self.server.maxRecentPosts) def _postToOutboxThread(self, messageJson: {}) -> bool: """Creates a thread to send a post diff --git a/inbox.py b/inbox.py index 16dd8314f..df51ab579 100644 --- a/inbox.py +++ b/inbox.py @@ -2025,6 +2025,7 @@ def inboxUpdateIndex(boxname: str, baseDir: str, handle: str, if '/' in destinationFilename: destinationFilename = destinationFilename.split('/')[-1] + written = False if os.path.isfile(indexFilename): try: with open(indexFilename, 'r+') as indexFile: @@ -2032,6 +2033,7 @@ def inboxUpdateIndex(boxname: str, baseDir: str, handle: str, if destinationFilename + '\n' not in content: indexFile.seek(0, 0) indexFile.write(destinationFilename + '\n' + content) + written = True return True except Exception as e: print('WARN: Failed to write entry to index ' + str(e)) @@ -2039,10 +2041,11 @@ def inboxUpdateIndex(boxname: str, baseDir: str, handle: str, try: with open(indexFilename, 'w+') as indexFile: indexFile.write(destinationFilename + '\n') + written = True except Exception as e: print('WARN: Failed to write initial entry to index ' + str(e)) - return False + return written def _updateLastSeen(baseDir: str, handle: str, actor: str) -> None: diff --git a/outbox.py b/outbox.py index 1e56d0446..de654dc77 100644 --- a/outbox.py +++ b/outbox.py @@ -40,6 +40,7 @@ from inbox import inboxUpdateIndex from announce import outboxAnnounce from announce import outboxUndoAnnounce from follow import outboxUndoFollow +from follow import followerApprovalActive from skills import outboxSkills from availability import outboxAvailability from like import outboxLike @@ -49,6 +50,7 @@ from bookmarks import outboxUndoBookmark from delete import outboxDelete from shares import outboxShareUpload from shares import outboxUndoShareUpload +from webapp_post import individualPostAsHtml def _outboxPersonReceiveUpdate(recentPostsCache: {}, @@ -195,7 +197,10 @@ def postMessageToOutbox(session, translate: {}, sharedItemsFederatedDomains: [], sharedItemFederationTokens: {}, lowBandwidth: bool, - signingPrivateKeyPem: str) -> bool: + signingPrivateKeyPem: str, + peertubeInstances: str, theme: str, + maxLikeCount: int, + maxRecentPosts: int) -> bool: """post is received by the outbox Client to server message post https://www.w3.org/TR/activitypub/#client-to-server-outbox-delivery @@ -425,6 +430,36 @@ def postMessageToOutbox(session, translate: {}, inboxUpdateIndex(boxNameIndex, baseDir, postToNickname + '@' + domain, savedFilename, debug) + + # regenerate the html + useCacheOnly = False + pageNumber = 1 + showIndividualPostIcons = True + manuallyApproveFollowers = \ + followerApprovalActive(baseDir, postToNickname, domain) + individualPostAsHtml(signingPrivateKeyPem, + False, recentPostsCache, + maxRecentPosts, + translate, pageNumber, + baseDir, session, + cachedWebfingers, + personCache, + postToNickname, domain, port, + messageJson, None, True, + allowDeletion, + httpPrefix, __version__, + boxNameIndex, + YTReplacementDomain, + showPublishedDateOnly, + peertubeInstances, + allowLocalNetworkAccess, + theme, systemLanguage, + maxLikeCount, + boxNameIndex != 'dm', + showIndividualPostIcons, + manuallyApproveFollowers, + False, True, useCacheOnly) + if outboxAnnounce(recentPostsCache, baseDir, messageJson, debug): if debug: diff --git a/schedule.py b/schedule.py index e29d46cff..165160ced 100644 --- a/schedule.py +++ b/schedule.py @@ -116,7 +116,11 @@ def _updatePostSchedule(baseDir: str, handle: str, httpd, httpd.sharedItemsFederatedDomains, httpd.sharedItemFederationTokens, httpd.lowBandwidth, - httpd.signingPrivateKeyPem): + httpd.signingPrivateKeyPem, + httpd.peertubeInstances, + httpd.themeName, + httpd.maxLikeCount, + httpd.maxRecentPosts): indexLines.remove(line) os.remove(postFilename) continue diff --git a/tests.py b/tests.py index be014979e..4b5692f61 100644 --- a/tests.py +++ b/tests.py @@ -2874,7 +2874,7 @@ def testClientToServer(): showTestBoxes('alice', aliceInboxPath, aliceOutboxPath) showTestBoxes('bob', bobInboxPath, bobOutboxPath) assert len([name for name in os.listdir(bobOutboxPath) - if os.path.isfile(os.path.join(bobOutboxPath, name))]) == 3 + if os.path.isfile(os.path.join(bobOutboxPath, name))]) == 4 assert len([name for name in os.listdir(aliceInboxPath) if os.path.isfile(os.path.join(aliceInboxPath, name))]) == 1 print('EVENT: Post repeated') diff --git a/webapp_post.py b/webapp_post.py index be70bf37e..6c5ea8bad 100644 --- a/webapp_post.py +++ b/webapp_post.py @@ -245,13 +245,20 @@ def _getAvatarImageHtml(showAvatarOptions: bool, avatarLink = '' if '/users/news/' not in avatarUrl: avatarLink = ' ' + showProfileStr = 'Show profile' + if translate.get(showProfileStr): + showProfileStr = translate[showProfileStr] avatarLink += \ ' \n' if showAvatarOptions and \ domainFull + '/users/' + nickname not in postActor: + showOptionsForThisPersonStr = 'Show options for this person' + if translate.get(showOptionsForThisPersonStr): + showOptionsForThisPersonStr = \ + translate[showOptionsForThisPersonStr] if '/users/news/' not in avatarUrl: avatarLink = \ ' \n' avatarLink += \ ' \n' else: # don't link to the person options for the news account avatarLink += \ ' \n' return avatarLink.strip() @@ -305,7 +312,9 @@ def _getReplyIconHtml(nickname: str, isPublicRepeat: bool, replyToLink += pageNumberParam replyStr = '' - replyToThisPostStr = translate['Reply to this post'] + replyToThisPostStr = 'Reply to this post' + if translate.get(replyToThisPostStr): + replyToThisPostStr = translate[replyToThisPostStr] conversationStr = '' if conversationId: conversationStr = '?conversationId=' + conversationId @@ -363,7 +372,9 @@ def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str, return editStr if isBlogPost(postJsonObject): - editBlogPostStr = translate['Edit blog post'] + editBlogPostStr = 'Edit blog post' + if translate.get(editBlogPostStr): + editBlogPostStr = translate[editBlogPostStr] if not isNewsPost(postJsonObject): editStr += \ ' ' + \ @@ -388,7 +399,9 @@ def _getEditIconHtml(baseDir: str, nickname: str, domainFull: str, editBlogPostStr + '" alt="' + editBlogPostStr + \ ' |" src="/icons/edit.png"/>\n' elif isEvent: - editEventStr = translate['Edit event'] + editEventStr = 'Edit event' + if translate.get(editEventStr): + editEventStr = translate[editEventStr] editStr += \ ' ' + \ '\n' + '" title="' + muteThisPostStr + '">\n' muteStr += \ ' ' + \ '' + \
-            translate['Mute this post'] + \
-            ' |\n' else: + undoMuteStr = 'Undo mute' + if translate.get(undoMuteStr): + undoMuteStr = translate[undoMuteStr] muteStr = \ ' \n' + timelinePostBookmark + '" title="' + undoMuteStr + '">\n' muteStr += \ ' ' + \ - '🔇 ' + translate['Undo mute'] + \
-            ' |\n' return muteStr @@ -622,16 +654,19 @@ def _getDeleteIconHtml(nickname: str, domainFull: str, messageId.startswith(postActor))): if '/users/' + nickname + '/' in messageId: if not isNewsPost(postJsonObject): + deleteThisPostStr = 'Delete this post' + if translate.get(deleteThisPostStr): + deleteThisPostStr = translate[deleteThisPostStr] deleteStr = \ ' \n' + '" title="' + deleteThisPostStr + '">\n' deleteStr += \ ' ' + \ '' + \
-                    translate['Delete this post'] + \
-                    ' |\n' return deleteStr @@ -699,7 +734,10 @@ def _getBlogCitationsHtml(boxName: str, '' + tagJson['name'] + '\n' if citationsStr: - citationsStr = '

' + translate['Citations'] + ':

' + \ + translatedCitationsStr = 'Citations' + if translate.get(translatedCitationsStr): + translatedCitationsStr = translate[translatedCitationsStr] + citationsStr = '

' + translatedCitationsStr + ':

' + \ '\n' return citationsStr @@ -707,9 +745,12 @@ def _getBlogCitationsHtml(boxName: str, def _boostOwnPostHtml(translate: {}) -> str: """The html title for announcing your own post """ + announcesStr = 'announces' + if translate.get(announcesStr): + announcesStr = translate[announcesStr] return ' ' + translate['announces'] + \
+        announcesStr + \
+        '\n' @@ -719,9 +760,12 @@ def _announceUnattributedHtml(translate: {}, """Returns the html for an announce title where there is no attribution on the announced post """ + announcesStr = 'announces' + if translate.get(announcesStr): + announcesStr = translate[announcesStr] return ' ' + \
-        translate['announces'] + '\n' + \ ' \n' + \ ' \n' \ ' ' \ ' \n \n' return (titleStr, replyAvatarImageInPost, @@ -842,9 +893,12 @@ def _getPostTitleAnnounceHtml(baseDir: str, def _replyToYourselfHtml(translate: {}) -> str: """Returns html for a title which is a reply to yourself """ + replyingToThemselvesStr = 'replying to themselves' + if translate.get(replyingToThemselvesStr): + replyingToThemselvesStr = translate[replyingToThemselvesStr] return ' ' + translate['replying to themselves'] + \
+        replyingToThemselvesStr + \
+        '\n' @@ -853,9 +907,12 @@ def _replyToUnknownHtml(translate: {}, postJsonObject: {}) -> str: """Returns the html title for a reply to an unknown handle """ + replyingToStr = 'replying to' + if translate.get(replyingToStr): + replyingToStr = translate[replyingToStr] return ' ' + \
-        translate['replying to'] + '\n' + \ ' \n' + \ ' \n' + \ ' \n' + \ ' \n' + \ '  \n \n' @@ -1542,7 +1608,10 @@ def individualPostAsHtml(signingPrivateKeyPem: str, postIsSensitive = postJsonObject['object']['sensitive'] else: # add a generic summary if none is provided - postJsonObject['object']['summary'] = translate['Sensitive'] + sensitiveStr = 'Sensitive' + if translate.get(sensitiveStr): + sensitiveStr = translate[sensitiveStr] + postJsonObject['object']['summary'] = sensitiveStr # add an extra line if there is a content warning, # for better vertical spacing on mobile @@ -1594,7 +1663,10 @@ def individualPostAsHtml(signingPrivateKeyPem: str, else: objectContent = contentStr else: - objectContent = '🔒 ' + translate['Encrypted'] + encryptedStr = 'Encrypted' + if translate.get(encryptedStr): + encryptedStr = translate[encryptedStr] + objectContent = '🔒 ' + encryptedStr objectContent = '
' + objectContent + '
' @@ -1711,9 +1783,11 @@ def htmlIndividualPost(cssCache: {}, likedByDomain, likedByPort = getDomainFromActor(likedBy) likedByDomain = getFullDomain(likedByDomain, likedByPort) likedByHandle = likedByNickname + '@' + likedByDomain + likedByStr = 'Liked by' + if translate.get(likedByStr): + likedByStr = translate[likedByStr] postStr += \ - '

' + translate['Liked by'] + \ - ' @' + \ + '

' + likedByStr + ' @' + \ likedByHandle + '\n' domainFull = getFullDomain(domain, port) @@ -1726,10 +1800,16 @@ def htmlIndividualPost(cssCache: {}, ' \n' if not isFollowingActor(baseDir, nickname, domainFull, likedBy): + translateFollowStr = 'Follow' + if translate.get(translateFollowStr): + translateFollowStr = translate[translateFollowStr] followStr += ' \n' + 'name="submitSearch">' + translateFollowStr + '\n' + goBackStr = 'Go Back' + if translate.get(goBackStr): + goBackStr = translate[goBackStr] followStr += ' \n' + 'name="submitBack">' + goBackStr + '\n' followStr += ' \n' postStr += followStr + '

\n'