Merge branch 'main' of ssh://code.freedombone.net:2222/bashrc/epicyon into main

main
Bob Mottram 2021-03-14 21:08:43 +00:00
commit 48265fd9c0
28 changed files with 250 additions and 153 deletions

View File

@ -219,7 +219,7 @@ def sendAnnounceViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -105,7 +105,7 @@ def sendAvailabilityViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -1248,6 +1248,9 @@ class PubServer(BaseHTTPRequestHandler):
headersDict['Date'] = self.headers['Date'] headersDict['Date'] = self.headers['Date']
if self.headers.get('digest'): if self.headers.get('digest'):
headersDict['digest'] = self.headers['digest'] headersDict['digest'] = self.headers['digest']
if self.headers.get('Collection-Synchronization'):
headersDict['Collection-Synchronization'] = \
self.headers['Collection-Synchronization']
if self.headers.get('Content-type'): if self.headers.get('Content-type'):
headersDict['Content-type'] = self.headers['Content-type'] headersDict['Content-type'] = self.headers['Content-type']
if self.headers.get('Content-Length'): if self.headers.get('Content-Length'):
@ -1330,6 +1333,7 @@ class PubServer(BaseHTTPRequestHandler):
return True return True
elif self.path.endswith('/' + nickname): elif self.path.endswith('/' + nickname):
return True return True
if self.server.debug:
print('AUTH: nickname ' + nickname + print('AUTH: nickname ' + nickname +
' was not found in path ' + self.path) ' was not found in path ' + self.path)
return False return False
@ -1376,7 +1380,7 @@ class PubServer(BaseHTTPRequestHandler):
if GETtimings.get(prevGetId): if GETtimings.get(prevGetId):
timeDiff = int(timeDiff - int(GETtimings[prevGetId])) timeDiff = int(timeDiff - int(GETtimings[prevGetId]))
GETtimings[currGetId] = str(timeDiff) GETtimings[currGetId] = str(timeDiff)
if logEvent: if logEvent and self.server.debug:
print('GET TIMING ' + currGetId + ' = ' + str(timeDiff)) print('GET TIMING ' + currGetId + ' = ' + str(timeDiff))
def _benchmarkPOSTtimings(self, POSTstartTime, POSTtimings: [], def _benchmarkPOSTtimings(self, POSTstartTime, POSTtimings: [],
@ -1394,6 +1398,7 @@ class PubServer(BaseHTTPRequestHandler):
if logEvent: if logEvent:
ctr = 1 ctr = 1
for timeDiff in POSTtimings: for timeDiff in POSTtimings:
if self.server.debug:
print('POST TIMING|' + str(ctr) + '|' + timeDiff) print('POST TIMING|' + str(ctr) + '|' + timeDiff)
ctr += 1 ctr += 1
@ -7348,6 +7353,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
self.server.allowLocalNetworkAccess, self.server.allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
actorJson['roles'], actorJson['roles'],
None, None) None, None)
msg = msg.encode('utf-8') msg = msg.encode('utf-8')
@ -7436,6 +7442,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
allowLocalNetworkAccess, allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
actorJson['skills'], actorJson['skills'],
None, None) None, None)
msg = msg.encode('utf-8') msg = msg.encode('utf-8')
@ -9240,6 +9247,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
self.server.allowLocalNetworkAccess, self.server.allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
shares, shares,
pageNumber, sharesPerPage) pageNumber, sharesPerPage)
msg = msg.encode('utf-8') msg = msg.encode('utf-8')
@ -9338,6 +9346,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
self.server.allowLocalNetworkAccess, self.server.allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
following, following,
pageNumber, pageNumber,
followsPerPage).encode('utf-8') followsPerPage).encode('utf-8')
@ -9436,6 +9445,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
self.server.allowLocalNetworkAccess, self.server.allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
followers, followers,
pageNumber, pageNumber,
followsPerPage).encode('utf-8') followsPerPage).encode('utf-8')
@ -9557,6 +9567,7 @@ class PubServer(BaseHTTPRequestHandler):
self.server.peertubeInstances, self.server.peertubeInstances,
self.server.allowLocalNetworkAccess, self.server.allowLocalNetworkAccess,
self.server.textModeBanner, self.server.textModeBanner,
self.server.debug,
None, None).encode('utf-8') None, None).encode('utf-8')
msglen = len(msg) msglen = len(msg)
self._set_headers('text/html', msglen, self._set_headers('text/html', msglen,
@ -13634,7 +13645,7 @@ class PubServer(BaseHTTPRequestHandler):
# check authorization # check authorization
authorized = self._isAuthorized() authorized = self._isAuthorized()
if not authorized: if not authorized and self.server.debug:
print('POST Not authorized') print('POST Not authorized')
print(str(self.headers)) print(str(self.headers))
@ -13931,6 +13942,7 @@ class PubServer(BaseHTTPRequestHandler):
"editblogpost", "newreminder", "newevent") "editblogpost", "newreminder", "newevent")
for currPostType in postTypes: for currPostType in postTypes:
if not authorized: if not authorized:
if self.server.debug:
print('POST was not authorized') print('POST was not authorized')
break break
@ -14233,6 +14245,7 @@ class PubServer(BaseHTTPRequestHandler):
return return
else: else:
if self.path == '/sharedInbox' or self.path == '/inbox': if self.path == '/sharedInbox' or self.path == '/inbox':
if self.server.debug:
print('DEBUG: POST to shared inbox') print('DEBUG: POST to shared inbox')
queueStatus = \ queueStatus = \
self._updateInboxQueue('inbox', messageJson, messageBytes) self._updateInboxQueue('inbox', messageJson, messageBytes)

View File

@ -55,7 +55,7 @@ def sendDeleteViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -295,6 +295,11 @@ parser.add_argument("--brochMode",
type=str2bool, nargs='?', type=str2bool, nargs='?',
const=True, default=False, const=True, default=False,
help="Enable broch mode") help="Enable broch mode")
parser.add_argument("--noKeyPress",
dest='noKeyPress',
type=str2bool, nargs='?',
const=True, default=False,
help="Notification daemon does not wait for keypresses")
parser.add_argument("--noapproval", type=str2bool, nargs='?', parser.add_argument("--noapproval", type=str2bool, nargs='?',
const=True, default=False, const=True, default=False,
help="Allow followers without approval") help="Allow followers without approval")
@ -509,6 +514,9 @@ args = parser.parse_args()
debug = False debug = False
if args.debug: if args.debug:
debug = True debug = True
else:
if os.path.isfile('debug'):
debug = True
if args.tests: if args.tests:
runAllTests() runAllTests()
@ -723,7 +731,7 @@ if args.json:
'Accept': 'application/ld+json; profile="' + profileStr + '"' 'Accept': 'application/ld+json; profile="' + profileStr + '"'
} }
testJson = getJson(session, args.json, asHeader, None, testJson = getJson(session, args.json, asHeader, None,
__version__, httpPrefix, None) debug, __version__, httpPrefix, None)
pprint(testJson) pprint(testJson)
sys.exit() sys.exit()
@ -1472,7 +1480,7 @@ if args.followers:
handle = nickname + '@' + domain handle = nickname + '@' + domain
wfRequest = webfingerHandle(session, handle, wfRequest = webfingerHandle(session, handle,
httpPrefix, cachedWebfingers, httpPrefix, cachedWebfingers,
None, __version__) None, __version__, debug)
if not wfRequest: if not wfRequest:
print('Unable to webfinger ' + handle) print('Unable to webfinger ' + handle)
sys.exit() sys.exit()
@ -1857,6 +1865,7 @@ if args.notifications:
args.screenreader, args.language, args.screenreader, args.language,
args.notificationSounds, args.notificationSounds,
args.notificationType, args.notificationType,
args.noKeyPress,
args.debug) args.debug)
sys.exit() sys.exit()

View File

@ -989,7 +989,7 @@ def sendFollowRequestViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)
@ -1078,7 +1078,7 @@ def sendUnfollowRequestViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -265,6 +265,10 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict,
if debug: if debug:
print('DEBUG: verifyPostHeaders ' + method) print('DEBUG: verifyPostHeaders ' + method)
print('verifyPostHeaders publicKeyPem: ' + str(publicKeyPem))
print('verifyPostHeaders headers: ' + str(headers))
print('verifyPostHeaders messageBodyJsonStr: ' +
str(messageBodyJsonStr))
pubkey = load_pem_public_key(publicKeyPem.encode('utf-8'), pubkey = load_pem_public_key(publicKeyPem.encode('utf-8'),
backend=default_backend()) backend=default_backend())
@ -353,7 +357,24 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict,
signedHeaderList.append( signedHeaderList.append(
f'{signedHeader}: {headers[signedHeader]}') f'{signedHeader}: {headers[signedHeader]}')
else: else:
if '-' in signedHeader:
# capitalise with dashes
# my-header becomes My-Header
headerParts = signedHeader.split('-')
signedHeaderCap = None
for part in headerParts:
if signedHeaderCap:
signedHeaderCap += '-' + part.capitalize()
else:
signedHeaderCap = part.capitalize()
else:
# header becomes Header
signedHeaderCap = signedHeader.capitalize() signedHeaderCap = signedHeader.capitalize()
if debug:
print('signedHeaderCap: ' + signedHeaderCap)
# if this is the date header then check it is recent
if signedHeaderCap == 'Date': if signedHeaderCap == 'Date':
if not _verifyRecentSignature(headers[signedHeaderCap]): if not _verifyRecentSignature(headers[signedHeaderCap]):
if debug: if debug:
@ -361,6 +382,14 @@ def verifyPostHeaders(httpPrefix: str, publicKeyPem: str, headers: dict,
'verifyPostHeaders date is not recent ' + 'verifyPostHeaders date is not recent ' +
headers[signedHeader]) headers[signedHeader])
return False return False
# add the capitalised header
if headers.get(signedHeaderCap):
signedHeaderList.append(
f'{signedHeader}: {headers[signedHeaderCap]}')
elif '-' in signedHeader:
# my-header becomes My-header
signedHeaderCap = signedHeader.capitalize()
if headers.get(signedHeaderCap): if headers.get(signedHeaderCap):
signedHeaderList.append( signedHeaderList.append(
f'{signedHeader}: {headers[signedHeaderCap]}') f'{signedHeader}: {headers[signedHeaderCap]}')

View File

