mirror of https://gitlab.com/bashrc2/epicyon
Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main
commit
bb3ea15e34
37
daemon.py
37
daemon.py
|
|
@ -2719,7 +2719,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.YTReplacementDomain,
|
self.server.YTReplacementDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
if hashtagStr:
|
if hashtagStr:
|
||||||
msg = hashtagStr.encode('utf-8')
|
msg = hashtagStr.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -2772,7 +2773,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.YTReplacementDomain,
|
self.server.YTReplacementDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
if historyStr:
|
if historyStr:
|
||||||
msg = historyStr.encode('utf-8')
|
msg = historyStr.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -2862,7 +2864,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
self.server.defaultTimeline,
|
self.server.defaultTimeline,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
if profileStr:
|
if profileStr:
|
||||||
msg = profileStr.encode('utf-8')
|
msg = profileStr.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -4853,8 +4856,7 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
# only receive DMs from accounts you follow
|
# only receive DMs from accounts you follow
|
||||||
followDMsFilename = \
|
followDMsFilename = \
|
||||||
baseDir + '/accounts/' + \
|
baseDir + '/accounts/' + \
|
||||||
nickname + '@' + domain + \
|
nickname + '@' + domain + '/.followDMs'
|
||||||
'/.followDMs'
|
|
||||||
if onFinalWelcomeScreen:
|
if onFinalWelcomeScreen:
|
||||||
# initial default setting created via
|
# initial default setting created via
|
||||||
# the welcome screen
|
# the welcome screen
|
||||||
|
|
@ -5988,7 +5990,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.YTReplacementDomain,
|
self.server.YTReplacementDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
if hashtagStr:
|
if hashtagStr:
|
||||||
msg = hashtagStr.encode('utf-8')
|
msg = hashtagStr.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
|
|
@ -6951,7 +6954,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.YTReplacementDomain,
|
self.server.YTReplacementDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
self.server.peertubeInstances,
|
self.server.peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
if deleteStr:
|
if deleteStr:
|
||||||
deleteStrLen = len(deleteStr)
|
deleteStrLen = len(deleteStr)
|
||||||
self._set_headers('text/html', deleteStrLen,
|
self._set_headers('text/html', deleteStrLen,
|
||||||
|
|
@ -7156,7 +7160,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
ytDomain,
|
ytDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
msg = msg.encode('utf-8')
|
msg = msg.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
self._set_headers('text/html', msglen,
|
self._set_headers('text/html', msglen,
|
||||||
|
|
@ -7243,7 +7248,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
ytDomain,
|
ytDomain,
|
||||||
self.server.showPublishedDateOnly,
|
self.server.showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
self.server.allowLocalNetworkAccess)
|
self.server.allowLocalNetworkAccess,
|
||||||
|
self.server.themeName)
|
||||||
msg = msg.encode('utf-8')
|
msg = msg.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
self._set_headers('text/html', msglen,
|
self._set_headers('text/html', msglen,
|
||||||
|
|
@ -7533,6 +7539,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
cssCache = self.server.cssCache
|
cssCache = self.server.cssCache
|
||||||
allowLocalNetworkAccess = \
|
allowLocalNetworkAccess = \
|
||||||
self.server.allowLocalNetworkAccess
|
self.server.allowLocalNetworkAccess
|
||||||
|
themeName = \
|
||||||
|
self.server.themeName
|
||||||
msg = \
|
msg = \
|
||||||
htmlIndividualPost(cssCache,
|
htmlIndividualPost(cssCache,
|
||||||
recentPostsCache,
|
recentPostsCache,
|
||||||
|
|
@ -7553,7 +7561,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
ytDomain,
|
ytDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess,
|
||||||
|
themeName)
|
||||||
msg = msg.encode('utf-8')
|
msg = msg.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
self._set_headers('text/html', msglen,
|
self._set_headers('text/html', msglen,
|
||||||
|
|
@ -7657,6 +7666,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
self.server.peertubeInstances
|
self.server.peertubeInstances
|
||||||
allowLocalNetworkAccess = \
|
allowLocalNetworkAccess = \
|
||||||
self.server.allowLocalNetworkAccess
|
self.server.allowLocalNetworkAccess
|
||||||
|
themeName = \
|
||||||
|
self.server.themeName
|
||||||
msg = \
|
msg = \
|
||||||
htmlIndividualPost(self.server.cssCache,
|
htmlIndividualPost(self.server.cssCache,
|
||||||
recentPostsCache,
|
recentPostsCache,
|
||||||
|
|
@ -7677,7 +7688,8 @@ class PubServer(BaseHTTPRequestHandler):
|
||||||
ytDomain,
|
ytDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess,
|
||||||
|
themeName)
|
||||||
msg = msg.encode('utf-8')
|
msg = msg.encode('utf-8')
|
||||||
msglen = len(msg)
|
msglen = len(msg)
|
||||||
self._set_headers('text/html', msglen,
|
self._set_headers('text/html', msglen,
|
||||||
|
|
@ -14668,7 +14680,8 @@ def runDaemon(brochMode: bool,
|
||||||
httpd.maxFollowers,
|
httpd.maxFollowers,
|
||||||
httpd.allowLocalNetworkAccess,
|
httpd.allowLocalNetworkAccess,
|
||||||
httpd.peertubeInstances,
|
httpd.peertubeInstances,
|
||||||
verifyAllSignatures), daemon=True)
|
verifyAllSignatures,
|
||||||
|
httpd.themeName), daemon=True)
|
||||||
|
|
||||||
print('Creating scheduled post thread')
|
print('Creating scheduled post thread')
|
||||||
httpd.thrPostSchedule = \
|
httpd.thrPostSchedule = \
|
||||||
|
|
|
||||||
39
inbox.py
39
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
|
||||||
|
|
@ -158,7 +158,8 @@ def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
allowDeletion: bool, boxname: str,
|
allowDeletion: bool, boxname: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> None:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> None:
|
||||||
"""Converts the json post into html and stores it in a cache
|
"""Converts the json post into html and stores it in a cache
|
||||||
This enables the post to be quickly displayed later
|
This enables the post to be quickly displayed later
|
||||||
"""
|
"""
|
||||||
|
|
@ -176,6 +177,7 @@ def _inboxStorePostToHtmlCache(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
httpPrefix, __version__, boxname, None,
|
httpPrefix, __version__, boxname, None,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances, allowLocalNetworkAccess,
|
peertubeInstances, allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
not isDM(postJsonObject),
|
not isDM(postJsonObject),
|
||||||
True, True, False, True)
|
True, True, False, True)
|
||||||
|
|
||||||
|
|
@ -1290,7 +1292,8 @@ def _receiveAnnounce(recentPostsCache: {},
|
||||||
personCache: {}, messageJson: {}, federationList: [],
|
personCache: {}, messageJson: {}, federationList: [],
|
||||||
debug: bool, translate: {},
|
debug: bool, translate: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
allowLocalNetworkAccess: bool) -> bool:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> bool:
|
||||||
"""Receives an announce activity within the POST section of HTTPServer
|
"""Receives an announce activity within the POST section of HTTPServer
|
||||||
"""
|
"""
|
||||||
if messageJson['type'] != 'Announce':
|
if messageJson['type'] != 'Announce':
|
||||||
|
|
@ -1408,9 +1411,12 @@ 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,
|
||||||
|
themeName)
|
||||||
ttsFile = open(postFilename + '.tts', "w+")
|
ttsFile = open(postFilename + '.tts', "w+")
|
||||||
if ttsFile:
|
if ttsFile:
|
||||||
ttsFile.write('\n')
|
ttsFile.write('\n')
|
||||||
|
|
@ -2164,7 +2170,8 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
allowLocalNetworkAccess: bool,
|
allowLocalNetworkAccess: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
lastBounceMessage: []) -> bool:
|
lastBounceMessage: [],
|
||||||
|
themeName: str) -> bool:
|
||||||
""" Anything which needs to be done after initial checks have passed
|
""" Anything which needs to be done after initial checks have passed
|
||||||
"""
|
"""
|
||||||
actor = keyId
|
actor = keyId
|
||||||
|
|
@ -2243,7 +2250,8 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
federationList,
|
federationList,
|
||||||
debug, translate,
|
debug, translate,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
allowLocalNetworkAccess):
|
allowLocalNetworkAccess,
|
||||||
|
themeName):
|
||||||
if debug:
|
if debug:
|
||||||
print('DEBUG: Announce accepted from ' + actor)
|
print('DEBUG: Announce accepted from ' + actor)
|
||||||
|
|
||||||
|
|
@ -2491,9 +2499,11 @@ 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, themeName)
|
||||||
if not unitTest:
|
if not unitTest:
|
||||||
if debug:
|
if debug:
|
||||||
print('Saving inbox post as html to cache')
|
print('Saving inbox post as html to cache')
|
||||||
|
|
@ -2513,7 +2523,8 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
boxname,
|
boxname,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess)
|
allowLocalNetworkAccess,
|
||||||
|
themeName)
|
||||||
if debug:
|
if debug:
|
||||||
timeDiff = \
|
timeDiff = \
|
||||||
str(int((time.time() - htmlCacheStartTime) *
|
str(int((time.time() - htmlCacheStartTime) *
|
||||||
|
|
@ -2614,7 +2625,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
maxFollowers: int, allowLocalNetworkAccess: bool,
|
maxFollowers: int, allowLocalNetworkAccess: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
verifyAllSignatures: bool) -> None:
|
verifyAllSignatures: bool,
|
||||||
|
themeName: str) -> None:
|
||||||
"""Processes received items and moves them to the appropriate
|
"""Processes received items and moves them to the appropriate
|
||||||
directories
|
directories
|
||||||
"""
|
"""
|
||||||
|
|
@ -3107,7 +3119,8 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
lastBounceMessage)
|
lastBounceMessage,
|
||||||
|
themeName)
|
||||||
if debug:
|
if debug:
|
||||||
pprint(queueJson['post'])
|
pprint(queueJson['post'])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,17 @@ def _speakerPicospeaker(pitch: int, rate: int, systemLanguage: str,
|
||||||
os.system(speakerCmd)
|
os.system(speakerCmd)
|
||||||
|
|
||||||
|
|
||||||
|
def _playNotificationSound(soundFilename: str, player='ffplay') -> None:
|
||||||
|
"""Plays a sound
|
||||||
|
"""
|
||||||
|
if not os.path.isfile(soundFilename):
|
||||||
|
return
|
||||||
|
|
||||||
|
if player == 'ffplay':
|
||||||
|
os.system('ffplay ' + soundFilename +
|
||||||
|
' -autoexit -hide_banner -nodisp')
|
||||||
|
|
||||||
|
|
||||||
def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str,
|
def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str,
|
||||||
nickname: str, domain: str, port: int,
|
nickname: str, domain: str, port: int,
|
||||||
password: str, screenreader: str,
|
password: str, screenreader: str,
|
||||||
|
|
@ -73,64 +84,121 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str,
|
||||||
"""Runs the notifications and screen reader client,
|
"""Runs the notifications and screen reader client,
|
||||||
which announces new inbox items
|
which announces new inbox items
|
||||||
"""
|
"""
|
||||||
if screenreader == 'espeak':
|
if screenreader:
|
||||||
print('Setting up espeak')
|
if screenreader == 'espeak':
|
||||||
from espeak import espeak
|
print('Setting up espeak')
|
||||||
elif screenreader != 'picospeaker':
|
from espeak import espeak
|
||||||
print(screenreader + ' is not a supported TTS system')
|
elif screenreader != 'picospeaker':
|
||||||
return
|
print(screenreader + ' is not a supported TTS system')
|
||||||
|
return
|
||||||
|
|
||||||
print('Running ' + screenreader + ' for ' + nickname + '@' + domain)
|
print('Running ' + screenreader + ' for ' + nickname + '@' + domain)
|
||||||
|
|
||||||
prevSay = ''
|
prevSay = ''
|
||||||
|
prevDM = False
|
||||||
|
prevReply = False
|
||||||
|
prevCalendar = False
|
||||||
|
prevFollow = False
|
||||||
|
prevLike = ''
|
||||||
|
prevShare = False
|
||||||
|
dmSoundFilename = 'dm.ogg'
|
||||||
|
replySoundFilename = 'reply.ogg'
|
||||||
|
calendarSoundFilename = 'calendar.ogg'
|
||||||
|
followSoundFilename = 'follow.ogg'
|
||||||
|
likeSoundFilename = 'like.ogg'
|
||||||
|
shareSoundFilename = 'share.ogg'
|
||||||
|
player = 'ffplay'
|
||||||
while (1):
|
while (1):
|
||||||
session = createSession(proxyType)
|
session = createSession(proxyType)
|
||||||
speakerJson = \
|
speakerJson = \
|
||||||
getSpeakerFromServer(baseDir, session, nickname, password,
|
getSpeakerFromServer(baseDir, session, nickname, password,
|
||||||
domain, port, httpPrefix, True, __version__)
|
domain, port, httpPrefix, True, __version__)
|
||||||
if speakerJson:
|
if speakerJson:
|
||||||
if speakerJson['say'] != prevSay:
|
if speakerJson.get('notify'):
|
||||||
if speakerJson.get('name'):
|
soundsDir = 'theme/default/sounds'
|
||||||
nameStr = speakerJson['name']
|
if speakerJson['notify'].get('theme'):
|
||||||
gender = 'They/Them'
|
soundsDir = \
|
||||||
if speakerJson.get('gender'):
|
'theme/' + speakerJson['notify']['theme'] + '/sounds'
|
||||||
gender = speakerJson['gender']
|
if not os.path.isdir(soundsDir):
|
||||||
|
soundsDir = 'theme/default/sounds'
|
||||||
|
if dmSoundFilename:
|
||||||
|
if speakerJson['notify']['dm'] != prevDM:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
dmSoundFilename, player)
|
||||||
|
elif replySoundFilename:
|
||||||
|
if speakerJson['notify']['reply'] != prevReply:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
replySoundFilename, player)
|
||||||
|
elif calendarSoundFilename:
|
||||||
|
if speakerJson['notify']['calendar'] != prevCalendar:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
calendarSoundFilename, player)
|
||||||
|
elif followSoundFilename:
|
||||||
|
if speakerJson['notify']['followRequests'] != prevFollow:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
followSoundFilename, player)
|
||||||
|
elif likeSoundFilename:
|
||||||
|
if speakerJson['notify']['like'] != prevLike:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
likeSoundFilename, player)
|
||||||
|
elif shareSoundFilename:
|
||||||
|
if speakerJson['notify']['share'] != prevShare:
|
||||||
|
_playNotificationSound(soundsDir + '/' +
|
||||||
|
shareSoundFilename, player)
|
||||||
|
|
||||||
# get the speech parameters
|
prevDM = speakerJson['notify']['dm']
|
||||||
pitch = getSpeakerPitch(nameStr, screenreader, gender)
|
prevReply = speakerJson['notify']['reply']
|
||||||
rate = getSpeakerRate(nameStr, screenreader)
|
prevCalendar = speakerJson['notify']['calendar']
|
||||||
srange = getSpeakerRange(nameStr)
|
prevFollow = speakerJson['notify']['followRequests']
|
||||||
|
prevLike = speakerJson['notify']['like']
|
||||||
|
prevShare = speakerJson['notify']['share']
|
||||||
|
|
||||||
# say the speaker's name
|
if speakerJson.get('say'):
|
||||||
if screenreader == 'espeak':
|
if speakerJson['say'] != prevSay:
|
||||||
_speakerEspeak(espeak, pitch, rate, srange, nameStr)
|
if speakerJson.get('name'):
|
||||||
elif screenreader == 'picospeaker':
|
nameStr = speakerJson['name']
|
||||||
_speakerPicospeaker(pitch, rate,
|
gender = 'They/Them'
|
||||||
systemLanguage, nameStr)
|
if speakerJson.get('gender'):
|
||||||
time.sleep(2)
|
gender = speakerJson['gender']
|
||||||
|
|
||||||
# append image description if needed
|
# get the speech parameters
|
||||||
if not speakerJson.get('imageDescription'):
|
pitch = getSpeakerPitch(nameStr, screenreader, gender)
|
||||||
sayStr = speakerJson['say']
|
rate = getSpeakerRate(nameStr, screenreader)
|
||||||
# echo spoken text to the screen
|
srange = getSpeakerRange(nameStr)
|
||||||
print(html.unescape(nameStr) + ': ' +
|
|
||||||
html.unescape(speakerJson['say']) + '\n')
|
|
||||||
else:
|
|
||||||
sayStr = speakerJson['say'] + '. ' + \
|
|
||||||
speakerJson['imageDescription']
|
|
||||||
# echo spoken text to the screen
|
|
||||||
print(html.unescape(nameStr) + ': ' +
|
|
||||||
html.unescape(speakerJson['say']) + '\n' +
|
|
||||||
html.unescape(speakerJson['imageDescription']))
|
|
||||||
|
|
||||||
# speak the post content
|
# say the speaker's name
|
||||||
if screenreader == 'espeak':
|
if screenreader == 'espeak':
|
||||||
_speakerEspeak(espeak, pitch, rate, srange, sayStr)
|
_speakerEspeak(espeak, pitch, rate, srange,
|
||||||
elif screenreader == 'picospeaker':
|
nameStr)
|
||||||
_speakerPicospeaker(pitch, rate,
|
elif screenreader == 'picospeaker':
|
||||||
systemLanguage, sayStr)
|
_speakerPicospeaker(pitch, rate,
|
||||||
|
systemLanguage, nameStr)
|
||||||
|
time.sleep(2)
|
||||||
|
|
||||||
prevSay = speakerJson['say']
|
# append image description if needed
|
||||||
|
if not speakerJson.get('imageDescription'):
|
||||||
|
sayStr = speakerJson['say']
|
||||||
|
# echo spoken text to the screen
|
||||||
|
print(html.unescape(nameStr) + ': ' +
|
||||||
|
html.unescape(speakerJson['say']) + '\n')
|
||||||
|
else:
|
||||||
|
sayStr = speakerJson['say'] + '. ' + \
|
||||||
|
speakerJson['imageDescription']
|
||||||
|
# echo spoken text to the screen
|
||||||
|
imageDescription = \
|
||||||
|
html.unescape(speakerJson['imageDescription'])
|
||||||
|
print(html.unescape(nameStr) + ': ' +
|
||||||
|
html.unescape(speakerJson['say']) + '\n' +
|
||||||
|
imageDescription)
|
||||||
|
|
||||||
|
# speak the post content
|
||||||
|
if screenreader == 'espeak':
|
||||||
|
_speakerEspeak(espeak, pitch, rate, srange, sayStr)
|
||||||
|
elif screenreader == 'picospeaker':
|
||||||
|
_speakerPicospeaker(pitch, rate,
|
||||||
|
systemLanguage, sayStr)
|
||||||
|
|
||||||
|
prevSay = speakerJson['say']
|
||||||
|
|
||||||
# wait for a while, or until a key is pressed
|
# wait for a while, or until a key is pressed
|
||||||
keyPress = _waitForKeypress(30, debug)
|
keyPress = _waitForKeypress(30, debug)
|
||||||
|
|
|
||||||
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?
|
||||||
|
|
|
||||||
|
|
@ -209,9 +209,9 @@ function notifications {
|
||||||
if [[ "$epicyonLikeFileContent" == *':'* ]]; then
|
if [[ "$epicyonLikeFileContent" == *':'* ]]; then
|
||||||
epicyonLikeMessage="Epicyon: $epicyonLikeFileContent"
|
epicyonLikeMessage="Epicyon: $epicyonLikeFileContent"
|
||||||
fi
|
fi
|
||||||
"${PROJECT_NAME}-notification" -u "$USERNAME" -s "Epicyon" -m "$epicyonLikeMessage" --sensitive yes
|
sendNotification "$USERNAME" "Epicyon" "$epicyonLikeMessage"
|
||||||
echo "##sent##" > "$epicyonLikeFile"
|
echo "##sent##" > "$epicyonLikeFile"
|
||||||
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonLkeFile"
|
chown ${PROJECT_NAME}:${PROJECT_NAME} "$epicyonLikeFile"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
||||||
68
speaker.py
68
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,11 @@ 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,
|
||||||
|
followRequestsExist: bool,
|
||||||
|
likedBy: str, postCal: bool,
|
||||||
|
postShare: bool, themeName: str) -> {}:
|
||||||
"""Returns a json endpoint for the TTS speaker
|
"""Returns a json endpoint for the TTS speaker
|
||||||
"""
|
"""
|
||||||
speakerJson = {
|
speakerJson = {
|
||||||
|
|
@ -272,7 +278,16 @@ def _speakerEndpointJson(displayName: str, summary: str,
|
||||||
"say": content,
|
"say": content,
|
||||||
"imageDescription": imageDescription,
|
"imageDescription": imageDescription,
|
||||||
"detectedLinks": links,
|
"detectedLinks": links,
|
||||||
"id": postId
|
"id": postId,
|
||||||
|
"notify": {
|
||||||
|
"theme": themeName,
|
||||||
|
"dm": postDM,
|
||||||
|
"reply": postReply,
|
||||||
|
"followRequests": followRequestsExist,
|
||||||
|
"likedBy": likedBy,
|
||||||
|
"calendar": postCal,
|
||||||
|
"share": postShare
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if gender:
|
if gender:
|
||||||
speakerJson['gender'] = gender
|
speakerJson['gender'] = gender
|
||||||
|
|
@ -360,9 +375,11 @@ 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,
|
||||||
|
themeName: str) -> {}:
|
||||||
"""Converts an ActivityPub post into some Json containing
|
"""Converts an ActivityPub post into some Json containing
|
||||||
speech synthesis parameters.
|
speech synthesis parameters.
|
||||||
NOTE: There currently appears to be no standardized json
|
NOTE: There currently appears to be no standardized json
|
||||||
|
|
@ -429,21 +446,54 @@ 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)
|
||||||
|
|
||||||
|
followRequestsExist = False
|
||||||
|
accountsDir = baseDir + '/accounts/' + nickname + '@' + domainFull
|
||||||
|
approveFollowsFilename = accountsDir + '/followrequests.txt'
|
||||||
|
if os.path.isfile(approveFollowsFilename):
|
||||||
|
with open(approveFollowsFilename, 'r') as fp:
|
||||||
|
follows = fp.readlines()
|
||||||
|
if len(follows) > 0:
|
||||||
|
followRequestsExist = True
|
||||||
|
likedBy = ''
|
||||||
|
likeFilename = accountsDir + '/.newLike'
|
||||||
|
if os.path.isfile(likeFilename):
|
||||||
|
with open(likeFilename, 'r') as fp:
|
||||||
|
likedBy = fp.read()
|
||||||
|
if '##sent##' in likedBy:
|
||||||
|
likedBy = ''
|
||||||
|
calendarFilename = accountsDir + '/.newCalendar'
|
||||||
|
postCal = os.path.isfile(calendarFilename)
|
||||||
|
shareFilename = accountsDir + '/.newShare'
|
||||||
|
postShare = os.path.isfile(shareFilename)
|
||||||
|
|
||||||
return _speakerEndpointJson(speakerName, summary,
|
return _speakerEndpointJson(speakerName, summary,
|
||||||
content, imageDescription,
|
content, imageDescription,
|
||||||
detectedLinks, gender, postId)
|
detectedLinks, gender, postId,
|
||||||
|
postDM, postReply,
|
||||||
|
followRequestsExist,
|
||||||
|
likedBy,
|
||||||
|
postCal, postShare, themeName)
|
||||||
|
|
||||||
|
|
||||||
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,
|
||||||
|
themeName: 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,
|
||||||
|
themeName)
|
||||||
speakerFilename = \
|
speakerFilename = \
|
||||||
baseDir + '/accounts/' + nickname + '@' + domain + '/speaker.json'
|
baseDir + '/accounts/' + nickname + '@' + domain + '/speaker.json'
|
||||||
saveJson(speakerJson, speakerFilename)
|
saveJson(speakerJson, speakerFilename)
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,8 @@ def htmlConfirmDelete(cssCache: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Shows a screen asking to confirm the deletion of a post
|
"""Shows a screen asking to confirm the deletion of a post
|
||||||
"""
|
"""
|
||||||
if '/statuses/' not in messageId:
|
if '/statuses/' not in messageId:
|
||||||
|
|
@ -72,6 +73,7 @@ def htmlConfirmDelete(cssCache: {},
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances, allowLocalNetworkAccess,
|
peertubeInstances, allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
deletePostStr += '<center>'
|
deletePostStr += '<center>'
|
||||||
deletePostStr += \
|
deletePostStr += \
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@ def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Shows posts on the front screen of a news instance
|
"""Shows posts on the front screen of a news instance
|
||||||
These should only be public blog posts from the features timeline
|
These should only be public blog posts from the features timeline
|
||||||
which is the blog timeline of the news actor
|
which is the blog timeline of the news actor
|
||||||
|
|
@ -71,6 +72,7 @@ def _htmlFrontScreenPosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, False, False, True, False)
|
False, False, False, True, False)
|
||||||
if postStr:
|
if postStr:
|
||||||
profileStr += postStr + separatorStr
|
profileStr += postStr + separatorStr
|
||||||
|
|
@ -159,7 +161,8 @@ def htmlFrontScreen(rssIconAtTop: bool,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess) + licenseStr
|
allowLocalNetworkAccess,
|
||||||
|
theme) + licenseStr
|
||||||
|
|
||||||
# Footer which is only used for system accounts
|
# Footer which is only used for system accounts
|
||||||
profileFooterStr = ' </td>\n'
|
profileFooterStr = ' </td>\n'
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1139,6 +1139,7 @@ def individualPostAsHtml(allowDownloads: bool,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool,
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str,
|
||||||
showRepeats=True,
|
showRepeats=True,
|
||||||
showIcons=False,
|
showIcons=False,
|
||||||
manuallyApprovesFollowers=False,
|
manuallyApprovesFollowers=False,
|
||||||
|
|
@ -1304,9 +1305,11 @@ 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'],
|
||||||
|
themeName)
|
||||||
ttsFile = open(announceFilename + '.tts', "w+")
|
ttsFile = open(announceFilename + '.tts', "w+")
|
||||||
if ttsFile:
|
if ttsFile:
|
||||||
ttsFile.write('\n')
|
ttsFile.write('\n')
|
||||||
|
|
@ -1683,7 +1686,8 @@ def htmlIndividualPost(cssCache: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Show an individual post as html
|
"""Show an individual post as html
|
||||||
"""
|
"""
|
||||||
postStr = ''
|
postStr = ''
|
||||||
|
|
@ -1724,7 +1728,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess, themeName,
|
||||||
False, authorized, False, False, False)
|
False, authorized, False, False, False)
|
||||||
messageId = removeIdEnding(postJsonObject['id'])
|
messageId = removeIdEnding(postJsonObject['id'])
|
||||||
|
|
||||||
|
|
@ -1752,6 +1756,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, authorized,
|
False, authorized,
|
||||||
False, False, False) + postStr
|
False, False, False) + postStr
|
||||||
|
|
||||||
|
|
@ -1782,6 +1787,7 @@ def htmlIndividualPost(cssCache: {},
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, authorized,
|
False, authorized,
|
||||||
False, False, False)
|
False, False, False)
|
||||||
cssFilename = baseDir + '/epicyon-profile.css'
|
cssFilename = baseDir + '/epicyon-profile.css'
|
||||||
|
|
@ -1803,7 +1809,8 @@ def htmlPostReplies(cssCache: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Show the replies to an individual post as html
|
"""Show the replies to an individual post as html
|
||||||
"""
|
"""
|
||||||
repliesStr = ''
|
repliesStr = ''
|
||||||
|
|
@ -1822,6 +1829,7 @@ def htmlPostReplies(cssCache: {},
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
|
|
||||||
cssFilename = baseDir + '/epicyon-profile.css'
|
cssFilename = baseDir + '/epicyon-profile.css'
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,8 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
defaultTimeline: str,
|
defaultTimeline: str,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Show a profile page after a search for a fediverse address
|
"""Show a profile page after a search for a fediverse address
|
||||||
"""
|
"""
|
||||||
if hasUsersPath(profileHandle) or '/@' in profileHandle:
|
if hasUsersPath(profileHandle) or '/@' in profileHandle:
|
||||||
|
|
@ -300,6 +301,7 @@ def htmlProfileAfterSearch(cssCache: {},
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances, allowLocalNetworkAccess,
|
peertubeInstances, allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, False, False, False, False)
|
False, False, False, False, False)
|
||||||
i += 1
|
i += 1
|
||||||
if i >= 20:
|
if i >= 20:
|
||||||
|
|
@ -804,7 +806,8 @@ def htmlProfile(rssIconAtTop: bool,
|
||||||
YTReplacementDomain,
|
YTReplacementDomain,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess) + licenseStr
|
allowLocalNetworkAccess,
|
||||||
|
theme) + licenseStr
|
||||||
elif selected == 'following':
|
elif selected == 'following':
|
||||||
profileStr += \
|
profileStr += \
|
||||||
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
_htmlProfileFollowing(translate, baseDir, httpPrefix,
|
||||||
|
|
@ -856,7 +859,8 @@ def _htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Shows posts on the profile screen
|
"""Shows posts on the profile screen
|
||||||
These should only be public posts
|
These should only be public posts
|
||||||
"""
|
"""
|
||||||
|
|
@ -896,6 +900,7 @@ def _htmlProfilePosts(recentPostsCache: {}, maxRecentPosts: int,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
False, False, False, True, False)
|
False, False, False, True, False)
|
||||||
if postStr:
|
if postStr:
|
||||||
profileStr += postStr + separatorStr
|
profileStr += postStr + separatorStr
|
||||||
|
|
|
||||||
|
|
@ -527,7 +527,8 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Show a page containing search results for your post history
|
"""Show a page containing search results for your post history
|
||||||
"""
|
"""
|
||||||
if historysearch.startswith('!'):
|
if historysearch.startswith('!'):
|
||||||
|
|
@ -604,6 +605,7 @@ def htmlHistorySearch(cssCache: {}, translate: {}, baseDir: str,
|
||||||
showPublishedDateOnly,
|
showPublishedDateOnly,
|
||||||
peertubeInstances,
|
peertubeInstances,
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
|
themeName,
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
False, False, False)
|
False, False, False)
|
||||||
|
|
@ -626,7 +628,8 @@ def htmlHashtagSearch(cssCache: {},
|
||||||
YTReplacementDomain: str,
|
YTReplacementDomain: str,
|
||||||
showPublishedDateOnly: bool,
|
showPublishedDateOnly: bool,
|
||||||
peertubeInstances: [],
|
peertubeInstances: [],
|
||||||
allowLocalNetworkAccess: bool) -> str:
|
allowLocalNetworkAccess: bool,
|
||||||
|
themeName: str) -> str:
|
||||||
"""Show a page containing search results for a hashtag
|
"""Show a page containing search results for a hashtag
|
||||||
"""
|
"""
|
||||||
if hashtag.startswith('#'):
|
if hashtag.startswith('#'):
|
||||||
|
|
@ -778,6 +781,7 @@ def htmlHashtagSearch(cssCache: {},
|
||||||
allowLocalNetworkAccess,
|
allowLocalNetworkAccess,
|
||||||
showRepeats, showIcons,
|
showRepeats, showIcons,
|
||||||
manuallyApprovesFollowers,
|
manuallyApprovesFollowers,
|
||||||
|
themeName,
|
||||||
showPublicOnly,
|
showPublicOnly,
|
||||||
storeToCache)
|
storeToCache)
|
||||||
if postStr:
|
if postStr:
|
||||||
|
|
|
||||||
|
|
@ -723,6 +723,7 @@ def htmlTimeline(cssCache: {}, defaultTimeline: str,
|
||||||
boxName != 'dm',
|
boxName != 'dm',
|
||||||
showIndividualPostIcons,
|
showIndividualPostIcons,
|
||||||
manuallyApproveFollowers,
|
manuallyApproveFollowers,
|
||||||
|
theme,
|
||||||
False, True)
|
False, True)
|
||||||
_logTimelineTiming(enableTimingLog,
|
_logTimelineTiming(enableTimingLog,
|
||||||
timelineStartTime, boxName, '12')
|
timelineStartTime, boxName, '12')
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue