From 166946b54165f2fc97c57f576b2d8152d31ab81d Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:01:05 +0000 Subject: [PATCH 1/6] Extra notification method --- notifications_client.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/notifications_client.py b/notifications_client.py index c8662d01f..e0c43c9f2 100644 --- a/notifications_client.py +++ b/notifications_client.py @@ -95,6 +95,10 @@ def _desktopNotification(notificationType: str, if notificationType == 'notify-send': # Ubuntu os.system('notify-send "' + title + '" "' + message + '"') + elif notificationType == 'zenity': + # Zenity + os.system('zenity --notification --title "' + title + + '" --text="' + message + '"') elif notificationType == 'osascript': # Mac os.system("osascript -e 'display notification \"" + From ff2fb5bcfe4111320bb510177ae6522823e093f0 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:02:12 +0000 Subject: [PATCH 2/6] Extra notification method --- epicyon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/epicyon.py b/epicyon.py index 0b9ffe78f..19db2a15c 100644 --- a/epicyon.py +++ b/epicyon.py @@ -113,7 +113,7 @@ parser.add_argument('--notificationType', '--notifyType', dest='notificationType', type=str, default='notify-send', help='Type of desktop notification command: ' + - 'notify-send/osascript/New-BurntToastNotification') + 'notify-send/zenity/osascript/New-BurntToastNotification') parser.add_argument('-o', '--onion', dest='onion', type=str, default=None, help='Onion domain name of the server if ' + From 073b322d36e29ad759822332594c60d6c10d31f8 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:10:56 +0000 Subject: [PATCH 3/6] Preserve original notification content --- speaker.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/speaker.py b/speaker.py index b74d6a529..58c04b932 100644 --- a/speaker.py +++ b/speaker.py @@ -274,7 +274,8 @@ def getSpeakerFromServer(baseDir: str, session, def _speakerEndpointJson(displayName: str, summary: str, - content: str, imageDescription: str, + content: str, sayContent: str, + imageDescription: str, links: [], gender: str, postId: str, postDM: bool, postReply: bool, followRequestsExist: bool, @@ -285,7 +286,8 @@ def _speakerEndpointJson(displayName: str, summary: str, speakerJson = { "name": displayName, "summary": summary, - "say": content, + "content": content, + "say": sayContent, "imageDescription": imageDescription, "detectedLinks": links, "id": postId, @@ -412,11 +414,12 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, content = content.replace(' <3', ' ' + translate['heart']) content = removeHtml(htmlReplaceQuoteMarks(content)) content = speakerReplaceLinks(content, translate, detectedLinks) - content = _speakerPronounce(baseDir, content, translate) + sayContent = content + sayContent = _speakerPronounce(baseDir, content, translate) # replace all double spaces - while ' ' in content: - content = content.replace(' ', ' ') - content = content.replace(' . ', '. ') + while ' ' in sayContent: + sayContent = sayContent.replace(' ', ' ') + sayContent = sayContent.replace(' . ', '. ') imageDescription = '' if postJsonObject['object'].get('attachment'): @@ -451,8 +454,9 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, announcedDomain, announcedport = getDomainFromActor(announcingActor) if announcedNickname and announcedDomain: announcedHandle = announcedNickname + '@' + announcedDomain - content = \ - translate['announces'] + ' ' + announcedHandle + '. ' + content + sayContent = \ + translate['announces'] + ' ' + \ + announcedHandle + '. ' + sayContent postId = None if postJsonObject['object'].get('id'): postId = postJsonObject['object']['id'] @@ -484,7 +488,7 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, postShare = os.path.isfile(shareFilename) return _speakerEndpointJson(speakerName, summary, - content, imageDescription, + content, sayContent, imageDescription, detectedLinks, gender, postId, postDM, postReply, followRequestsExist, From 8f0c6e5b352fcc37aded9fcbc2b160697c5a1d4f Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:15:25 +0000 Subject: [PATCH 4/6] Include publication date in speaker endpoint --- speaker.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/speaker.py b/speaker.py index 58c04b932..cdce66140 100644 --- a/speaker.py +++ b/speaker.py @@ -279,7 +279,7 @@ def _speakerEndpointJson(displayName: str, summary: str, links: [], gender: str, postId: str, postDM: bool, postReply: bool, followRequestsExist: bool, - likedBy: str, postCal: bool, + likedBy: str, published: str, postCal: bool, postShare: bool, themeName: str) -> {}: """Returns a json endpoint for the TTS speaker """ @@ -288,6 +288,7 @@ def _speakerEndpointJson(displayName: str, summary: str, "summary": summary, "content": content, "say": sayContent, + "published": published, "imageDescription": imageDescription, "detectedLinks": links, "id": postId, @@ -433,6 +434,10 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, imageDescription += \ img['name'] + '. ' + published = '' + if postJsonObject['object'].get('published'): + published = postJsonObject['object']['published'] + summary = '' if postJsonObject['object'].get('summary'): if isinstance(postJsonObject['object']['summary'], str): @@ -492,7 +497,7 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, detectedLinks, gender, postId, postDM, postReply, followRequestsExist, - likedBy, + likedBy, published, postCal, postShare, themeName) From 902a4e157374ac7250967d4e12b504f32236a6d1 Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:32:39 +0000 Subject: [PATCH 5/6] Remove extra spaces --- speaker.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/speaker.py b/speaker.py index cdce66140..fef271773 100644 --- a/speaker.py +++ b/speaker.py @@ -415,12 +415,16 @@ def _postToSpeakerJson(baseDir: str, httpPrefix: str, content = content.replace(' <3', ' ' + translate['heart']) content = removeHtml(htmlReplaceQuoteMarks(content)) content = speakerReplaceLinks(content, translate, detectedLinks) + # replace all double spaces + while ' ' in content: + content = content.replace(' ', ' ') + content = content.replace(' . ', '. ').strip() sayContent = content sayContent = _speakerPronounce(baseDir, content, translate) # replace all double spaces while ' ' in sayContent: sayContent = sayContent.replace(' ', ' ') - sayContent = sayContent.replace(' . ', '. ') + sayContent = sayContent.replace(' . ', '. ').strip() imageDescription = '' if postJsonObject['object'].get('attachment'): From 08c29c6e2460d581bda2c199c1a440445b5e20ed Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Thu, 11 Mar 2021 10:47:52 +0000 Subject: [PATCH 6/6] Display original message content in notification client --- notifications_client.py | 101 +++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 44 deletions(-) diff --git a/notifications_client.py b/notifications_client.py index e0c43c9f2..2d3cc6d40 100644 --- a/notifications_client.py +++ b/notifications_client.py @@ -122,14 +122,14 @@ def _textToSpeech(sayStr: str, screenreader: str, systemLanguage, sayStr) -def _sayCommand(sayStr: str, screenreader: str, +def _sayCommand(content: str, sayStr: str, screenreader: str, systemLanguage: str, espeak=None, speakerName='screen reader', speakerGender='They/Them') -> None: """Speaks a command """ - print(sayStr) + print(content) if not screenreader: return @@ -157,29 +157,30 @@ def _notificationReplyToPost(session, postId: str, toNickname = getNicknameFromActor(postId) toDomain, toPort = getDomainFromActor(postId) sayStr = 'Replying to ' + toNickname + '@' + toDomain - _sayCommand(sayStr, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sayStr = 'Type your reply message, then press Enter.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) replyMessage = input() if not replyMessage: sayStr = 'No reply was entered.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return replyMessage = replyMessage.strip() if not replyMessage: sayStr = 'No reply was entered.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return sayStr = 'You entered this reply:' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) - _sayCommand(replyMessage, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) + _sayCommand(replyMessage, replyMessage, screenreader, + systemLanguage, espeak) sayStr = 'Send this reply, yes or no?' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) yesno = input() if 'y' not in yesno.lower(): sayStr = 'Abandoning reply' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return ccUrl = None followersOnly = False @@ -190,7 +191,7 @@ def _notificationReplyToPost(session, postId: str, subject = None commentsEnabled = True sayStr = 'Sending reply' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) if sendPostViaServer(__version__, baseDir, session, nickname, password, domain, port, @@ -203,7 +204,7 @@ def _notificationReplyToPost(session, postId: str, sayStr = 'Reply sent' else: sayStr = 'Reply failed' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) def _notificationNewPost(session, @@ -216,28 +217,28 @@ def _notificationNewPost(session, """Use the notification client to create a new post """ sayStr = 'Create new post' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sayStr = 'Type your post, then press Enter.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) newMessage = input() if not newMessage: sayStr = 'No post was entered.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return newMessage = newMessage.strip() if not newMessage: sayStr = 'No post was entered.' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return sayStr = 'You entered this public post:' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) - _sayCommand(newMessage, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) + _sayCommand(newMessage, newMessage, screenreader, systemLanguage, espeak) sayStr = 'Send this post, yes or no?' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) yesno = input() if 'y' not in yesno.lower(): sayStr = 'Abandoning new post' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) return ccUrl = None followersOnly = False @@ -249,7 +250,7 @@ def _notificationNewPost(session, commentsEnabled = True subject = None sayStr = 'Sending' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) if sendPostViaServer(__version__, baseDir, session, nickname, password, domain, port, @@ -262,7 +263,7 @@ def _notificationNewPost(session, sayStr = 'Post sent' else: sayStr = 'Post failed' - _sayCommand(sayStr, screenreader, systemLanguage, espeak) + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, @@ -285,7 +286,7 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, return sayStr = 'Running ' + screenreader + ' for ' + nickname + '@' + domain - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) else: print('Running desktop notifications for ' + nickname + '@' + domain) @@ -293,10 +294,10 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, sayStr = 'Notification sounds on' else: sayStr = 'Notification sounds off' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sayStr = '/q or /quit to exit' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) print('') keyPress = _waitForKeypress(2, debug) @@ -414,15 +415,19 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, messageStr = speakerJson['say'] + '. ' + \ speakerJson['imageDescription'] + content = messageStr + if speakerJson.get('content'): + content = speakerJson['content'] + # say the speaker's name - _sayCommand(nameStr, screenreader, + _sayCommand(nameStr, nameStr, screenreader, systemLanguage, espeak, nameStr, gender) time.sleep(2) # speak the post content - _sayCommand(messageStr, screenreader, + _sayCommand(content, messageStr, screenreader, systemLanguage, espeak, nameStr, gender) @@ -437,7 +442,7 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, keyPress = keyPress[1:] if keyPress == 'q' or keyPress == 'quit' or keyPress == 'exit': sayStr = 'Quit' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) if screenreader: keyPress = _waitForKeypress(2, debug) @@ -469,7 +474,8 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, print('') elif keyPress == 'like': if nameStr and gender and messageStr: - _sayCommand('Liking post by ' + nameStr, + sayStr = 'Liking post by ' + nameStr + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sessionLike = createSession(proxyType) @@ -482,7 +488,8 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, print('') elif keyPress == 'unlike' or keyPress == 'undo like': if nameStr and gender and messageStr: - _sayCommand('Undoing like of post by ' + nameStr, + sayStr = 'Undoing like of post by ' + nameStr + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sessionUnlike = createSession(proxyType) @@ -499,7 +506,8 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, if speakerJson.get('id'): if nameStr and gender and messageStr: postId = speakerJson['id'] - _sayCommand('Announcing post by ' + nameStr, + sayStr = 'Announcing post by ' + nameStr + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sessionAnnounce = createSession(proxyType) @@ -519,8 +527,9 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, followDomain, followPort = \ getDomainFromActor(followHandle) if followNickname and followDomain: - _sayCommand('Sending follow request to ' + - followNickname + '@' + followDomain, + sayStr = 'Sending follow request to ' + \ + followNickname + '@' + followDomain + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sessionFollow = createSession(proxyType) sendFollowRequestViaServer(baseDir, sessionFollow, @@ -534,7 +543,8 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, personCache, debug, __version__) else: - _sayCommand(followHandle + ' is not valid', + sayStr = followHandle + ' is not valid' + _sayCommand(sayStr, screenreader, systemLanguage, espeak) print('') elif (keyPress.startswith('unfollow ') or @@ -548,8 +558,9 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, followDomain, followPort = \ getDomainFromActor(followHandle) if followNickname and followDomain: - _sayCommand('Stop following ' + - followNickname + '@' + followDomain, + sayStr = 'Stop following ' + \ + followNickname + '@' + followDomain + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) sessionUnfollow = createSession(proxyType) sendUnfollowRequestViaServer(baseDir, sessionUnfollow, @@ -563,28 +574,30 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, personCache, debug, __version__) else: - _sayCommand(followHandle + ' is not valid', + sayStr = followHandle + ' is not valid' + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) print('') elif (keyPress == 'repeat' or keyPress == 'replay' or keyPress == 'rp'): - if nameStr and gender and messageStr: - _sayCommand('Repeating ' + nameStr, screenreader, + if nameStr and gender and messageStr and content: + sayStr = 'Repeating ' + nameStr, screenreader + _sayCommand(sayStr, sayStr, systemLanguage, espeak, nameStr, gender) time.sleep(2) - _sayCommand(messageStr, screenreader, + _sayCommand(content, messageStr, screenreader, systemLanguage, espeak, nameStr, gender) print('') elif keyPress == 'sounds on' or keyPress == 'sound': sayStr = 'Notification sounds on' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) notificationSounds = True elif keyPress == 'sounds off' or keyPress == 'nosound': sayStr = 'Notification sounds off' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) notificationSounds = False elif (keyPress == 'speak' or @@ -595,7 +608,7 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, if originalScreenReader: screenreader = originalScreenReader sayStr = 'Screen reader on' - _sayCommand(sayStr, screenreader, + _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) else: print('No --screenreader option was specified') @@ -607,7 +620,7 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str, if originalScreenReader: screenreader = None sayStr = 'Screen reader off' - _sayCommand(sayStr, originalScreenReader, + _sayCommand(sayStr, sayStr, originalScreenReader, systemLanguage, espeak) else: print('No --screenreader option was specified')