@ -253,8 +253,8 @@ def getPersonPubKey(baseDir: str, session, personUrl: str,
'Accept': 'application/activity+json; profile="' + profileStr + '"' 'Accept': 'application/activity+json; profile="' + profileStr + '"'
} }
personJson = \ personJson = \
getJson(session, personUrl, asHeader, None, projectVersion, getJson(session, personUrl, asHeader, None, debug,
httpPrefix, personDomain) projectVersion, httpPrefix, personDomain)
if not personJson: if not personJson:
return None return None
pubKey = None pubKey = None
@ -395,6 +395,7 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str,
replyDomain, replyPort = \ replyDomain, replyPort = \
getDomainFromActor(inReplyTo) getDomainFromActor(inReplyTo)
if isBlockedDomain(baseDir, replyDomain): if isBlockedDomain(baseDir, replyDomain):
if debug:
print('WARN: post contains reply from ' + print('WARN: post contains reply from ' +
str(actor) + str(actor) +
' to a blocked domain: ' + replyDomain) ' to a blocked domain: ' + replyDomain)
@ -405,6 +406,7 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str,
if replyNickname and replyDomain: if replyNickname and replyDomain:
if isBlocked(baseDir, nickname, domain, if isBlocked(baseDir, nickname, domain,
replyNickname, replyDomain): replyNickname, replyDomain):
if debug:
print('WARN: post contains reply from ' + print('WARN: post contains reply from ' +
str(actor) + str(actor) +
' to a blocked account: ' + ' to a blocked account: ' +
@ -414,6 +416,7 @@ def savePostToInboxQueue(baseDir: str, httpPrefix: str,
if isinstance(postJsonObject['object']['content'], str): if isinstance(postJsonObject['object']['content'], str):
if isFiltered(baseDir, nickname, domain, if isFiltered(baseDir, nickname, domain,
postJsonObject['object']['content']): postJsonObject['object']['content']):
if debug:
print('WARN: post was filtered out due to content') print('WARN: post was filtered out due to content')
return None return None
originalPostId = None originalPostId = None
@ -758,6 +761,7 @@ def _personReceiveUpdate(baseDir: str,
debug: bool) -> bool: debug: bool) -> bool:
"""Changes an actor. eg: avatar or display name change """Changes an actor. eg: avatar or display name change
""" """
if debug:
print('Receiving actor update for ' + personJson['url'] + print('Receiving actor update for ' + personJson['url'] +
' ' + str(personJson)) ' ' + str(personJson))
domainFull = getFullDomain(domain, port) domainFull = getFullDomain(domain, port)
@ -814,6 +818,7 @@ def _personReceiveUpdate(baseDir: str,
personCache, True) personCache, True)
# save to cache on file # save to cache on file
if saveJson(personJson, actorFilename): if saveJson(personJson, actorFilename):
if debug:
print('actor updated for ' + personJson['id']) print('actor updated for ' + personJson['id'])
# remove avatar if it exists so that it will be refreshed later # remove avatar if it exists so that it will be refreshed later
@ -901,7 +906,9 @@ def _receiveUpdate(recentPostsCache: {}, session, baseDir: str,
if messageJson['type'] == 'Person': if messageJson['type'] == 'Person':
if messageJson.get('url') and messageJson.get('id'): if messageJson.get('url') and messageJson.get('id'):
print('Request to update actor unwrapped: ' + str(messageJson)) if debug:
print('Request to update actor unwrapped: ' +
str(messageJson))
updateNickname = getNicknameFromActor(messageJson['id']) updateNickname = getNicknameFromActor(messageJson['id'])
if updateNickname: if updateNickname:
updateDomain, updatePort = \ updateDomain, updatePort = \
@ -922,6 +929,7 @@ def _receiveUpdate(recentPostsCache: {}, session, baseDir: str,
messageJson['object']['type'] == 'Service': messageJson['object']['type'] == 'Service':
if messageJson['object'].get('url') and \ if messageJson['object'].get('url') and \
messageJson['object'].get('id'): messageJson['object'].get('id'):
if debug:
print('Request to update actor: ' + str(messageJson)) print('Request to update actor: ' + str(messageJson))
updateNickname = getNicknameFromActor(messageJson['actor']) updateNickname = getNicknameFromActor(messageJson['actor'])
if updateNickname: if updateNickname:
@ -1376,7 +1384,7 @@ def _receiveAnnounce(recentPostsCache: {},
__version__, translate, __version__, translate,
YTReplacementDomain, YTReplacementDomain,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache) recentPostsCache, debug)
if not postJsonObject: if not postJsonObject:
notInOnion = True notInOnion = True
if onionDomain: if onionDomain:
@ -1432,6 +1440,7 @@ def _receiveAnnounce(recentPostsCache: {},
__version__, httpPrefix, __version__, httpPrefix,
domain, onionDomain) domain, onionDomain)
if pubKey: if pubKey:
if debug:
print('DEBUG: public key obtained for announce: ' + print('DEBUG: public key obtained for announce: ' +
lookupActor) lookupActor)
break break
@ -1602,7 +1611,7 @@ def _estimateNumberOfEmoji(content: str) -> int:
def _validPostContent(baseDir: str, nickname: str, domain: str, def _validPostContent(baseDir: str, nickname: str, domain: str,
messageJson: {}, maxMentions: int, maxEmoji: int, messageJson: {}, maxMentions: int, maxEmoji: int,
allowLocalNetworkAccess: bool) -> bool: allowLocalNetworkAccess: bool, debug: bool) -> bool:
"""Is the content of a received post valid? """Is the content of a received post valid?
Check for bad html Check for bad html
Check for hellthreads Check for hellthreads
@ -1621,7 +1630,7 @@ def _validPostContent(baseDir: str, nickname: str, domain: str,
return False return False
if 'Z' not in messageJson['object']['published']: if 'Z' not in messageJson['object']['published']:
return False return False
if not validPostDate(messageJson['object']['published']): if not validPostDate(messageJson['object']['published'], 90, debug):
return False return False
if messageJson['object'].get('summary'): if messageJson['object'].get('summary'):
@ -1687,6 +1696,7 @@ def _validPostContent(baseDir: str, nickname: str, domain: str,
print('REJECT: reply to post which does not ' + print('REJECT: reply to post which does not ' +
'allow comments: ' + originalPostId) 'allow comments: ' + originalPostId)
return False return False
if debug:
print('ACCEPT: post content is valid') print('ACCEPT: post content is valid')
return True return True
@ -1729,6 +1739,7 @@ def _obtainAvatarForReplyPost(session, baseDir: str, httpPrefix: str,
__version__, httpPrefix, __version__, httpPrefix,
domain, onionDomain) domain, onionDomain)
if pubKey: if pubKey:
if debug:
print('DEBUG: public key obtained for reply: ' + lookupActor) print('DEBUG: public key obtained for reply: ' + lookupActor)
break break
@ -2299,7 +2310,7 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
nickname = handle.split('@')[0] nickname = handle.split('@')[0]
if _validPostContent(baseDir, nickname, domain, if _validPostContent(baseDir, nickname, domain,
postJsonObject, maxMentions, maxEmoji, postJsonObject, maxMentions, maxEmoji,
allowLocalNetworkAccess): allowLocalNetworkAccess, debug):
if postJsonObject.get('object'): if postJsonObject.get('object'):
jsonObj = postJsonObject['object'] jsonObj = postJsonObject['object']
@ -2465,7 +2476,7 @@ def _inboxAfterInitial(recentPostsCache: {}, maxRecentPosts: int,
nickname, domain, postJsonObject, nickname, domain, postJsonObject,
translate, YTReplacementDomain, translate, YTReplacementDomain,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache): recentPostsCache, debug):
# media index will be updated # media index will be updated
updateIndexList.append('tlmedia') updateIndexList.append('tlmedia')
if isBlogPost(postJsonObject): if isBlogPost(postJsonObject):
@ -2702,6 +2713,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
queue.pop(0) queue.pop(0)
continue continue
if debug:
print('Loading queue item ' + queueFilename) print('Loading queue item ' + queueFilename)
# Load the queue json # Load the queue json
@ -2829,7 +2841,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
if accountMaxPostsPerDay > 0 or domainMaxPostsPerDay > 0: if accountMaxPostsPerDay > 0 or domainMaxPostsPerDay > 0:
pprint(quotasDaily) pprint(quotasDaily)
if queueJson.get('actor'): if debug and queueJson.get('actor'):
print('Obtaining public key for actor ' + queueJson['actor']) print('Obtaining public key for actor ' + queueJson['actor'])
# Try a few times to obtain the public key # Try a few times to obtain the public key
@ -2866,6 +2878,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
time.sleep(1) time.sleep(1)
if not pubKey: if not pubKey:
if debug:
print('Queue: public key could not be obtained from ' + keyId) print('Queue: public key could not be obtained from ' + keyId)
if os.path.isfile(queueFilename): if os.path.isfile(queueFilename):
os.remove(queueFilename) os.remove(queueFilename)
@ -2888,7 +2901,6 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
debug): debug):
httpSignatureFailed = True httpSignatureFailed = True
print('Queue: Header signature check failed') print('Queue: Header signature check failed')
if debug:
pprint(queueJson['httpHeaders']) pprint(queueJson['httpHeaders'])
else: else:
if debug: if debug:
@ -3041,6 +3053,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
federationList, federationList,
queueJson['postNickname'], queueJson['postNickname'],
debug): debug):
if debug:
print('Queue: Update accepted from ' + keyId) print('Queue: Update accepted from ' + keyId)
if os.path.isfile(queueFilename): if os.path.isfile(queueFilename):
os.remove(queueFilename) os.remove(queueFilename)
@ -3054,6 +3067,7 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
httpPrefix, domain, port, debug) httpPrefix, domain, port, debug)
if len(recipientsDict.items()) == 0 and \ if len(recipientsDict.items()) == 0 and \
len(recipientsDictFollowers.items()) == 0: len(recipientsDictFollowers.items()) == 0:
if debug:
print('Queue: no recipients were resolved ' + print('Queue: no recipients were resolved ' +
'for post arriving in inbox') 'for post arriving in inbox')
if os.path.isfile(queueFilename): if os.path.isfile(queueFilename):
@ -3123,7 +3137,6 @@ def runInboxQueue(recentPostsCache: {}, maxRecentPosts: int,
themeName) themeName)
if debug: if debug:
pprint(queueJson['post']) pprint(queueJson['post'])
print('Queue: Queue post accepted') print('Queue: Queue post accepted')
if os.path.isfile(queueFilename): if os.path.isfile(queueFilename):
os.remove(queueFilename) os.remove(queueFilename)

View File

@ -78,7 +78,7 @@ fi
echo ''; echo '';
echo '[Service]'; echo '[Service]';
echo "WorkingDirectory=${HOME}/.epicyon"; echo "WorkingDirectory=${HOME}/.epicyon";
echo "ExecStart=/usr/bin/python3 epicyon.py --notifyType $notificationType --notify $HANDLE --password \"$PASSWORD\""; echo "ExecStart=/usr/bin/python3 epicyon.py --noKeyPress --notifyType $notificationType --notify $HANDLE --password \"$PASSWORD\"";
echo 'Type=oneshot'; echo 'Type=oneshot';
echo 'RemainAfterExit=yes'; echo 'RemainAfterExit=yes';
echo ''; echo '';

View File

