mirror of https://gitlab.com/bashrc2/epicyon
Add dm and reply notifications to speaker endpoint
parent
6a388a7103
commit
66056face5
12
inbox.py
12
inbox.py
|
@ -58,12 +58,12 @@ from filters import isFiltered
|
||||||
from utils import updateAnnounceCollection
|
from utils import updateAnnounceCollection
|
||||||
from utils import undoAnnounceCollectionEntry
|
from utils import undoAnnounceCollectionEntry
|
||||||
from utils import dangerousMarkup
|
from utils import dangerousMarkup
|
||||||
|
from utils import isDM
|
||||||
|
from utils import isReply
|
||||||
from httpsig import messageContentDigest
|
from httpsig import messageContentDigest
|
||||||
from posts import createDirectMessagePost
|
from posts import createDirectMessagePost
|
||||||
from posts import validContentWarning
|
from posts import validContentWarning
|
||||||
from posts import downloadAnnounce
|
from posts import downloadAnnounce
|
||||||
from posts import isDM
|
|
||||||
from posts import isReply
|
|
||||||
from posts import isMuted
|
from posts import isMuted
|
||||||
from posts import isImageMedia
|
from posts import isImageMedia
|
||||||
from posts import sendSignedJson
|
from posts import sendSignedJson
|
||||||
|
@ -1408,7 +1408,9 @@ def _receiveAnnounce(recentPostsCache: {},
|
||||||
|
|
||||||
if isRecentPost(postJsonObject):
|
if isRecentPost(postJsonObject):
|
||||||
if not os.path.isfile(postFilename + '.tts'):
|
if not os.path.isfile(postFilename + '.tts'):
|
||||||
updateSpeaker(baseDir, nickname, domain,
|
domainFull = getFullDomain(domain, port)
|
||||||
|
updateSpeaker(baseDir, httpPrefix,
|
||||||
|
nickname, domain, domainFull,
|
||||||
postJsonObject, personCache,
|
postJsonObject, personCache,
|
||||||
translate, lookupActor)
|
translate, lookupActor)
|
||||||
ttsFile = open(postFilename + '.tts', "w+")
|
ttsFile = open(postFilename + '.tts', "w+")
|
||||||
|
@ -2491,7 +2493,9 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
else:
|
else:
|
||||||
if boxname == 'inbox':
|
if boxname == 'inbox':
|
||||||
if isRecentPost(postJsonObject):
|
if isRecentPost(postJsonObject):
|
||||||
updateSpeaker(baseDir, nickname, domain,
|
domainFull = getFullDomain(domain, port)
|
||||||
|
updateSpeaker(baseDir, httpPrefix,
|
||||||
|
nickname, domain, domainFull,
|
||||||
postJsonObject, personCache,
|
postJsonObject, personCache,
|
||||||
translate, None)
|
translate, None)
|
||||||
if not unitTest:
|
if not unitTest:
|
||||||
|
|
62
posts.py
62
posts.py
|
@ -2921,34 +2921,6 @@ def createModeration(baseDir: str, nickname: str, domain: str, port: int,
|
||||||
return boxItems
|
return boxItems
|
||||||
|
|
||||||
|
|
||||||
def isDM(postJsonObject: {}) -> bool:
|
|
||||||
"""Returns true if the given post is a DM
|
|
||||||
"""
|
|
||||||
if postJsonObject['type'] != 'Create':
|
|
||||||
return False
|
|
||||||
if not postJsonObject.get('object'):
|
|
||||||
return False
|
|
||||||
if not isinstance(postJsonObject['object'], dict):
|
|
||||||
return False
|
|
||||||
if postJsonObject['object']['type'] != 'Note' and \
|
|
||||||
postJsonObject['object']['type'] != 'Patch' and \
|
|
||||||
postJsonObject['object']['type'] != 'EncryptedMessage' and \
|
|
||||||
postJsonObject['object']['type'] != 'Article':
|
|
||||||
return False
|
|
||||||
if postJsonObject['object'].get('moderationStatus'):
|
|
||||||
return False
|
|
||||||
fields = ('to', 'cc')
|
|
||||||
for f in fields:
|
|
||||||
if not postJsonObject['object'].get(f):
|
|
||||||
continue
|
|
||||||
for toAddress in postJsonObject['object'][f]:
|
|
||||||
if toAddress.endswith('#Public'):
|
|
||||||
return False
|
|
||||||
if toAddress.endswith('followers'):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def isImageMedia(session, baseDir: str, httpPrefix: str,
|
def isImageMedia(session, baseDir: str, httpPrefix: str,
|
||||||
nickname: str, domain: str,
|
nickname: str, domain: str,
|
||||||
postJsonObject: {}, translate: {},
|
postJsonObject: {}, translate: {},
|
||||||
|
@ -2992,40 +2964,6 @@ def isImageMedia(session, baseDir: str, httpPrefix: str,
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def isReply(postJsonObject: {}, actor: str) -> bool:
|
|
||||||
"""Returns true if the given post is a reply to the given actor
|
|
||||||
"""
|
|
||||||
if postJsonObject['type'] != 'Create':
|
|
||||||
return False
|
|
||||||
if not postJsonObject.get('object'):
|
|
||||||
return False
|
|
||||||
if not isinstance(postJsonObject['object'], dict):
|
|
||||||
return False
|
|
||||||
if postJsonObject['object'].get('moderationStatus'):
|
|
||||||
return False
|
|
||||||
if postJsonObject['object']['type'] != 'Note' and \
|
|
||||||
postJsonObject['object']['type'] != 'EncryptedMessage' and \
|
|
||||||
postJsonObject['object']['type'] != 'Article':
|
|
||||||
return False
|
|
||||||
if postJsonObject['object'].get('inReplyTo'):
|
|
||||||
if isinstance(postJsonObject['object']['inReplyTo'], str):
|
|
||||||
if postJsonObject['object']['inReplyTo'].startswith(actor):
|
|
||||||
return True
|
|
||||||
if not postJsonObject['object'].get('tag'):
|
|
||||||
return False
|
|
||||||
if not isinstance(postJsonObject['object']['tag'], list):
|
|
||||||
return False
|
|
||||||
for tag in postJsonObject['object']['tag']:
|
|
||||||
if not tag.get('type'):
|
|
||||||
continue
|
|
||||||
if tag['type'] == 'Mention':
|
|
||||||
if not tag.get('href'):
|
|
||||||
continue
|
|
||||||
if actor in tag['href']:
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def _addPostStringToTimeline(postStr: str, boxname: str,
|
def _addPostStringToTimeline(postStr: str, boxname: str,
|
||||||
postsInBox: [], boxActor: str) -> bool:
|
postsInBox: [], boxActor: str) -> bool:
|
||||||
""" is this a valid timeline post?
|
""" is this a valid timeline post?
|
||||||
|
|
27
speaker.py
27
speaker.py
|
@ -12,6 +12,8 @@ import random
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
from auth import createBasicAuthHeader
|
from auth import createBasicAuthHeader
|
||||||
from session import getJson
|
from session import getJson
|
||||||
|
from utils import isDM
|
||||||
|
from utils import isReply
|
||||||
from utils import camelCaseSplit
|
from utils import camelCaseSplit
|
||||||
from utils import getDomainFromActor
|
from utils import getDomainFromActor
|
||||||
from utils import getNicknameFromActor
|
from utils import getNicknameFromActor
|
||||||
|
@ -263,7 +265,8 @@ def getSpeakerFromServer(baseDir: str, session,
|
||||||
|
|
||||||
def _speakerEndpointJson(displayName: str, summary: str,
|
def _speakerEndpointJson(displayName: str, summary: str,
|
||||||
content: str, imageDescription: str,
|
content: str, imageDescription: str,
|
||||||
links: [], gender: str, postId: str) -> {}:
|
links: [], gender: str, postId: str,
|
||||||
|
postDM: bool, postReply: bool) -> {}:
|
||||||
"""Returns a json endpoint for the TTS speaker
|
"""Returns a json endpoint for the TTS speaker
|
||||||
"""
|
"""
|
||||||
speakerJson = {
|
speakerJson = {
|
||||||
|
@ -272,7 +275,11 @@ def _speakerEndpointJson(displayName: str, summary: str,
|
||||||
"say": content,
|
"say": content,
|
||||||
"imageDescription": imageDescription,
|
"imageDescription": imageDescription,
|
||||||
"detectedLinks": links,
|
"detectedLinks": links,
|
||||||
"id": postId
|
"id": postId,
|
||||||
|
"notify": {
|
||||||
|
"dm": postDM,
|
||||||
|
"reply": postReply
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if gender:
|
if gender:
|
||||||
speakerJson['gender'] = gender
|
speakerJson['gender'] = gender
|
||||||
|
@ -360,7 +367,8 @@ def getSSMLbox(baseDir: str, path: str,
|
||||||
instanceTitle, gender)
|
instanceTitle, gender)
|
||||||
|
|
||||||
|
|
||||||
def _postToSpeakerJson(baseDir: str, nickname: str, domain: str,
|
def _postToSpeakerJson(baseDir: str, httpPrefix: str,
|
||||||
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {}, personCache: {},
|
postJsonObject: {}, personCache: {},
|
||||||
translate: {}, announcingActor: str) -> {}:
|
translate: {}, announcingActor: str) -> {}:
|
||||||
"""Converts an ActivityPub post into some Json containing
|
"""Converts an ActivityPub post into some Json containing
|
||||||
|
@ -429,19 +437,26 @@ def _postToSpeakerJson(baseDir: str, nickname: str, domain: str,
|
||||||
postId = None
|
postId = None
|
||||||
if postJsonObject['object'].get('id'):
|
if postJsonObject['object'].get('id'):
|
||||||
postId = postJsonObject['object']['id']
|
postId = postJsonObject['object']['id']
|
||||||
|
|
||||||
|
actor = httpPrefix + '://' + domainFull + '/users/' + nickname
|
||||||
|
postDM = isDM(postJsonObject)
|
||||||
|
postReply = isReply(postJsonObject, actor)
|
||||||
return _speakerEndpointJson(speakerName, summary,
|
return _speakerEndpointJson(speakerName, summary,
|
||||||
content, imageDescription,
|
content, imageDescription,
|
||||||
detectedLinks, gender, postId)
|
detectedLinks, gender, postId,
|
||||||
|
postDM, postReply)
|
||||||
|
|
||||||
|
|
||||||
def updateSpeaker(baseDir: str, nickname: str, domain: str,
|
def updateSpeaker(baseDir: str, httpPrefix: str,
|
||||||
|
nickname: str, domain: str, domainFull: str,
|
||||||
postJsonObject: {}, personCache: {},
|
postJsonObject: {}, personCache: {},
|
||||||
translate: {}, announcingActor: str) -> None:
|
translate: {}, announcingActor: str) -> None:
|
||||||
""" Generates a json file which can be used for TTS announcement
|
""" Generates a json file which can be used for TTS announcement
|
||||||
of incoming inbox posts
|
of incoming inbox posts
|
||||||
"""
|
"""
|
||||||
speakerJson = \
|
speakerJson = \
|
||||||
_postToSpeakerJson(baseDir, nickname, domain,
|
_postToSpeakerJson(baseDir, httpPrefix,
|
||||||
|
nickname, domain, domainFull,
|
||||||
postJsonObject, personCache,
|
postJsonObject, personCache,
|
||||||
translate, announcingActor)
|
translate, announcingActor)
|
||||||
speakerFilename = \
|
speakerFilename = \
|
||||||
|
|
62
utils.py
62
utils.py
|
@ -2068,3 +2068,65 @@ def rejectPostId(baseDir: str, nickname: str, domain: str,
|
||||||
if rejectFile:
|
if rejectFile:
|
||||||
rejectFile.write('\n')
|
rejectFile.write('\n')
|
||||||
rejectFile.close()
|
rejectFile.close()
|
||||||
|
|
||||||
|
|
||||||
|
def isDM(postJsonObject: {}) -> bool:
|
||||||
|
"""Returns true if the given post is a DM
|
||||||
|
"""
|
||||||
|
if postJsonObject['type'] != 'Create':
|
||||||
|
return False
|
||||||
|
if not postJsonObject.get('object'):
|
||||||
|
return False
|
||||||
|
if not isinstance(postJsonObject['object'], dict):
|
||||||
|
return False
|
||||||
|
if postJsonObject['object']['type'] != 'Note' and \
|
||||||
|
postJsonObject['object']['type'] != 'Patch' and \
|
||||||
|
postJsonObject['object']['type'] != 'EncryptedMessage' and \
|
||||||
|
postJsonObject['object']['type'] != 'Article':
|
||||||
|
return False
|
||||||
|
if postJsonObject['object'].get('moderationStatus'):
|
||||||
|
return False
|
||||||
|
fields = ('to', 'cc')
|
||||||
|
for f in fields:
|
||||||
|
if not postJsonObject['object'].get(f):
|
||||||
|
continue
|
||||||
|
for toAddress in postJsonObject['object'][f]:
|
||||||
|
if toAddress.endswith('#Public'):
|
||||||
|
return False
|
||||||
|
if toAddress.endswith('followers'):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def isReply(postJsonObject: {}, actor: str) -> bool:
|
||||||
|
"""Returns true if the given post is a reply to the given actor
|
||||||
|
"""
|
||||||
|
if postJsonObject['type'] != 'Create':
|
||||||
|
return False
|
||||||
|
if not postJsonObject.get('object'):
|
||||||
|
return False
|
||||||
|
if not isinstance(postJsonObject['object'], dict):
|
||||||
|
return False
|
||||||
|
if postJsonObject['object'].get('moderationStatus'):
|
||||||
|
return False
|
||||||
|
if postJsonObject['object']['type'] != 'Note' and \
|
||||||
|
postJsonObject['object']['type'] != 'EncryptedMessage' and \
|
||||||
|
postJsonObject['object']['type'] != 'Article':
|
||||||
|
return False
|
||||||
|
if postJsonObject['object'].get('inReplyTo'):
|
||||||
|
if isinstance(postJsonObject['object']['inReplyTo'], str):
|
||||||
|
if postJsonObject['object']['inReplyTo'].startswith(actor):
|
||||||
|
return True
|
||||||
|
if not postJsonObject['object'].get('tag'):
|
||||||
|
return False
|
||||||
|
if not isinstance(postJsonObject['object']['tag'], list):
|
||||||
|
return False
|
||||||
|
for tag in postJsonObject['object']['tag']:
|
||||||
|
if not tag.get('type'):
|
||||||
|
continue
|
||||||
|
if tag['type'] == 'Mention':
|
||||||
|
if not tag.get('href'):
|
||||||
|
continue
|
||||||
|
if actor in tag['href']:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
|
@ -19,9 +19,9 @@ from like import noOfLikes
|
||||||
from follow import isFollowingActor
|
from follow import isFollowingActor
|
||||||
from posts import postIsMuted
|
from posts import postIsMuted
|
||||||
from posts import getPersonBox
|
from posts import getPersonBox
|
||||||
from posts import isDM
|
|
||||||
from posts import downloadAnnounce
|
from posts import downloadAnnounce
|
||||||
from posts import populateRepliesJson
|
from posts import populateRepliesJson
|
||||||
|
from utils import isDM
|
||||||
from utils import rejectPostId
|
from utils import rejectPostId
|
||||||
from utils import isRecentPost
|
from utils import isRecentPost
|
||||||
from utils import getConfigParam
|
from utils import getConfigParam
|
||||||
|
@ -1304,7 +1304,8 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
postJsonObject['id'])
|
postJsonObject['id'])
|
||||||
if announceFilename and postJsonObject.get('actor'):
|
if announceFilename and postJsonObject.get('actor'):
|
||||||
if not os.path.isfile(announceFilename + '.tts'):
|
if not os.path.isfile(announceFilename + '.tts'):
|
||||||
updateSpeaker(baseDir, nickname, domain,
|
updateSpeaker(baseDir, httpPrefix,
|
||||||
|
nickname, domain, domainFull,
|
||||||
postJsonObject, personCache,
|
postJsonObject, personCache,
|
||||||
translate, postJsonObject['actor'])
|
translate, postJsonObject['actor'])
|
||||||
ttsFile = open(announceFilename + '.tts', "w+")
|
ttsFile = open(announceFilename + '.tts', "w+")
|
||||||
|
|
Loading…
Reference in New Issue