@ -167,7 +167,7 @@ def sendLikeViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)
@ -248,7 +248,7 @@ def sendUndoLikeViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -56,7 +56,7 @@ def _updateMovedHandle(baseDir: str, nickname: str, domain: str,
handle = handle[1:] handle = handle[1:]
wfRequest = webfingerHandle(session, handle, wfRequest = webfingerHandle(session, handle,
httpPrefix, cachedWebfingers, httpPrefix, cachedWebfingers,
None, __version__) None, __version__, debug)
if not wfRequest: if not wfRequest:
print('updateMovedHandle unable to webfinger ' + handle) print('updateMovedHandle unable to webfinger ' + handle)
return ctr return ctr
@ -76,7 +76,7 @@ def _updateMovedHandle(baseDir: str, nickname: str, domain: str,
'Accept': 'application/activity+json; profile="' + profileStr + '"' 'Accept': 'application/activity+json; profile="' + profileStr + '"'
} }
if not personUrl: if not personUrl:
personUrl = getUserUrl(wfRequest) personUrl = getUserUrl(wfRequest, 0, debug)
if not personUrl: if not personUrl:
return ctr return ctr
@ -85,8 +85,8 @@ def _updateMovedHandle(baseDir: str, nickname: str, domain: str,
'Accept': 'application/ld+json; profile="' + profileStr + '"' 'Accept': 'application/ld+json; profile="' + profileStr + '"'
} }
personJson = \ personJson = \
getJson(session, personUrl, asHeader, None, __version__, getJson(session, personUrl, asHeader, None,
httpPrefix, None) debug, __version__, httpPrefix, None)
if not personJson: if not personJson:
return ctr return ctr
if not personJson.get('movedTo'): if not personJson.get('movedTo'):

View File

@ -144,11 +144,11 @@ def _addNewswireDictEntry(baseDir: str, domain: str,
] ]
def _validFeedDate(pubDate: str) -> bool: def _validFeedDate(pubDate: str, debug=False) -> bool:
# convert from YY-MM-DD HH:MM:SS+00:00 to # convert from YY-MM-DD HH:MM:SS+00:00 to
# YY-MM-DDTHH:MM:SSZ # YY-MM-DDTHH:MM:SSZ
postDate = pubDate.replace(' ', 'T').replace('+00:00', 'Z') postDate = pubDate.replace(' ', 'T').replace('+00:00', 'Z')
return validPostDate(postDate, 90) return validPostDate(postDate, 90, debug)
def parseFeedDate(pubDate: str) -> str: def parseFeedDate(pubDate: str) -> str:

View File

@ -574,6 +574,7 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str,
systemLanguage: str, systemLanguage: str,
notificationSounds: bool, notificationSounds: bool,
notificationType: str, notificationType: str,
noKeyPress: bool,
debug: bool) -> None: debug: bool) -> None:
"""Runs the notifications and screen reader client, """Runs the notifications and screen reader client,
which announces new inbox items which announces new inbox items
@ -772,6 +773,9 @@ def runNotificationsClient(baseDir: str, proxyType: str, httpPrefix: str,
prevSay = speakerJson['say'] prevSay = speakerJson['say']
# wait for a while, or until a key is pressed # wait for a while, or until a key is pressed
if noKeyPress:
time.sleep(10)
else:
keyPress = _waitForKeypress(30, debug) keyPress = _waitForKeypress(30, debug)
if keyPress: if keyPress:
if keyPress.startswith('/'): if keyPress.startswith('/'):

View File

@ -272,7 +272,7 @@ def postMessageToOutbox(session, translate: {},
messageJson, messageJson,
translate, YTReplacementDomain, translate, YTReplacementDomain,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache): recentPostsCache, debug):
inboxUpdateIndex('tlmedia', baseDir, inboxUpdateIndex('tlmedia', baseDir,
postToNickname + '@' + domain, postToNickname + '@' + domain,
savedFilename, debug) savedFilename, debug)

View File

@ -1102,7 +1102,8 @@ def setPersonNotes(baseDir: str, nickname: str, domain: str,
return True return True
def getActorJson(handle: str, http: bool, gnunet: bool, quiet=False) -> {}: def getActorJson(handle: str, http: bool, gnunet: bool,
debug: bool, quiet=False) -> {}:
"""Returns the actor json """Returns the actor json
""" """
originalActor = handle originalActor = handle
@ -1175,7 +1176,7 @@ def getActorJson(handle: str, http: bool, gnunet: bool, quiet=False) -> {}:
handle = nickname + '@' + domain handle = nickname + '@' + domain
wfRequest = webfingerHandle(session, handle, wfRequest = webfingerHandle(session, handle,
httpPrefix, cachedWebfingers, httpPrefix, cachedWebfingers,
None, __version__) None, __version__, debug)
if not wfRequest: if not wfRequest:
if not quiet: if not quiet:
print('Unable to webfinger ' + handle) print('Unable to webfinger ' + handle)
@ -1203,7 +1204,7 @@ def getActorJson(handle: str, http: bool, gnunet: bool, quiet=False) -> {}:
'Accept': 'application/activity+json; profile="' + profileStr + '"' 'Accept': 'application/activity+json; profile="' + profileStr + '"'
} }
if not personUrl: if not personUrl:
personUrl = getUserUrl(wfRequest) personUrl = getUserUrl(wfRequest, 0, debug)
if nickname == domain: if nickname == domain:
personUrl = personUrl.replace('/users/', '/actor/') personUrl = personUrl.replace('/users/', '/actor/')
personUrl = personUrl.replace('/accounts/', '/actor/') personUrl = personUrl.replace('/accounts/', '/actor/')
@ -1224,8 +1225,8 @@ def getActorJson(handle: str, http: bool, gnunet: bool, quiet=False) -> {}:
} }
personJson = \ personJson = \
getJson(session, personUrl, asHeader, None, __version__, getJson(session, personUrl, asHeader, None,
httpPrefix, None, 20, quiet) debug, __version__, httpPrefix, None, 20, quiet)
if personJson: if personJson:
if not quiet: if not quiet:
pprint(personJson) pprint(personJson)
@ -1236,7 +1237,7 @@ def getActorJson(handle: str, http: bool, gnunet: bool, quiet=False) -> {}:
} }
personJson = \ personJson = \
getJson(session, personUrl, asHeader, None, getJson(session, personUrl, asHeader, None,
__version__, httpPrefix, None) debug, __version__, httpPrefix, None)
if not quiet: if not quiet:
if personJson: if personJson:
pprint(personJson) pprint(personJson)

View File

@ -148,7 +148,7 @@ def _cleanHtml(rawHtml: str) -> str:
return html.unescape(text) return html.unescape(text)
def getUserUrl(wfRequest: {}, sourceId=0) -> str: def getUserUrl(wfRequest: {}, sourceId=0, debug=False) -> str:
"""Gets the actor url from a webfinger request """Gets the actor url from a webfinger request
""" """
if not wfRequest.get('links'): if not wfRequest.get('links'):
@ -166,7 +166,7 @@ def getUserUrl(wfRequest: {}, sourceId=0) -> str:
if link['type'] != 'application/activity+json': if link['type'] != 'application/activity+json':
continue continue
if '/@' not in link['href']: if '/@' not in link['href']:
if not hasUsersPath(link['href']): if debug and not hasUsersPath(link['href']):
print('getUserUrl webfinger activity+json ' + print('getUserUrl webfinger activity+json ' +
'contains single user instance actor ' + 'contains single user instance actor ' +
str(sourceId) + ' ' + str(link)) str(sourceId) + ' ' + str(link))
@ -183,7 +183,7 @@ def parseUserFeed(session, feedUrl: str, asHeader: {},
return None return None
feedJson = getJson(session, feedUrl, asHeader, None, feedJson = getJson(session, feedUrl, asHeader, None,
projectVersion, httpPrefix, domain) False, projectVersion, httpPrefix, domain)
if not feedJson: if not feedJson:
return None return None
@ -220,6 +220,7 @@ def getPersonBox(baseDir: str, session, wfRequest: {},
nickname: str, domain: str, nickname: str, domain: str,
boxName='inbox', boxName='inbox',
sourceId=0) -> (str, str, str, str, str, str, str, str): sourceId=0) -> (str, str, str, str, str, str, str, str):
debug = False
profileStr = 'https://www.w3.org/ns/activitystreams' profileStr = 'https://www.w3.org/ns/activitystreams'
asHeader = { asHeader = {
'Accept': 'application/activity+json; profile="' + profileStr + '"' 'Accept': 'application/activity+json; profile="' + profileStr + '"'
@ -229,7 +230,7 @@ def getPersonBox(baseDir: str, session, wfRequest: {},
return None, None, None, None, None, None, None return None, None, None, None, None, None, None
if not wfRequest.get('errors'): if not wfRequest.get('errors'):
personUrl = getUserUrl(wfRequest, sourceId) personUrl = getUserUrl(wfRequest, sourceId, debug)
else: else:
if nickname == 'dev': if nickname == 'dev':
# try single user instance # try single user instance
@ -250,13 +251,13 @@ def getPersonBox(baseDir: str, session, wfRequest: {},
'Accept': 'application/ld+json; profile="' + profileStr + '"' 'Accept': 'application/ld+json; profile="' + profileStr + '"'
} }
personJson = getJson(session, personUrl, asHeader, None, personJson = getJson(session, personUrl, asHeader, None,
projectVersion, httpPrefix, domain) debug, projectVersion, httpPrefix, domain)
if not personJson: if not personJson:
asHeader = { asHeader = {
'Accept': 'application/ld+json; profile="' + profileStr + '"' 'Accept': 'application/ld+json; profile="' + profileStr + '"'
} }
personJson = getJson(session, personUrl, asHeader, None, personJson = getJson(session, personUrl, asHeader, None,
projectVersion, httpPrefix, domain) debug, projectVersion, httpPrefix, domain)
if not personJson: if not personJson:
print('Unable to get actor') print('Unable to get actor')
return None, None, None, None, None, None, None return None, None, None, None, None, None, None
@ -1935,7 +1936,7 @@ def sendPost(projectVersion: str,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
return 1 return 1
if not isinstance(wfRequest, dict): if not isinstance(wfRequest, dict):
@ -2052,7 +2053,7 @@ def sendPostViaServer(projectVersion: str,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: webfinger failed for ' + handle) print('DEBUG: webfinger failed for ' + handle)
@ -2249,7 +2250,7 @@ def sendSignedJson(postJsonObject: {}, session, baseDir: str,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, cachedWebfingers, wfRequest = webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: webfinger for ' + handle + ' failed') print('DEBUG: webfinger for ' + handle + ' failed')
@ -2538,7 +2539,8 @@ def sendToNamedAddresses(session, baseDir: str,
personCache, debug, projectVersion) personCache, debug, projectVersion)
def _hasSharedInbox(session, httpPrefix: str, domain: str) -> bool: def _hasSharedInbox(session, httpPrefix: str, domain: str,
debug: bool) -> bool:
"""Returns true if the given domain has a shared inbox """Returns true if the given domain has a shared inbox
This tries the new and the old way of webfingering the shared inbox This tries the new and the old way of webfingering the shared inbox
""" """
@ -2547,9 +2549,8 @@ def _hasSharedInbox(session, httpPrefix: str, domain: str) -> bool:
'inbox@' + domain 'inbox@' + domain
] ]
for handle in tryHandles: for handle in tryHandles:
wfRequest = webfingerHandle(session, handle, wfRequest = webfingerHandle(session, handle, httpPrefix, {},
httpPrefix, {}, None, __version__, debug)
None, __version__)
if wfRequest: if wfRequest:
if isinstance(wfRequest, dict): if isinstance(wfRequest, dict):
if not wfRequest.get('errors'): if not wfRequest.get('errors'):
@ -2634,7 +2635,8 @@ def sendToFollowers(session, baseDir: str,
print('Sending post to followers domain is active: ' + print('Sending post to followers domain is active: ' +
followerDomainUrl) followerDomainUrl)
withSharedInbox = _hasSharedInbox(session, httpPrefix, followerDomain) withSharedInbox = _hasSharedInbox(session, httpPrefix,
followerDomain, debug)
if debug: if debug:
if withSharedInbox: if withSharedInbox:
print(followerDomain + ' has shared inbox') print(followerDomain + ' has shared inbox')
@ -2926,7 +2928,7 @@ def isImageMedia(session, baseDir: str, httpPrefix: str,
postJsonObject: {}, translate: {}, postJsonObject: {}, translate: {},
YTReplacementDomain: str, YTReplacementDomain: str,
allowLocalNetworkAccess: bool, allowLocalNetworkAccess: bool,
recentPostsCache: {}) -> bool: recentPostsCache: {}, debug: bool) -> bool:
"""Returns true if the given post has attached image media """Returns true if the given post has attached image media
""" """
if postJsonObject['type'] == 'Announce': if postJsonObject['type'] == 'Announce':
@ -2936,7 +2938,7 @@ def isImageMedia(session, baseDir: str, httpPrefix: str,
__version__, translate, __version__, translate,
YTReplacementDomain, YTReplacementDomain,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache) recentPostsCache, debug)
if postJsonAnnounce: if postJsonAnnounce:
postJsonObject = postJsonAnnounce postJsonObject = postJsonAnnounce
if postJsonObject['type'] != 'Create': if postJsonObject['type'] != 'Create':
@ -3463,7 +3465,7 @@ def getPublicPostsOfPerson(baseDir: str, nickname: str, domain: str,
handle = httpPrefix + "://" + domainFull + "/@" + nickname handle = httpPrefix + "://" + domainFull + "/@" + nickname
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
sys.exit() sys.exit()
if not isinstance(wfRequest, dict): if not isinstance(wfRequest, dict):
@ -3505,7 +3507,7 @@ def getPublicPostDomains(session, baseDir: str, nickname: str, domain: str,
handle = httpPrefix + "://" + domainFull + "/@" + nickname handle = httpPrefix + "://" + domainFull + "/@" + nickname
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
return domainList return domainList
if not isinstance(wfRequest, dict): if not isinstance(wfRequest, dict):
@ -3536,7 +3538,7 @@ def getPublicPostDomains(session, baseDir: str, nickname: str, domain: str,
def downloadFollowCollection(followType: str, def downloadFollowCollection(followType: str,
session, httpPrefix, session, httpPrefix,
actor: str, pageNumber=1, actor: str, pageNumber=1,
noOfPages=1) -> []: noOfPages=1, debug=False) -> []:
"""Returns a list of following/followers for the given actor """Returns a list of following/followers for the given actor
by downloading the json for their following/followers collection by downloading the json for their following/followers collection
""" """
@ -3553,8 +3555,8 @@ def downloadFollowCollection(followType: str,
for pageCtr in range(noOfPages): for pageCtr in range(noOfPages):
url = actor + '/' + followType + '?page=' + str(pageNumber + pageCtr) url = actor + '/' + followType + '?page=' + str(pageNumber + pageCtr)
followersJson = \ followersJson = \
getJson(session, url, sessionHeaders, None, __version__, getJson(session, url, sessionHeaders, None,
httpPrefix, None) debug, __version__, httpPrefix, None)
if followersJson: if followersJson:
if followersJson.get('orderedItems'): if followersJson.get('orderedItems'):
for followerActor in followersJson['orderedItems']: for followerActor in followersJson['orderedItems']:
@ -3585,7 +3587,7 @@ def getPublicPostInfo(session, baseDir: str, nickname: str, domain: str,
handle = httpPrefix + "://" + domainFull + "/@" + nickname handle = httpPrefix + "://" + domainFull + "/@" + nickname
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
return {} return {}
if not isinstance(wfRequest, dict): if not isinstance(wfRequest, dict):
@ -3841,7 +3843,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
postJsonObject: {}, projectVersion: str, postJsonObject: {}, projectVersion: str,
translate: {}, YTReplacementDomain: str, translate: {}, YTReplacementDomain: str,
allowLocalNetworkAccess: bool, allowLocalNetworkAccess: bool,
recentPostsCache: {}) -> {}: recentPostsCache: {}, debug: bool) -> {}:
"""Download the post referenced by an announce """Download the post referenced by an announce
""" """
if not postJsonObject.get('object'): if not postJsonObject.get('object'):
@ -3865,6 +3867,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
return None return None
if os.path.isfile(announceFilename): if os.path.isfile(announceFilename):
if debug:
print('Reading cached Announce content for ' + print('Reading cached Announce content for ' +
postJsonObject['object']) postJsonObject['object'])
postJsonObject = loadJson(announceFilename) postJsonObject = loadJson(announceFilename)
@ -3906,10 +3909,12 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
print('Announce download blocked object: ' + print('Announce download blocked object: ' +
str(postJsonObject['object'])) str(postJsonObject['object']))
return None return None
print('Downloading Announce content for ' + postJsonObject['object']) if debug:
print('Downloading Announce content for ' +
postJsonObject['object'])
announcedJson = \ announcedJson = \
getJson(session, postJsonObject['object'], asHeader, getJson(session, postJsonObject['object'], asHeader,
None, projectVersion, httpPrefix, domain) None, debug, projectVersion, httpPrefix, domain)
if not announcedJson: if not announcedJson:
return None return None
@ -3958,7 +3963,7 @@ def downloadAnnounce(session, baseDir: str, httpPrefix: str,
baseDir, nickname, domain, postId, baseDir, nickname, domain, postId,
recentPostsCache) recentPostsCache)
return None return None
if not validPostDate(announcedJson['published']): if not validPostDate(announcedJson['published'], 90, debug):
_rejectAnnounce(announceFilename, _rejectAnnounce(announceFilename,
baseDir, nickname, domain, postId, baseDir, nickname, domain, postId,
recentPostsCache) recentPostsCache)
@ -4148,7 +4153,7 @@ def sendBlockViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)
@ -4232,7 +4237,7 @@ def sendUndoBlockViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -2378,8 +2378,13 @@ class JsonLdProcessor(object):
# hash bnode paths # hash bnode paths
path_namer = UniqueNamer('_:b') path_namer = UniqueNamer('_:b')
path_namer.get_name(bnode) path_namer.get_name(bnode)
results.append(self._hash_paths( try:
bnode, bnodes, namer, path_namer)) bnode_path = self._hash_paths(
bnode, bnodes, namer, path_namer)
results.append(bnode_path)
except BaseException:
print('WARN: jsonld bnode_path failed')
pass
# name bnodes in hash order # name bnodes in hash order
cmp_hashes = cmp_to_key(lambda x, y: cmp(x['hash'], y['hash'])) cmp_hashes = cmp_to_key(lambda x, y: cmp(x['hash'], y['hash']))

View File

@ -310,7 +310,7 @@ def sendRoleViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = webfingerHandle(session, handle, httpPrefix, wfRequest = webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
delegatorDomain, projectVersion) delegatorDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -84,10 +84,11 @@ def urlExists(session, url: str, timeoutSec=3,
return False return False
def getJson(session, url: str, headers: {}, params: {}, def getJson(session, url: str, headers: {}, params: {}, debug: bool,
version='1.2.0', httpPrefix='https', version='1.2.0', httpPrefix='https',
domain='testdomain', timeoutSec=20, quiet=False) -> {}: domain='testdomain', timeoutSec=20, quiet=False) -> {}:
if not isinstance(url, str): if not isinstance(url, str):
if debug and not quiet:
print('url: ' + str(url)) print('url: ' + str(url))
print('ERROR: getJson failed, url should be a string') print('ERROR: getJson failed, url should be a string')
return None return None
@ -113,7 +114,7 @@ def getJson(session, url: str, headers: {}, params: {},
sessionHeaders2 = sessionHeaders.copy() sessionHeaders2 = sessionHeaders.copy()
if sessionHeaders2.get('Authorization'): if sessionHeaders2.get('Authorization'):
sessionHeaders2['Authorization'] = 'REDACTED' sessionHeaders2['Authorization'] = 'REDACTED'
if not quiet: if debug and not quiet:
print('ERROR: getJson failed\nurl: ' + str(url) + ' ' + print('ERROR: getJson failed\nurl: ' + str(url) + ' ' +
'headers: ' + str(sessionHeaders2) + ' ' + 'headers: ' + str(sessionHeaders2) + ' ' +
'params: ' + str(sessionParams)) 'params: ' + str(sessionParams))
@ -122,7 +123,7 @@ def getJson(session, url: str, headers: {}, params: {},
sessionHeaders2 = sessionHeaders.copy() sessionHeaders2 = sessionHeaders.copy()
if sessionHeaders2.get('Authorization'): if sessionHeaders2.get('Authorization'):
sessionHeaders2['Authorization'] = 'REDACTED' sessionHeaders2['Authorization'] = 'REDACTED'
if not quiet: if debug and not quiet:
print('ERROR: getJson failed\nurl: ' + str(url) + ' ' + print('ERROR: getJson failed\nurl: ' + str(url) + ' ' +
'headers: ' + str(sessionHeaders2) + ' ' + 'headers: ' + str(sessionHeaders2) + ' ' +
'params: ' + str(sessionParams) + ' ') 'params: ' + str(sessionParams) + ' ')

View File

@ -358,7 +358,7 @@ def sendShareViaServer(baseDir, session,
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)
@ -457,7 +457,7 @@ def sendUndoShareViaServer(baseDir: str, session,
# lookup the inbox for the To handle # lookup the inbox for the To handle
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, cachedWebfingers, webfingerHandle(session, handle, httpPrefix, cachedWebfingers,
fromDomain, projectVersion) fromDomain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -123,7 +123,7 @@ def sendSkillViaServer(baseDir: str, session, nickname: str, password: str,
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
if debug: if debug:
print('DEBUG: announce webfinger failed for ' + handle) print('DEBUG: announce webfinger failed for ' + handle)

View File

@ -52,7 +52,7 @@ def instancesGraph(baseDir: str, handles: str,
wfRequest = \ wfRequest = \
webfingerHandle(session, handle, httpPrefix, webfingerHandle(session, handle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wfRequest: if not wfRequest:
return dotGraphStr + '}\n' return dotGraphStr + '}\n'
if not isinstance(wfRequest, dict): if not isinstance(wfRequest, dict):

View File

@ -279,7 +279,7 @@ def getSpeakerFromServer(baseDir: str, session,
domainFull + '/users/' + nickname + '/speaker' domainFull + '/users/' + nickname + '/speaker'
speakerJson = \ speakerJson = \
getJson(session, url, headers, None, getJson(session, url, headers, None, debug,
__version__, httpPrefix, domain, 20, True) __version__, httpPrefix, domain, 20, True)
return speakerJson return speakerJson

View File

@ -100,7 +100,7 @@ def hasUsersPath(pathStr: str) -> bool:
return False return False
def validPostDate(published: str, maxAgeDays=90) -> bool: def validPostDate(published: str, maxAgeDays=90, debug=False) -> bool:
"""Returns true if the published date is recent and is not in the future """Returns true if the published date is recent and is not in the future
""" """
baselineTime = datetime.datetime(1970, 1, 1) baselineTime = datetime.datetime(1970, 1, 1)
@ -118,10 +118,12 @@ def validPostDate(published: str, maxAgeDays=90) -> bool:
postDaysSinceEpoch = daysDiff.days postDaysSinceEpoch = daysDiff.days
if postDaysSinceEpoch > nowDaysSinceEpoch: if postDaysSinceEpoch > nowDaysSinceEpoch:
if debug:
print("Inbox post has a published date in the future!") print("Inbox post has a published date in the future!")
return False return False
if nowDaysSinceEpoch - postDaysSinceEpoch >= maxAgeDays: if nowDaysSinceEpoch - postDaysSinceEpoch >= maxAgeDays:
if debug:
print("Inbox post is not recent enough") print("Inbox post is not recent enough")
return False return False
return True return True

View File

@ -1223,7 +1223,7 @@ def individualPostAsHtml(allowDownloads: bool,
postActorWf = \ postActorWf = \
webfingerHandle(session, postActorHandle, httpPrefix, webfingerHandle(session, postActorHandle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, __version__) domain, __version__, False)
avatarUrl2 = None avatarUrl2 = None
displayName = None displayName = None
@ -1292,7 +1292,7 @@ def individualPostAsHtml(allowDownloads: bool,
projectVersion, translate, projectVersion, translate,
YTReplacementDomain, YTReplacementDomain,
allowLocalNetworkAccess, allowLocalNetworkAccess,
recentPostsCache) recentPostsCache, False)
if not postJsonAnnounce: if not postJsonAnnounce:
# if the announce could not be downloaded then mark it as rejected # if the announce could not be downloaded then mark it as rejected
rejectPostId(baseDir, nickname, domain, postJsonObject['id'], rejectPostId(baseDir, nickname, domain, postJsonObject['id'],

View File

@ -75,11 +75,13 @@ def htmlProfileAfterSearch(cssCache: {},
searchDomain, searchPort = getDomainFromActor(profileHandle) searchDomain, searchPort = getDomainFromActor(profileHandle)
else: else:
if '@' not in profileHandle: if '@' not in profileHandle:
if debug:
print('DEBUG: no @ in ' + profileHandle) print('DEBUG: no @ in ' + profileHandle)
return None return None
if profileHandle.startswith('@'): if profileHandle.startswith('@'):
profileHandle = profileHandle[1:] profileHandle = profileHandle[1:]
if '@' not in profileHandle: if '@' not in profileHandle:
if debug:
print('DEBUG: no @ in ' + profileHandle) print('DEBUG: no @ in ' + profileHandle)
return None return None
searchNickname = profileHandle.split('@')[0] searchNickname = profileHandle.split('@')[0]
@ -91,16 +93,20 @@ def htmlProfileAfterSearch(cssCache: {},
searchPort = int(searchPortStr) searchPort = int(searchPortStr)
searchDomain = searchDomain.split(':')[0] searchDomain = searchDomain.split(':')[0]
if searchPort: if searchPort:
if debug:
print('DEBUG: Search for handle ' + print('DEBUG: Search for handle ' +
str(searchNickname) + '@' + str(searchDomain) + ':' + str(searchNickname) + '@' + str(searchDomain) + ':' +
str(searchPort)) str(searchPort))
else: else:
if debug:
print('DEBUG: Search for handle ' + print('DEBUG: Search for handle ' +
str(searchNickname) + '@' + str(searchDomain)) str(searchNickname) + '@' + str(searchDomain))
if not searchNickname: if not searchNickname:
if debug:
print('DEBUG: No nickname found in ' + profileHandle) print('DEBUG: No nickname found in ' + profileHandle)
return None return None
if not searchDomain: if not searchDomain:
if debug:
print('DEBUG: No domain found in ' + profileHandle) print('DEBUG: No domain found in ' + profileHandle)
return None return None
@ -115,8 +121,9 @@ def htmlProfileAfterSearch(cssCache: {},
webfingerHandle(session, webfingerHandle(session,
searchNickname + '@' + searchDomainFull, searchNickname + '@' + searchDomainFull,
httpPrefix, cachedWebfingers, httpPrefix, cachedWebfingers,
domain, projectVersion) domain, projectVersion, debug)
if not wf: if not wf:
if debug:
print('DEBUG: Unable to webfinger ' + print('DEBUG: Unable to webfinger ' +
searchNickname + '@' + searchDomainFull) searchNickname + '@' + searchDomainFull)
print('DEBUG: cachedWebfingers ' + str(cachedWebfingers)) print('DEBUG: cachedWebfingers ' + str(cachedWebfingers))
@ -124,6 +131,7 @@ def htmlProfileAfterSearch(cssCache: {},
print('DEBUG: domain ' + domain) print('DEBUG: domain ' + domain)
return None return None
if not isinstance(wf, dict): if not isinstance(wf, dict):
if debug:
print('WARN: Webfinger search for ' + print('WARN: Webfinger search for ' +
searchNickname + '@' + searchDomainFull + searchNickname + '@' + searchDomainFull +
' did not return a dict. ' + ' did not return a dict. ' +
@ -140,7 +148,7 @@ def htmlProfileAfterSearch(cssCache: {},
'Accept': 'application/activity+json; profile="' + profileStr + '"' 'Accept': 'application/activity+json; profile="' + profileStr + '"'
} }
if not personUrl: if not personUrl:
personUrl = getUserUrl(wf) personUrl = getUserUrl(wf, 0, debug)
if not personUrl: if not personUrl:
# try single user instance # try single user instance
asHeader = { asHeader = {
@ -148,14 +156,14 @@ def htmlProfileAfterSearch(cssCache: {},
} }
personUrl = httpPrefix + '://' + searchDomainFull personUrl = httpPrefix + '://' + searchDomainFull
profileJson = \ profileJson = \
getJson(session, personUrl, asHeader, None, getJson(session, personUrl, asHeader, None, debug,
projectVersion, httpPrefix, domain) projectVersion, httpPrefix, domain)
if not profileJson: if not profileJson:
asHeader = { asHeader = {
'Accept': 'application/ld+json; profile="' + profileStr + '"' 'Accept': 'application/ld+json; profile="' + profileStr + '"'
} }
profileJson = \ profileJson = \
getJson(session, personUrl, asHeader, None, getJson(session, personUrl, asHeader, None, debug,
projectVersion, httpPrefix, domain) projectVersion, httpPrefix, domain)
if not profileJson: if not profileJson:
print('DEBUG: No actor returned from ' + personUrl) print('DEBUG: No actor returned from ' + personUrl)
@ -481,6 +489,7 @@ def htmlProfile(rssIconAtTop: bool,
peertubeInstances: [], peertubeInstances: [],
allowLocalNetworkAccess: bool, allowLocalNetworkAccess: bool,
textModeBanner: str, textModeBanner: str,
debug: bool,
extraJson=None, pageNumber=None, extraJson=None, pageNumber=None,
maxItemsPerPage=None) -> str: maxItemsPerPage=None) -> str:
"""Show the profile page as html """Show the profile page as html
@ -816,7 +825,7 @@ def htmlProfile(rssIconAtTop: bool,
cachedWebfingers, personCache, extraJson, cachedWebfingers, personCache, extraJson,
projectVersion, ["unfollow"], selected, projectVersion, ["unfollow"], selected,
usersPath, pageNumber, maxItemsPerPage, usersPath, pageNumber, maxItemsPerPage,
dormantMonths) dormantMonths, debug)
elif selected == 'followers': elif selected == 'followers':
profileStr += \ profileStr += \
_htmlProfileFollowing(translate, baseDir, httpPrefix, _htmlProfileFollowing(translate, baseDir, httpPrefix,
@ -825,7 +834,7 @@ def htmlProfile(rssIconAtTop: bool,
cachedWebfingers, personCache, extraJson, cachedWebfingers, personCache, extraJson,
projectVersion, ["block"], projectVersion, ["block"],
selected, usersPath, pageNumber, selected, usersPath, pageNumber,
maxItemsPerPage, dormantMonths) maxItemsPerPage, dormantMonths, debug)
elif selected == 'roles': elif selected == 'roles':
profileStr += \ profileStr += \
_htmlProfileRoles(translate, nickname, domainFull, _htmlProfileRoles(translate, nickname, domainFull,
@ -920,7 +929,7 @@ def _htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
feedName: str, actor: str, feedName: str, actor: str,
pageNumber: int, pageNumber: int,
maxItemsPerPage: int, maxItemsPerPage: int,
dormantMonths: int) -> str: dormantMonths: int, debug: bool) -> str:
"""Shows following on the profile screen """Shows following on the profile screen
""" """
profileStr = '' profileStr = ''
@ -952,7 +961,7 @@ def _htmlProfileFollowing(translate: {}, baseDir: str, httpPrefix: str,
domain, followingActor, domain, followingActor,
authorized, nickname, authorized, nickname,
httpPrefix, projectVersion, dormant, httpPrefix, projectVersion, dormant,
buttons) debug, buttons)
if authorized and maxItemsPerPage and pageNumber: if authorized and maxItemsPerPage and pageNumber:
if len(followingJson['orderedItems']) >= maxItemsPerPage: if len(followingJson['orderedItems']) >= maxItemsPerPage:
@ -1801,6 +1810,7 @@ def _individualFollowAsHtml(translate: {},
httpPrefix: str, httpPrefix: str,
projectVersion: str, projectVersion: str,
dormant: bool, dormant: bool,
debug: bool,
buttons=[]) -> str: buttons=[]) -> str:
"""An individual follow entry on the profile screen """An individual follow entry on the profile screen
""" """
@ -1817,7 +1827,7 @@ def _individualFollowAsHtml(translate: {},
followUrlWf = \ followUrlWf = \
webfingerHandle(session, followUrlHandle, httpPrefix, webfingerHandle(session, followUrlHandle, httpPrefix,
cachedWebfingers, cachedWebfingers,
domain, __version__) domain, __version__, debug)
(inboxUrl, pubKeyId, pubKey, (inboxUrl, pubKeyId, pubKey,
fromPersonId, sharedInbox, fromPersonId, sharedInbox,

View File

@ -441,7 +441,7 @@ def setBlogAddress(actorJson: {}, blogAddress: str) -> None:
def updateAvatarImageCache(session, baseDir: str, httpPrefix: str, def updateAvatarImageCache(session, baseDir: str, httpPrefix: str,
actor: str, avatarUrl: str, actor: str, avatarUrl: str,
personCache: {}, allowDownloads: bool, personCache: {}, allowDownloads: bool,
force=False) -> str: force=False, debug=False) -> str:
"""Updates the cached avatar for the given actor """Updates the cached avatar for the given actor
""" """
if not avatarUrl: if not avatarUrl:
@ -502,8 +502,8 @@ def updateAvatarImageCache(session, baseDir: str, httpPrefix: str,
'Accept': 'application/ld+json; profile="' + prof + '"' 'Accept': 'application/ld+json; profile="' + prof + '"'
} }
personJson = \ personJson = \
getJson(session, actor, sessionHeaders, None, __version__, getJson(session, actor, sessionHeaders, None,
httpPrefix, None) debug, __version__, httpPrefix, None)
if personJson: if personJson:
if not personJson.get('id'): if not personJson.get('id'):
return None return None

View File

@ -40,10 +40,12 @@ def _parseHandle(handle: str) -> (str, str):
def webfingerHandle(session, handle: str, httpPrefix: str, def webfingerHandle(session, handle: str, httpPrefix: str,
cachedWebfingers: {}, cachedWebfingers: {},
fromDomain: str, projectVersion: str) -> {}: fromDomain: str, projectVersion: str,
debug: bool) -> {}:
"""Gets webfinger result for the given ActivityPub handle """Gets webfinger result for the given ActivityPub handle
""" """
if not session: if not session:
if debug:
print('WARN: No session specified for webfingerHandle') print('WARN: No session specified for webfingerHandle')
return None return None
@ -60,6 +62,7 @@ def webfingerHandle(session, handle: str, httpPrefix: str,
wf = getWebfingerFromCache(nickname + '@' + wfDomain, wf = getWebfingerFromCache(nickname + '@' + wfDomain,
cachedWebfingers) cachedWebfingers)
if wf: if wf:
if debug:
print('Webfinger from cache: ' + str(wf)) print('Webfinger from cache: ' + str(wf))
return wf return wf
url = '{}://{}/.well-known/webfinger'.format(httpPrefix, domain) url = '{}://{}/.well-known/webfinger'.format(httpPrefix, domain)
@ -71,7 +74,8 @@ def webfingerHandle(session, handle: str, httpPrefix: str,
} }
try: try:
result = \ result = \
getJson(session, url, hdr, par, projectVersion, getJson(session, url, hdr, par,
debug, projectVersion,
httpPrefix, fromDomain) httpPrefix, fromDomain)
except Exception as e: except Exception as e:
print(e) print(e)
@ -81,6 +85,7 @@ def webfingerHandle(session, handle: str, httpPrefix: str,
storeWebfingerInCache(nickname + '@' + wfDomain, storeWebfingerInCache(nickname + '@' + wfDomain,
result, cachedWebfingers) result, cachedWebfingers)
else: else:
if debug:
print("WARN: Unable to webfinger " + url + ' ' + print("WARN: Unable to webfinger " + url + ' ' +
'nickname: ' + str(nickname) + ' ' + 'nickname: ' + str(nickname) + ' ' +
'domain: ' + str(wfDomain) + ' ' + 'domain: ' + str(wfDomain) + ' ' +