Bob Mottram 7 months ago
parent
commit
d0884fa04d
46 changed files with 1288 additions and 1124 deletions
  1. 8 8
      acceptreject.py
  2. 30 28
      announce.py
  3. 22 22
      auth.py
  4. 20 17
      availability.py
  5. 28 23
      blocking.py
  6. 12 12
      blog.py
  7. 66 59
      blurhash.py
  8. 31 27
      bookmarks.py
  9. 7 7
      cache.py
  10. 10 10
      capabilities.py
  11. 8 8
      config.py
  12. 12 11
      content.py
  13. 69 69
      daemon.py
  14. 25 22
      delete.py
  15. 7 7
      donate.py
  16. 50 38
      epicyon.py
  17. 7 7
      filters.py
  18. 51 43
      follow.py
  19. 8 8
      happening.py
  20. 37 28
      httpsig.py
  21. 19 19
      inbox.py
  22. 31 26
      like.py
  23. 9 9
      manualapprove.py
  24. 7 7
      matrix.py
  25. 7 7
      media.py
  26. 29 28
      metadata.py
  27. 7 7
      migrate.py
  28. 7 7
      outbox.py
  29. 85 77
      person.py
  30. 7 7
      pgp.py
  31. 143 118
      posts.py
  32. 9 9
      question.py
  33. 26 21
      roles.py
  34. 8 8
      schedule.py
  35. 16 15
      session.py
  36. 43 35
      shares.py
  37. 19 17
      skills.py
  38. 7 7
      ssb.py
  39. 81 56
      tests.py
  40. 7 7
      theme.py
  41. 14 14
      threads.py
  42. 7 7
      tox.py
  43. 23 19
      utils.py
  44. 27 23
      webfinger.py
  45. 135 113
      webinterface.py
  46. 7 7
      xmpp.py

+ 8 - 8
acceptreject.py

@@ -1,10 +1,10 @@
-__filename__ = "acceptreject.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="acceptreject.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import json
@@ -39,7 +39,7 @@ def createAcceptReject(baseDir: str,federationList: [], \
             if ':' not in domain:
                 domain=domain+':'+str(port)
 
-    newAccept = {
+    newAccept={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': acceptType,
         'actor': httpPrefix+'://'+domain+'/users/'+nickname,

+ 30 - 28
announce.py

@@ -1,10 +1,10 @@
-__filename__ = "announce.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="announce.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import time
@@ -162,7 +162,7 @@ def updateAnnounceCollection(recentPostsCache: {}, \
             if debug:
                 print('DEBUG: Adding initial shares (announcements) to '+ \
                       postUrl)
-            announcementsJson = {
+            announcementsJson={
                 "@context": "https://www.w3.org/ns/activitystreams",
                 'id': postUrl,
                 'type': 'Collection',
@@ -236,10 +236,10 @@ def createAnnounce(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fullDomain=domain+':'+str(port)
 
-    statusNumber,published = getStatusNumber()
+    statusNumber,published=getStatusNumber()
     newAnnounceId= \
         httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber
-    newAnnounce = {
+    newAnnounce={
         "@context": "https://www.w3.org/ns/activitystreams",
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
         'atomUri': httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber,
@@ -254,7 +254,7 @@ def createAnnounce(session,baseDir: str,federationList: [], \
         if len(ccUrl)>0:
             newAnnounce['cc']=[ccUrl]
     if saveToFile:
-        outboxDir = createOutboxDir(nickname,domain,baseDir)
+        outboxDir=createOutboxDir(nickname,domain,baseDir)
         filename=outboxDir+'/'+newAnnounceId.replace('/','#')+'.json'
         saveJson(newAnnounce,filename)
 
@@ -291,8 +291,8 @@ def announcePublic(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fromDomain=domain+':'+str(port)
 
-    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
-    ccUrl = httpPrefix + '://'+fromDomain+'/users/'+nickname+'/followers'
+    toUrl='https://www.w3.org/ns/activitystreams#Public'
+    ccUrl=httpPrefix+'://'+fromDomain+'/users/'+nickname+'/followers'
     return createAnnounce(session,baseDir,federationList, \
                           nickname,domain,port, \
                           toUrl,ccUrl,httpPrefix, \
@@ -317,7 +317,7 @@ def repeatPost(session,baseDir: str,federationList: [], \
             if ':' not in announcedDomain:
                 announcedDomain=announcedDomain+':'+str(announcePort)
 
-    objectUrl = announceHttpsPrefix + '://'+announcedDomain+'/users/'+ \
+    objectUrl=announceHttpsPrefix+'://'+announcedDomain+'/users/'+ \
         announceNickname+'/statuses/'+str(announceStatusNumber)
 
     return announcePublic(session,baseDir,federationList, \
@@ -352,7 +352,7 @@ def undoAnnounce(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fullDomain=domain+':'+str(port)
 
-    newUndoAnnounce = {
+    newUndoAnnounce={
         "@context": "https://www.w3.org/ns/activitystreams",
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
         'type': 'Undo',
@@ -403,8 +403,8 @@ def undoAnnouncePublic(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fromDomain=domain+':'+str(port)
 
-    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
-    ccUrl = httpPrefix + '://'+fromDomain+'/users/'+nickname+'/followers'
+    toUrl='https://www.w3.org/ns/activitystreams#Public'
+    ccUrl=httpPrefix+'://'+fromDomain+'/users/'+nickname+'/followers'
     return undoAnnounce(session,baseDir,federationList, \
                         nickname,domain,port, \
                         toUrl,ccUrl,httpPrefix, \
@@ -429,7 +429,7 @@ def undoRepeatPost(session,baseDir: str,federationList: [], \
             if ':' not in announcedDomain:
                 announcedDomain=announcedDomain+':'+str(announcePort)
 
-    objectUrl = announceHttpsPrefix + '://'+announcedDomain+'/users/'+ \
+    objectUrl=announceHttpsPrefix+'://'+announcedDomain+'/users/'+ \
         announceNickname+'/statuses/'+str(announceStatusNumber)
 
     return undoAnnouncePublic(session,baseDir,federationList, \
@@ -459,14 +459,14 @@ def sendAnnounceViaServer(baseDir: str,session, \
             if ':' not in fromDomain:
                 fromDomainFull=fromDomain+':'+str(fromPort)
 
-    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
-    ccUrl = httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
+    toUrl='https://www.w3.org/ns/activitystreams#Public'
+    ccUrl=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/followers'
 
-    statusNumber,published = getStatusNumber()
+    statusNumber,published=getStatusNumber()
     newAnnounceId= \
         httpPrefix+'://'+fromDomainFull+'/users/'+ \
         fromNickname+'/statuses/'+statusNumber
-    newAnnounceJson = {
+    newAnnounceJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
         'atomUri': newAnnounceId,
@@ -481,7 +481,7 @@ def sendAnnounceViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = \
+    wfRequest= \
         webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
                         fromDomain,projectVersion)
     if not wfRequest:
@@ -492,7 +492,7 @@ def sendAnnounceViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname,fromDomain,postToBox)
                      
@@ -507,10 +507,12 @@ def sendAnnounceViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newAnnounceJson,[],inboxUrl,headers,"inbox:write")
 
     if debug:

+ 22 - 22
auth.py

@@ -1,10 +1,10 @@
-__filename__ = "auth.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="auth.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import base64
 import hashlib
@@ -16,24 +16,24 @@ import random
 def hashPassword(password: str) -> str:
     """Hash a password for storing
     """
-    salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
-    pwdhash = hashlib.pbkdf2_hmac('sha512', \
+    salt=hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
+    pwdhash=hashlib.pbkdf2_hmac('sha512', \
                                   password.encode('utf-8'), \
                                   salt, 100000)
-    pwdhash = binascii.hexlify(pwdhash)
-    return (salt + pwdhash).decode('ascii')
+    pwdhash=binascii.hexlify(pwdhash)
+    return (salt+pwdhash).decode('ascii')
  
 def verifyPassword(storedPassword: str,providedPassword: str) -> bool:
     """Verify a stored password against one provided by user
     """
-    salt = storedPassword[:64]
-    storedPassword = storedPassword[64:]
-    pwdhash = hashlib.pbkdf2_hmac('sha512', \
+    salt=storedPassword[:64]
+    storedPassword=storedPassword[64:]
+    pwdhash=hashlib.pbkdf2_hmac('sha512', \
                                   providedPassword.encode('utf-8'), \
                                   salt.encode('ascii'), \
                                   100000)
-    pwdhash = binascii.hexlify(pwdhash).decode('ascii')
-    return pwdhash == storedPassword
+    pwdhash=binascii.hexlify(pwdhash).decode('ascii')
+    return pwdhash==storedPassword
 
 def createBasicAuthHeader(nickname: str,password: str) -> str:
     """This is only used by tests
@@ -60,13 +60,13 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
             print('DEBUG: This is not a users endpoint')
         return False
     nicknameFromPath=pathUsersSection.split('/')[0]
-    base64Str = authHeader.split(' ')[1].replace('\n','')
-    plain = base64.b64decode(base64Str).decode('utf-8')
+    base64Str=authHeader.split(' ')[1].replace('\n','')
+    plain=base64.b64decode(base64Str).decode('utf-8')
     if ':' not in plain:
         if debug:
             print('DEBUG: Basic Auth header does not contain a ":" separator for username:password')
         return False
-    nickname = plain.split(':')[0]
+    nickname=plain.split(':')[0]
     if nickname!=nicknameFromPath:
         if debug:
             print('DEBUG: Nickname given in the path ('+nicknameFromPath+ \
@@ -78,12 +78,12 @@ def authorizeBasic(baseDir: str,path: str,authHeader: str,debug: bool) -> bool:
         if debug:
             print('DEBUG: passwords file missing')
         return False
-    providedPassword = plain.split(':')[1]
-    passfile = open(passwordFile, "r")
+    providedPassword=plain.split(':')[1]
+    passfile=open(passwordFile, "r")
     for line in passfile:
         if line.startswith(nickname+':'):
             storedPassword=line.split(':')[1].replace('\n','')
-            success = verifyPassword(storedPassword,providedPassword)
+            success=verifyPassword(storedPassword,providedPassword)
             if not success:
                 if debug:
                     print('DEBUG: Password check failed for '+nickname)

+ 20 - 17
availability.py

@@ -1,10 +1,10 @@
-__filename__ = "availability.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="availability.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 import time
@@ -89,10 +89,10 @@ def sendAvailabilityViaServer(baseDir: str,session, \
             if ':' not in domain:
                 domainFull=domain+':'+str(port)
         
-    toUrl = httpPrefix+'://'+domainFull+'/users/'+nickname
-    ccUrl = httpPrefix+'://'+domainFull+'/users/'+nickname+'/followers'
+    toUrl=httpPrefix+'://'+domainFull+'/users/'+nickname
+    ccUrl=httpPrefix+'://'+domainFull+'/users/'+nickname+'/followers'
 
-    newAvailabilityJson = {
+    newAvailabilityJson={
         'type': 'Availability',
         'actor': httpPrefix+'://'+domainFull+'/users/'+nickname,
         'object': '"'+status+'"',
@@ -103,8 +103,9 @@ def sendAvailabilityViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+domainFull+'/@'+nickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                domain,projectVersion)
+    wfRequest= \
+        webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                        domain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -113,7 +114,7 @@ def sendAvailabilityViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,nickname,domain,postToBox)
                      
@@ -128,10 +129,12 @@ def sendAvailabilityViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(Nickname,password)
      
-    headers = {'host': domain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': domain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newAvailabilityJson,[],inboxUrl,headers,"inbox:write")
 
     if debug:

+ 28 - 23
blocking.py

@@ -1,10 +1,10 @@
-__filename__ = "blocking.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="blocking.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 from utils import isEvil
@@ -174,10 +174,10 @@ def sendBlockViaServer(baseDir: str,session, \
 
     toUrl= 'https://www.w3.org/ns/activitystreams#Public'
     ccUrl= \
-        httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
+        httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/followers'
 
     blockActor=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname
-    newBlockJson = {
+    newBlockJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Block',
         'actor': blockActor,
@@ -189,8 +189,9 @@ def sendBlockViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                fromDomain,projectVersion)
+    wfRequest= \
+        webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                        fromDomain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -199,7 +200,7 @@ def sendBlockViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -215,10 +216,12 @@ def sendBlockViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newBlockJson,[],inboxUrl,headers,"inbox:write")
 
     if debug:
@@ -246,10 +249,10 @@ def sendUndoBlockViaServer(baseDir: str,session, \
 
     toUrl= 'https://www.w3.org/ns/activitystreams#Public'
     ccUrl= \
-        httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
+        httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/followers'
 
     blockActor=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname
-    newBlockJson = {
+    newBlockJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Undo',
         'actor': blockActor,
@@ -276,7 +279,7 @@ def sendUndoBlockViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -292,10 +295,12 @@ def sendUndoBlockViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newBlockJson,[],inboxUrl,headers,"inbox:write")
 
     if debug:

+ 12 - 12
blog.py

@@ -1,10 +1,10 @@
-__filename__ = "blog.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="blog.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 import time
@@ -63,12 +63,12 @@ def noOfBlogReplies(baseDir: str,httpPrefix: str,translate: {}, \
 
     replies=0
     with open(postFilename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
         for replyPostId in lines:
             replyPostId= \
                 replyPostId.replace('\n','').replace('.json','').replace('.replies','')
             replies+= \
-                1 + \
+                1+ \
                 noOfBlogReplies(baseDir,httpPrefix,translate, \
                                 nickname,domain,domainFull, \
                                 replyPostId,depth+1)
@@ -111,7 +111,7 @@ def getBlogReplies(baseDir: str,httpPrefix: str,translate: {}, \
         return ''
 
     with open(postFilename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
         repliesStr=''
         for replyPostId in lines:
             replyPostId= \
@@ -556,13 +556,13 @@ def htmlEditBlog(mediaInstance: bool,translate: {}, \
 
     if os.path.isfile(baseDir+'/accounts/newpost.txt'):
         with open(baseDir+'/accounts/newpost.txt', 'r') as file:
-            editBlogText = '<p class="new-post-text">'+file.read()+'</p>'    
+            editBlogText='<p class="new-post-text">'+file.read()+'</p>'    
 
     cssFilename=baseDir+'/epicyon-profile.css'
     if os.path.isfile(baseDir+'/epicyon.css'):
         cssFilename=baseDir+'/epicyon.css'        
     with open(cssFilename, 'r') as cssFile:
-        editBlogCSS = cssFile.read()
+        editBlogCSS=cssFile.read()
         if httpPrefix!='https':
             editBlogCSS=editBlogCSS.replace('https://',httpPrefix+'://')
 

+ 66 - 59
blurhash.py

@@ -32,16 +32,16 @@ Very close port of the original Swift implementation by Dag Ågren.
 import math
 
 # Alphabet for base 83
-alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"
-alphabet_values = dict(zip(alphabet, range(len(alphabet))))
+alphabet="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz#$%*+,-.:;=?@[]^_{|}~"
+alphabet_values=dict(zip(alphabet,range(len(alphabet))))
 
 def base83_decode(base83_str):
     """
     Decodes a base83 string, as used in blurhash, to an integer.
     """
-    value = 0
+    value=0
     for base83_char in base83_str:
-        value = value * 83 + alphabet_values[base83_char]
+        value=value*83+alphabet_values[base83_char]
     return value
 
 def base83_encode(value, length):
@@ -54,9 +54,9 @@ def base83_encode(value, length):
     if int(value) // (83 ** (length)) != 0:
         raise ValueError("Specified length is too short to encode given value.")
         
-    result = ""
-    for i in range(1, length + 1):
-        digit = int(value) // (83 ** (length - i)) % 83
+    result=""
+    for i in range(1,length+1):
+        digit=int(value) // (83 ** (length - i)) % 83
         result += alphabet[int(digit)]
     return result
 
@@ -64,10 +64,10 @@ def srgb_to_linear(value):
     """
     srgb 0-255 integer to linear 0.0-1.0 floating point conversion.
     """
-    value = float(value) / 255.0
+    value=float(value) / 255.0
     if value <= 0.04045:
         return value / 12.92
-    return math.pow((value + 0.055) / 1.055, 2.4)
+    return math.pow((value+0.055) / 1.055, 2.4)
 
 def sign_pow(value, exp):
     """
@@ -79,10 +79,10 @@ def linear_to_srgb(value):
     """
     linear 0.0-1.0 floating point to srgb 0-255 integer conversion.
     """
-    value = max(0.0, min(1.0, value))
+    value=max(0.0, min(1.0, value))
     if value <= 0.0031308:
-        return int(value * 12.92 * 255 + 0.5)
-    return int((1.055 * math.pow(value, 1 / 2.4) - 0.055) * 255 + 0.5)
+        return int(value*12.92*255+0.5)
+    return int((1.055*math.pow(value, 1 / 2.4)-0.055)*255+0.5)
 
 def blurhash_components(blurhash):
     """
@@ -92,13 +92,13 @@ def blurhash_components(blurhash):
         raise ValueError("BlurHash must be at least 6 characters long.")
     
     # Decode metadata
-    size_info = base83_decode(blurhash[0])
-    size_y = int(size_info / 9) + 1
-    size_x = (size_info % 9) + 1
+    size_info=base83_decode(blurhash[0])
+    size_y=int(size_info / 9)+1
+    size_x=(size_info % 9)+1
     
     return size_x, size_y
 
-def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
+def blurhash_decode(blurhash,width,height,punch=1.0,linear=False):
     """
     Decodes the given blurhash to an image of the specified size.
     
@@ -117,20 +117,20 @@ def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
         raise ValueError("BlurHash must be at least 6 characters long.")
     
     # Decode metadata
-    size_info = base83_decode(blurhash[0])
-    size_y = int(size_info / 9) + 1
-    size_x = (size_info % 9) + 1
+    size_info=base83_decode(blurhash[0])
+    size_y=int(size_info / 9)+1
+    size_x=(size_info % 9)+1
     
-    quant_max_value = base83_decode(blurhash[1])
-    real_max_value = (float(quant_max_value + 1) / 166.0) * punch
+    quant_max_value=base83_decode(blurhash[1])
+    real_max_value=(float(quant_max_value+1)/166.0)*punch
     
     # Make sure we at least have the right number of characters
-    if len(blurhash) != 4 + 2 * size_x * size_y:
+    if len(blurhash) != 4+2*size_x*size_y:
         raise ValueError("Invalid BlurHash length.")
         
     # Decode DC component
-    dc_value = base83_decode(blurhash[2:6])
-    colours = [(
+    dc_value=base83_decode(blurhash[2:6])
+    colours=[(
         srgb_to_linear(dc_value >> 16),
         srgb_to_linear((dc_value >> 8) & 255),
         srgb_to_linear(dc_value & 255)
@@ -138,7 +138,7 @@ def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
     
     # Decode AC components
     for component in range(1, size_x * size_y):
-        ac_value = base83_decode(blurhash[4+component*2:4+(component+1)*2])
+        ac_value=base83_decode(blurhash[4+component*2:4+(component+1)*2])
         colours.append((
             sign_pow((float(int(ac_value / (19 * 19))) - 9.0) / 9.0, 2.0) * real_max_value,
             sign_pow((float(int(ac_value / 19) % 19) - 9.0) / 9.0, 2.0) * real_max_value,
@@ -147,20 +147,21 @@ def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
     
     # Return image RGB values, as a list of lists of lists, 
     # consumable by something like numpy or PIL.
-    pixels = []
+    pixels=[]
     for y in range(height):
-        pixel_row = []
+        pixel_row=[]
         for x in range(width):
-            pixel = [0.0, 0.0, 0.0]
+            pixel=[0.0, 0.0, 0.0]
 
             for j in range(size_y):
                 for i in range(size_x):
-                    basis = math.cos(math.pi * float(x) * float(i) / float(width)) * \
-                            math.cos(math.pi * float(y) * float(j) / float(height))
-                    colour = colours[i + j * size_x]
-                    pixel[0] += colour[0] * basis
-                    pixel[1] += colour[1] * basis
-                    pixel[2] += colour[2] * basis
+                    basis= \
+                        math.cos(math.pi*float(x)*float(i)/float(width))* \
+                        math.cos(math.pi*float(y)*float(j)/float(height))
+                    colour=colours[i+j*size_x]
+                    pixel[0] += colour[0]*basis
+                    pixel[1] += colour[1]*basis
+                    pixel[2] += colour[2]*basis
             if linear == False:
                 pixel_row.append([
                     linear_to_srgb(pixel[0]),
@@ -172,7 +173,7 @@ def blurhash_decode(blurhash, width, height, punch = 1.0, linear = False):
         pixels.append(pixel_row)
     return pixels
     
-def blurhash_encode(image, components_x = 4, components_y = 4, linear = False):
+def blurhash_encode(image,components_x=4,components_y=4,linear=False):
     """
     Calculates the blurhash for an image using the given x and y component counts.
     
@@ -186,14 +187,14 @@ def blurhash_encode(image, components_x = 4, components_y = 4, linear = False):
     """
     if components_x < 1 or components_x > 9 or components_y < 1 or components_y > 9: 
         raise ValueError("x and y component counts must be between 1 and 9 inclusive.")
-    height = float(len(image))
-    width = float(len(image[0]))
+    height=float(len(image))
+    width=float(len(image[0]))
     
     # Convert to linear if neeeded
-    image_linear = []
-    if linear == False:
+    image_linear=[]
+    if linear==False:
         for y in range(int(height)):
-            image_linear_line = []
+            image_linear_line=[]
             for x in range(int(width)):
                 image_linear_line.append([
                     srgb_to_linear(image[y][x][0]),
@@ -202,19 +203,20 @@ def blurhash_encode(image, components_x = 4, components_y = 4, linear = False):
                 ])
             image_linear.append(image_linear_line)
     else:
-        image_linear = image
+        image_linear=image
         
     # Calculate components
-    components = []
-    max_ac_component = 0.0
+    components=[]
+    max_ac_component=0.0
     for j in range(components_y):
         for i in range(components_x):
-            norm_factor = 1.0 if (i == 0 and j == 0) else 2.0
-            component = [0.0, 0.0, 0.0]
+            norm_factor=1.0 if (i==0 and j==0) else 2.0
+            component=[0.0,0.0,0.0]
             for y in range(int(height)):
                 for x in range(int(width)):
-                    basis = norm_factor * math.cos(math.pi * float(i) * float(x) / width) * \
-                                          math.cos(math.pi * float(j) * float(y) / height)
+                    basis= \
+                        norm_factor * math.cos(math.pi * float(i) * float(x) / width) * \
+                        math.cos(math.pi * float(j) * float(y) / height)
                     component[0] += basis * image_linear[y][x][0]
                     component[1] += basis * image_linear[y][x][1]
                     component[2] += basis * image_linear[y][x][2]
@@ -224,27 +226,32 @@ def blurhash_encode(image, components_x = 4, components_y = 4, linear = False):
             component[2] /= (width * height)
             components.append(component)
             
-            if not (i == 0 and j == 0):
-                max_ac_component = max(max_ac_component, abs(component[0]), abs(component[1]), abs(component[2]))
+            if not (i==0 and j==0):
+                max_ac_component= \
+                    max(max_ac_component,abs(component[0]), \
+                        abs(component[1]),abs(component[2]))
                 
     # Encode components
-    dc_value = (linear_to_srgb(components[0][0]) << 16) + \
-               (linear_to_srgb(components[0][1]) << 8) + \
-               linear_to_srgb(components[0][2])
+    dc_value= \
+        (linear_to_srgb(components[0][0]) << 16)+ \
+        (linear_to_srgb(components[0][1]) << 8)+ \
+        linear_to_srgb(components[0][2])
     
-    quant_max_ac_component = int(max(0, min(82, math.floor(max_ac_component * 166 - 0.5))))
-    ac_component_norm_factor = float(quant_max_ac_component + 1) / 166.0
+    quant_max_ac_component= \
+        int(max(0, min(82, math.floor(max_ac_component * 166 - 0.5))))
+    ac_component_norm_factor= \
+        float(quant_max_ac_component+1) / 166.0
     
-    ac_values = []
+    ac_values=[]
     for r, g, b in components[1:]:
         ac_values.append(
-            int(max(0.0, min(18.0, math.floor(sign_pow(r / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 * 19 + \
-            int(max(0.0, min(18.0, math.floor(sign_pow(g / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 + \
-            int(max(0.0, min(18.0, math.floor(sign_pow(b / ac_component_norm_factor, 0.5) * 9.0 + 9.5))))
+            int(max(0.0,min(18.0,math.floor(sign_pow(r / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 * 19 + \
+            int(max(0.0,min(18.0, math.floor(sign_pow(g / ac_component_norm_factor, 0.5) * 9.0 + 9.5)))) * 19 + \
+            int(max(0.0,min(18.0, math.floor(sign_pow(b / ac_component_norm_factor, 0.5) * 9.0 + 9.5))))
         )
         
     # Build final blurhash
-    blurhash = ""
+    blurhash=""
     blurhash += base83_encode((components_x - 1) + (components_y - 1) * 9, 1)
     blurhash += base83_encode(quant_max_ac_component, 1)
     blurhash += base83_encode(dc_value, 4)

+ 31 - 27
bookmarks.py

@@ -1,10 +1,10 @@
-__filename__ = "bookmarks.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="bookmarks.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import json
@@ -159,7 +159,7 @@ def updateBookmarksCollection(recentPostsCache: {}, \
         if not postJsonObject['object'].get('bookmarks'):
             if debug:
                 print('DEBUG: Adding initial bookmarks to '+objectUrl)
-            bookmarksJson = {
+            bookmarksJson={
                 "@context": "https://www.w3.org/ns/activitystreams",
                 'id': objectUrl,
                 'type': 'Collection',
@@ -198,7 +198,7 @@ def updateBookmarksCollection(recentPostsCache: {}, \
             if bookmarkIndex not in open(bookmarksIndexFilename).read():
                 try:
                     with open(bookmarksIndexFilename, 'r+') as bookmarksIndexFile:
-                        content = bookmarksIndexFile.read()
+                        content=bookmarksIndexFile.read()
                         bookmarksIndexFile.seek(0, 0)
                         bookmarksIndexFile.write(bookmarkIndex+'\n'+content)
                         if debug:
@@ -239,7 +239,7 @@ def bookmark(recentPostsCache: {}, \
     if '/statuses/' in objectUrl:
         bookmarkTo=[objectUrl.split('/statuses/')[0]]
 
-    newBookmarkJson = {
+    newBookmarkJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Bookmark',
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
@@ -348,7 +348,7 @@ def undoBookmark(recentPostsCache: {}, \
     if '/statuses/' in objectUrl:
         bookmarkTo=[objectUrl.split('/statuses/')[0]]
 
-    newUndoBookmarkJson = {
+    newUndoBookmarkJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Undo',
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
@@ -414,8 +414,8 @@ def undoBookmarkPost(session,baseDir: str,federationList: [], \
             if ':' not in bookmarkedomain:
                 bookmarkedomain=bookmarkedomain+':'+str(bookmarkPort)
 
-    objectUrl = \
-        httpPrefix + '://'+bookmarkedomain+'/users/'+bookmarkNickname+ \
+    objectUrl= \
+        httpPrefix+'://'+bookmarkedomain+'/users/'+bookmarkNickname+ \
         '/statuses/'+str(bookmarkStatusNumber)
 
     ccUrl=httpPrefix+'://'+bookmarkedomain+'/users/'+bookmarkNickname
@@ -454,7 +454,7 @@ def sendBookmarkViaServer(baseDir: str,session, \
     if '/statuses/' in bookmarkUrl:
         toUrl=[bookmarkUrl.split('/statuses/')[0]]
         
-    newBookmarkJson = {
+    newBookmarkJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Bookmark',
         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
@@ -474,7 +474,7 @@ def sendBookmarkViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -490,10 +490,12 @@ def sendBookmarkViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
     
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newBookmarkJson,[],inboxUrl,headers,"inbox:write")
     #if not postResult:
     #    if debug:
@@ -529,7 +531,7 @@ def sendUndoBookmarkViaServer(baseDir: str,session, \
     if '/statuses/' in bookmarkUrl:
         toUrl=[bookmarkUrl.split('/statuses/')[0]]
 
-    newUndoBookmarkJson = {
+    newUndoBookmarkJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Undo',
         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
@@ -543,8 +545,8 @@ def sendUndoBookmarkViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                fromDomain,projectVersion)
+    wfRequest=webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                              fromDomain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -553,7 +555,7 @@ def sendUndoBookmarkViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -569,10 +571,12 @@ def sendUndoBookmarkViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
     
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newUndoBookmarkJson,[],inboxUrl,headers,"inbox:write")
     #if not postResult:
     #    if debug:

+ 7 - 7
cache.py

@@ -1,10 +1,10 @@
-__filename__ = "cache.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="cache.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import time

+ 10 - 10
capabilities.py

@@ -1,10 +1,10 @@
-__filename__ = "capabilities.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="capabilities.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import datetime
@@ -94,7 +94,7 @@ def capabilitiesRequest(baseDir: str,httpPrefix: str,domain: str, \
     # which could be instance wide or for a particular person
     # This could also be added to a follow activity
     ocapId=createPassword(32)
-    ocapRequest = {
+    ocapRequest={
         "@context": "https://www.w3.org/ns/activitystreams",
         "id": httpPrefix+"://"+requestedDomain+"/caps/request/"+ocapId,
         "type": "Request",
@@ -140,7 +140,7 @@ def capabilitiesAccept(baseDir: str,httpPrefix: str, \
             ocapId=acceptedActorNickname+'@'+acceptedActorDomain+':'+str(acceptedActorPort)+'#'+createPassword(32)
         else:
             ocapId=acceptedActorNickname+'@'+acceptedActorDomain+'#'+createPassword(32)
-        ocapAccept = {
+        ocapAccept={
             "@context": "https://www.w3.org/ns/activitystreams",
             "id": httpPrefix+"://"+fullDomain+"/caps/"+ocapId,
             "type": "Capability",
@@ -196,7 +196,7 @@ def capabilitiesUpdate(baseDir: str,httpPrefix: str, \
         return None
 
     # create an update activity
-    ocapUpdate = {
+    ocapUpdate={
         "@context": "https://www.w3.org/ns/activitystreams",
         'type': 'Update',
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,

+ 8 - 8
config.py

@@ -1,10 +1,10 @@
-__filename__ = "config.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="config.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import time
@@ -18,7 +18,7 @@ def createConfig(baseDir: str) -> None:
     configFilename=baseDir+'/config.json'
     if os.path.isfile(configFilename):
         return
-    configJson = {
+    configJson={
     }
     saveJson(configJson,configFilename)
 

+ 12 - 11
content.py

@@ -1,10 +1,10 @@
-__filename__ = "content.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="content.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import time
@@ -158,7 +158,8 @@ def addWebLinks(content: str) -> str:
 def validHashTag(hashtag: str) -> bool:
     """Returns true if the give hashtag contains valid characters
     """
-    validChars = set('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
+    validChars= \
+        set('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ')
     if set(hashtag).issubset(validChars):
         return True
     return False
@@ -417,7 +418,7 @@ def addHtmlTags(baseDir: str,httpPrefix: str, \
     if '@' in words:
         if os.path.isfile(followingFilename):
             with open(followingFilename, "r") as f:
-                following = f.readlines()
+                following=f.readlines()
 
     # extract mentions and tags from words
     longWordsList=[]
@@ -569,7 +570,7 @@ def saveMediaInFormPOST(mediaBytes,debug: bool, \
         if os.path.isfile(possibleOtherFormat):
             os.remove(possibleOtherFormat)
 
-    fd = open(filename, 'wb')
+    fd=open(filename, 'wb')
     fd.write(mediaBytes[startPos:])
     fd.close()
 
@@ -579,7 +580,7 @@ def extractTextFieldsInPOST(postBytes,boundary,debug: bool) -> {}:
     """Returns a dictionary containing the text fields of a http form POST
     The boundary argument comes from the http header
     """    
-    msg = email.parser.BytesParser().parsebytes(postBytes)
+    msg=email.parser.BytesParser().parsebytes(postBytes)
     if debug:
         print('DEBUG: POST arriving '+msg.get_payload(decode=True).decode('utf-8'))
     messageFields=msg.get_payload(decode=True).decode('utf-8').split(boundary)

+ 69 - 69
daemon.py

@@ -1,10 +1,10 @@
-__filename__ = "daemon.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="daemon.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 from http.server import BaseHTTPRequestHandler,ThreadingHTTPServer
 #import socketserver
@@ -218,17 +218,17 @@ def readFollowList(filename: str) -> None:
     followlist=[]
     if not os.path.isfile(filename):
         return followlist
-    followUsers = open(filename, "r")    
+    followUsers=open(filename, "r")    
     for u in followUsers:
         if u not in followlist:
-            nickname,domain = parseHandle(u)
+            nickname,domain=parseHandle(u)
             if nickname:
                 followlist.append(nickname+'@'+domain)
     followUsers.close()
     return followlist
 
 class PubServer(BaseHTTPRequestHandler):
-    protocol_version = 'HTTP/1.1'        
+    protocol_version='HTTP/1.1'        
 
     def _sendReplyToQuestion(self,nickname: str,messageId: str,answer: str) -> None:
         """Sends a reply to a question
@@ -451,7 +451,7 @@ class PubServer(BaseHTTPRequestHandler):
         if os.path.isfile(mediaFilename+'.etag'):
             try:
                 with open(mediaFilename+'.etag', 'r') as etagFile:
-                    etag = etagFile.read()
+                    etag=etagFile.read()
             except:
                 pass
         if not etag:
@@ -771,7 +771,7 @@ class PubServer(BaseHTTPRequestHandler):
 
         beginSaveTime=time.time()
         # save the json for later queue processing
-        queueFilename = \
+        queueFilename= \
             savePostToInboxQueue(self.server.baseDir,
                                  self.server.httpPrefix,
                                  nickname,
@@ -962,7 +962,7 @@ class PubServer(BaseHTTPRequestHandler):
         self._benchmarkGETtimings(GETstartTime,GETtimings,4)
 
         # check authorization
-        authorized = self._isAuthorized()
+        authorized=self._isAuthorized()
         if self.server.debug:
             if authorized:
                 print('GET Authorization granted')
@@ -1270,7 +1270,7 @@ class PubServer(BaseHTTPRequestHandler):
                 while tries<5:
                     try:
                         with open('epicyon-profile.css', 'r') as cssfile:
-                            css = cssfile.read()
+                            css=cssfile.read()
                             break
                     except Exception as e:
                         print(e)
@@ -1299,7 +1299,7 @@ class PubServer(BaseHTTPRequestHandler):
                 while tries<5:
                     try:
                         with open(mediaFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             break
                     except Exception as e:
                         print(e)
@@ -1324,7 +1324,7 @@ class PubServer(BaseHTTPRequestHandler):
                 while tries<5:
                     try:
                         with open(mediaFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             break
                     except Exception as e:
                         print(e)
@@ -1349,7 +1349,7 @@ class PubServer(BaseHTTPRequestHandler):
                 while tries<5:
                     try:
                         with open(mediaFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             break
                     except Exception as e:
                         print(e)
@@ -1383,7 +1383,7 @@ class PubServer(BaseHTTPRequestHandler):
                     else:
                         mediaImageType='gif'                        
                     with open(emojiFilename, 'rb') as avFile:
-                        mediaBinary = avFile.read()
+                        mediaBinary=avFile.read()
                         self._set_headers('image/'+mediaImageType,len(mediaBinary),cookie)
                         self._write(mediaBinary)
                     return
@@ -1439,7 +1439,7 @@ class PubServer(BaseHTTPRequestHandler):
                             currEtag=''
                             try:
                                 with open(mediaFilename, 'r') as etagFile:
-                                    currEtag = etagFile.read()
+                                    currEtag=etagFile.read()
                             except:
                                 pass
                             if oldEtag==currEtag:
@@ -1447,7 +1447,7 @@ class PubServer(BaseHTTPRequestHandler):
                                 self._304()
                                 return
                     with open(mediaFilename, 'rb') as avFile:
-                        mediaBinary = avFile.read()
+                        mediaBinary=avFile.read()
                         self._set_headers_etag(mediaFilename,mediaFileType,mediaBinary,cookie)
                         self._write(mediaBinary)
                     return        
@@ -1477,7 +1477,7 @@ class PubServer(BaseHTTPRequestHandler):
                     else:
                         mediaFileType='gif'
                     with open(mediaFilename, 'rb') as avFile:
-                        mediaBinary = avFile.read()
+                        mediaBinary=avFile.read()
                         self._set_headers('image/'+mediaFileType,len(mediaBinary),cookie)
                         self._write(mediaBinary)
                     return        
@@ -1501,7 +1501,7 @@ class PubServer(BaseHTTPRequestHandler):
                 else:
                     if os.path.isfile(mediaFilename):
                         with open(mediaFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             self._set_headers('image/png',len(mediaBinary),cookie)
                             self._write(mediaBinary)
                             self.server.iconsCache[mediaStr]=mediaBinary
@@ -1518,7 +1518,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.baseDir+'/cache/'+self.path
             if os.path.isfile(mediaFilename):
                 with open(mediaFilename, 'rb') as avFile:
-                    mediaBinary = avFile.read()
+                    mediaBinary=avFile.read()
                     if mediaFilename.endswith('.png'):
                         self._set_headers('image/png',len(mediaBinary),cookie)
                     elif mediaFilename.endswith('.jpg'):
@@ -1568,7 +1568,7 @@ class PubServer(BaseHTTPRequestHandler):
                         else:
                             mediaImageType='webp'
                         with open(avatarFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             self._set_headers('image/'+mediaImageType, \
                                               len(mediaBinary),cookie)
                             self._write(mediaBinary)
@@ -1861,7 +1861,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 '/users/'+self.postToNickname
             unRepeatToStr='https://www.w3.org/ns/activitystreams#Public'
-            newUndoAnnounce = {
+            newUndoAnnounce={
                 "@context": "https://www.w3.org/ns/activitystreams",
                 'actor': undoAnnounceActor,
                 'type': 'Undo',
@@ -2534,7 +2534,7 @@ class PubServer(BaseHTTPRequestHandler):
                                     nickname+'#statuses#'+statusNumber+'.replies'
                                 if not os.path.isfile(postRepliesFilename):
                                     # There are no replies, so show empty collection
-                                    repliesJson = {
+                                    repliesJson={
                                         '@context': 'https://www.w3.org/ns/activitystreams',
                                         'first': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'/replies?page=true',
                                         'id': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'/replies',
@@ -2574,7 +2574,7 @@ class PubServer(BaseHTTPRequestHandler):
                                     return
                                 else:
                                     # replies exist. Itterate through the text file containing message ids
-                                    repliesJson = {
+                                    repliesJson={
                                         '@context': 'https://www.w3.org/ns/activitystreams',
                                         'id': self.server.httpPrefix+'://'+self.server.domainFull+'/users/'+nickname+'/statuses/'+statusNumber+'?page=true',
                                         'orderedItems': [
@@ -2637,7 +2637,7 @@ class PubServer(BaseHTTPRequestHandler):
                     if actorJson:                    
                         if actorJson.get('roles'):
                             if self._requestHTTP():
-                                getPerson = \
+                                getPerson= \
                                     personLookup(self.server.domain, \
                                                  self.path.replace('/roles',''), \
                                                  self.server.baseDir)
@@ -2683,7 +2683,7 @@ class PubServer(BaseHTTPRequestHandler):
                     if actorJson:                    
                         if actorJson.get('skills'):
                             if self._requestHTTP():
-                                getPerson = \
+                                getPerson= \
                                     personLookup(self.server.domain, \
                                                  self.path.replace('/skills',''), \
                                                  self.server.baseDir)
@@ -3525,7 +3525,7 @@ class PubServer(BaseHTTPRequestHandler):
                     if pageNumberStr.isdigit():
                         pageNumber=int(pageNumberStr)
                     searchPath=self.path.split('?page=')[0]
-                getPerson = \
+                getPerson= \
                     personLookup(self.server.domain, \
                                  searchPath.replace('/following',''), \
                                  self.server.baseDir)
@@ -3629,7 +3629,7 @@ class PubServer(BaseHTTPRequestHandler):
         self._benchmarkGETtimings(GETstartTime,GETtimings,52)
 
         # look up a person
-        getPerson = \
+        getPerson= \
             personLookup(self.server.domain,self.path, \
                          self.server.baseDir)
         if getPerson:
@@ -3687,7 +3687,7 @@ class PubServer(BaseHTTPRequestHandler):
         filename=self.server.baseDir+self.path
         if os.path.isfile(filename):
             with open(filename, 'r', encoding='utf-8') as File:
-                content = File.read()
+                content=File.read()
                 contentJson=json.loads(content)
                 msg=json.dumps(contentJson,ensure_ascii=False).encode('utf-8')
                 self._set_headers('application/json',len(msg),None)
@@ -3723,12 +3723,12 @@ class PubServer(BaseHTTPRequestHandler):
                     if os.path.isfile(mediaFilename+'.etag'):
                         try:
                             with open(mediaFilename+'.etag', 'r') as etagFile:
-                                etag = etagFile.read()
+                                etag=etagFile.read()
                         except:
                             pass
                     else:
                         with open(mediaFilename, 'rb') as avFile:
-                            mediaBinary = avFile.read()
+                            mediaBinary=avFile.read()
                             etag=sha1(mediaBinary).hexdigest()
                             try:
                                 with open(mediaFilename+'.etag', 'w') as etagFile:
@@ -3760,10 +3760,10 @@ class PubServer(BaseHTTPRequestHandler):
                                postType: str,path: str,headers: {},
                                length: int,postBytes,boundary: str) -> int:
         # Note: this needs to happen synchronously
-        # 0 = this is not a new post
-        # 1 = new post success
-        # -1 = new post failed
-        # 2 = new post canceled
+        # 0=this is not a new post
+        # 1=new post success
+        # -1=new post failed
+        # 2=new post canceled
         if self.server.debug:
             print('DEBUG: receiving POST')
 
@@ -3776,7 +3776,7 @@ class PubServer(BaseHTTPRequestHandler):
                 nickname=nicknameStr.split('/')[0]
             else:
                 return -1
-            length = int(headers['Content-Length'])
+            length=int(headers['Content-Length'])
             if length>self.server.maxPostLength:
                 print('POST size too large')
                 return -1
@@ -4229,7 +4229,7 @@ class PubServer(BaseHTTPRequestHandler):
                 headersWithoutCookie[dictEntryName]=headerLine
         print('New post headers: '+str(headersWithoutCookie))
 
-        length = int(headers['Content-Length'])
+        length=int(headers['Content-Length'])
         if length>self.server.maxPostLength:
             print('POST size too large')
             return None
@@ -4304,7 +4304,7 @@ class PubServer(BaseHTTPRequestHandler):
             cookie=self.headers['Cookie']
 
         # check authorization
-        authorized = self._isAuthorized()
+        authorized=self._isAuthorized()
         if self.server.debug:
             if authorized:
                 print('POST Authorization granted')
@@ -4320,7 +4320,7 @@ class PubServer(BaseHTTPRequestHandler):
         
         if self.path.startswith('/login'):
             # get the contents of POST containing login credentials
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             if length>512:
                 print('Login failed - credentials too long')
                 self.send_response(401)
@@ -4368,7 +4368,7 @@ class PubServer(BaseHTTPRequestHandler):
                     if os.path.isfile(saltFilename):
                         try:
                             with open(saltFilename, 'r') as fp:
-                                salt = fp.read()
+                                salt=fp.read()
                         except Exception as e:
                             print('WARN: Unable to read salt for '+ \
                                   loginNickname+' '+str(e))
@@ -4430,7 +4430,7 @@ class PubServer(BaseHTTPRequestHandler):
                     self._redirect_headers(actorStr,cookie)
                     self.server.POSTbusy=False
                     return
-                length = int(self.headers['Content-length'])
+                length=int(self.headers['Content-length'])
                 if length>self.server.maxPostLength:
                     print('Maximum profile data length exceeded '+str(length))
                     self._redirect_headers(actorStr,cookie)
@@ -4855,7 +4855,7 @@ class PubServer(BaseHTTPRequestHandler):
             actorStr= \
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 self.path.replace('/moderationaction','')
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             moderationParams=self.rfile.read(length).decode('utf-8')
             print('moderationParams: '+moderationParams)
             if '&' in moderationParams:
@@ -4995,7 +4995,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.POSTbusy=False
                 return
             # get the parameters
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             questionParams=self.rfile.read(length).decode('utf-8')
             questionParams= \
                 questionParams.replace('+',' ').replace('%40','@').replace('%3A',':').replace('%23','#').replace('%2F','/').replace('%3F','').strip()
@@ -5034,7 +5034,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.httpPrefix+'://'+ \
                 self.server.domainFull+ \
                 self.path.replace('/searchhandle','')
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             searchParams=self.rfile.read(length).decode('utf-8')
             if 'submitBack=' in searchParams:
                 # go back on search screen
@@ -5165,7 +5165,7 @@ class PubServer(BaseHTTPRequestHandler):
             originPathStr= \
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 self.path.split('/rmshare')[0]
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             removeShareConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitYes=' in removeShareConfirmParams:
                 removeShareConfirmParams= \
@@ -5193,7 +5193,7 @@ class PubServer(BaseHTTPRequestHandler):
             originPathStr= \
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 self.path.split('/rmpost')[0]
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             removePostConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitYes=' in removePostConfirmParams:
                 removePostConfirmParams= \
@@ -5255,7 +5255,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 self.path.split('/followconfirm')[0]
             followerNickname=getNicknameFromActor(originPathStr)
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             followConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitView=' in followConfirmParams:
                 followingActor= \
@@ -5308,7 +5308,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self.server.httpPrefix+'://'+self.server.domainFull+ \
                 self.path.split('/unfollowconfirm')[0]
             followerNickname=getNicknameFromActor(originPathStr)
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             followConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitYes=' in followConfirmParams:
                 followingActor= \
@@ -5329,9 +5329,9 @@ class PubServer(BaseHTTPRequestHandler):
                         self.server.httpPrefix+'://'+ \
                         self.server.domainFull+ \
                         '/users/'+followerNickname
-                    statusNumber,published = getStatusNumber()
+                    statusNumber,published=getStatusNumber()
                     followId=followActor+'/statuses/'+str(statusNumber)
-                    unfollowJson = {
+                    unfollowJson={
                         '@context': 'https://www.w3.org/ns/activitystreams',
                         'id': followId+'/undo',
                         'type': 'Undo',
@@ -5363,7 +5363,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self._redirect_headers(originPathStr,cookie)
                 self.server.POSTbusy=False
                 return                
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             blockConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitYes=' in blockConfirmParams:
                 blockingActor= \
@@ -5410,7 +5410,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self._redirect_headers(originPathStr,cookie)
                 self.server.POSTbusy=False
                 return                
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             blockConfirmParams=self.rfile.read(length).decode('utf-8')
             if '&submitYes=' in blockConfirmParams:
                 blockingActor= \
@@ -5462,7 +5462,7 @@ class PubServer(BaseHTTPRequestHandler):
                 self._redirect_headers(originPathStr,cookie)
                 self.server.POSTbusy=False
                 return                
-            length = int(self.headers['Content-length'])
+            length=int(self.headers['Content-length'])
             optionsConfirmParams= \
                 self.rfile.read(length).decode('utf-8').replace('%3A',':').replace('%2F','/')
             # page number to return to
@@ -5671,7 +5671,7 @@ class PubServer(BaseHTTPRequestHandler):
         self._benchmarkPOSTtimings(POSTstartTime,POSTtimings,17)
 
         # read the message and convert it into a python dictionary
-        length = int(self.headers['Content-length'])
+        length=int(self.headers['Content-length'])
         if self.server.debug:
             print('DEBUG: content-length: '+str(length))
         if not self.headers['Content-type'].startswith('image/') and \
@@ -5740,7 +5740,7 @@ class PubServer(BaseHTTPRequestHandler):
             print("POST is not json: "+self.headers['Content-type'])
             if self.server.debug:
                 print(str(self.headers))
-                length = int(self.headers['Content-length'])
+                length=int(self.headers['Content-length'])
                 if length<self.server.maxPostLength:
                     unknownPost=self.rfile.read(length).decode('utf-8')
                     print(str(unknownPost))
@@ -5758,11 +5758,11 @@ class PubServer(BaseHTTPRequestHandler):
         if self.path == '/sharedInbox' or self.path == '/inbox':
             length=0
             if self.headers.get('Content-length'):
-                length = int(self.headers['Content-length'])
+                length=int(self.headers['Content-length'])
             elif self.headers.get('Content-Length'):
-                length = int(self.headers['Content-Length'])
+                length=int(self.headers['Content-Length'])
             elif self.headers.get('content-length'):
-                length = int(self.headers['content-length'])
+                length=int(self.headers['content-length'])
             if length>10240:
                 print('WARN: post to shared inbox is too long '+str(length)+' bytes')
                 self._400()
@@ -5897,7 +5897,7 @@ class PubServer(BaseHTTPRequestHandler):
         self.server.POSTbusy=False
 
 class PubServerUnitTest(PubServer):
-    protocol_version = 'HTTP/1.0'
+    protocol_version='HTTP/1.0'
 
 def runPostsQueue(baseDir: str,sendThreads: [],debug: bool) -> None:
     """Manages the threads used to send posts
@@ -5952,7 +5952,7 @@ def loadTokens(baseDir: str,tokensDict: {},tokensLookup: {}) -> None:
                 token=None
                 try:
                     with open(tokenFilename, 'r') as fp:
-                        token = fp.read()
+                        token=fp.read()
                 except Exception as e:
                     print('WARN: Unable to read token for '+nickname+' '+str(e))
                 if not token:
@@ -5984,14 +5984,14 @@ def runDaemon(blogsInstance: bool,mediaInstance: bool, \
             return
 
     if unitTest: 
-        serverAddress = (domain, proxyPort)
-        pubHandler = partial(PubServerUnitTest)
+        serverAddress=(domain, proxyPort)
+        pubHandler=partial(PubServerUnitTest)
     else:
-        serverAddress = ('', proxyPort)
-        pubHandler = partial(PubServer)
+        serverAddress=('', proxyPort)
+        pubHandler=partial(PubServer)
 
     try:
-        httpd = ThreadingHTTPServer(serverAddress, pubHandler)
+        httpd=ThreadingHTTPServer(serverAddress, pubHandler)
     except Exception as e:
         if e.errno==98:
             print('ERROR: HTTP server address is already in use. '+str(serverAddress))
@@ -6068,7 +6068,7 @@ def runDaemon(blogsInstance: bool,mediaInstance: bool, \
     httpd.personCache={}
     httpd.cachedWebfingers={}
     httpd.useTor=useTor
-    httpd.session = None
+    httpd.session=None
     httpd.sessionLastUpdate=0
     httpd.lastGET=0
     httpd.lastPOST=0

+ 25 - 22
delete.py

@@ -1,10 +1,10 @@
-__filename__ = "delete.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="delete.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import json
@@ -46,10 +46,10 @@ def createDelete(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fullDomain=domain+':'+str(port)
 
-    statusNumber,published = getStatusNumber()
+    statusNumber,published=getStatusNumber()
     newDeleteId= \
         httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber
-    newDelete = {
+    newDelete={
         "@context": "https://www.w3.org/ns/activitystreams",
         'actor': httpPrefix+'://'+fullDomain+'/users/'+nickname,
         'atomUri': httpPrefix+'://'+fullDomain+'/users/'+nickname+'/statuses/'+statusNumber,
@@ -101,10 +101,10 @@ def sendDeleteViaServer(baseDir: str,session, \
             if ':' not in fromDomain:
                 fromDomainFull=fromDomain+':'+str(fromPort)
 
-    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
-    ccUrl = httpPrefix + '://'+fromDomainFull+'/users/'+fromNickname+'/followers'
+    toUrl='https://www.w3.org/ns/activitystreams#Public'
+    ccUrl=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname+'/followers'
 
-    newDeleteJson = {
+    newDeleteJson={
         "@context": "https://www.w3.org/ns/activitystreams",
         'actor': httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname,
         'cc': [ccUrl],
@@ -116,8 +116,9 @@ def sendDeleteViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                fromDomain,projectVersion)
+    wfRequest= \
+        webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                        fromDomain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -126,7 +127,7 @@ def sendDeleteViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -142,10 +143,12 @@ def sendDeleteViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newDeleteJson,[],inboxUrl,headers,"inbox:write")
     #if not postResult:
     #    if debug:
@@ -171,8 +174,8 @@ def deletePublic(session,baseDir: str,federationList: [], \
             if ':' not in domain:
                 fromDomain=domain+':'+str(port)
 
-    toUrl = 'https://www.w3.org/ns/activitystreams#Public'
-    ccUrl = httpPrefix + '://'+fromDomain+'/users/'+nickname+'/followers'
+    toUrl='https://www.w3.org/ns/activitystreams#Public'
+    ccUrl=httpPrefix+'://'+fromDomain+'/users/'+nickname+'/followers'
     return createDelete(session,baseDir,federationList, \
                         nickname,domain,port, \
                         toUrl,ccUrl,httpPrefix, \
@@ -197,7 +200,7 @@ def deletePostPub(session,baseDir: str,federationList: [], \
             if ':' not in deletedDomain:
                 deletedDomain=deletedDomain+':'+str(deletePort)
 
-    objectUrl = \
+    objectUrl= \
         deleteHttpsPrefix + '://'+deletedDomain+'/users/'+ \
         deleteNickname+'/statuses/'+str(deleteStatusNumber)
 

+ 7 - 7
donate.py

@@ -1,10 +1,10 @@
-__filename__ = "donate.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="donate.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 

+ 50 - 38
epicyon.py

@@ -1,10 +1,10 @@
-__filename__ = "epicyon.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="epicyon.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 from person import createPerson
 from person import createGroup
@@ -93,7 +93,7 @@ def str2bool(v):
     else:
         raise argparse.ArgumentTypeError('Boolean value expected.')
 
-parser = argparse.ArgumentParser(description='ActivityPub Server')
+parser=argparse.ArgumentParser(description='ActivityPub Server')
 parser.add_argument('-n','--nickname', dest='nickname', type=str,default=None, \
                     help='Nickname of the account to use')
 parser.add_argument('--fol','--follow', dest='follow', type=str,default=None, \
@@ -311,7 +311,7 @@ parser.add_argument('--maxregistrations', dest='maxRegistrations', type=int,defa
 parser.add_argument("--resetregistrations", type=str2bool, nargs='?', \
                     const=True, default=False, \
                     help="Reset the number of remaining registrations")
-args = parser.parse_args()
+args=parser.parse_args()
 
 debug=False
 if args.debug:
@@ -365,9 +365,11 @@ if args.postsraw:
     sys.exit()
 
 if args.json:
-    session = createSession(False)
-    asHeader = {'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'}
-    testJson = getJson(session,args.json,asHeader,None,__version__,httpPrefix,None)
+    session=createSession(False)
+    asHeader={
+        'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+    }
+    testJson=getJson(session,args.json,asHeader,None,__version__,httpPrefix,None)
     pprint(testJson)
     sys.exit()
 
@@ -533,7 +535,7 @@ if args.approve:
     if '@' not in args.approve:
         print('syntax: --approve nick@domain')
         sys.exit()
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     sendThreads=[]
     postLog=[]
     cachedWebfingers={}
@@ -557,7 +559,7 @@ if args.deny:
     if '@' not in args.deny:
         print('syntax: --deny nick@domain')
         sys.exit()
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     sendThreads=[]
     postLog=[]
     cachedWebfingers={}
@@ -599,7 +601,7 @@ if args.message:
         print('Specify a password with the --password option')
         sys.exit()
         
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     if not args.sendto:
         print('Specify an account to sent to: --sendto [nickname@domain]')
         sys.exit()        
@@ -634,8 +636,8 @@ if args.message:
     clientToServer=args.client
     attachedImageDescription=args.imageDescription
     useBlurhash=args.blurhash
-    sendThreads = []
-    postLog = []
+    sendThreads=[]
+    postLog=[]
     personCache={}
     cachedWebfingers={}
     subject=args.subject
@@ -671,7 +673,7 @@ if args.announce:
         print('Specify a password with the --password option')
         sys.exit()
         
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending announce/repeat of '+args.announce)
@@ -715,7 +717,7 @@ if args.itemName:
         print('Specify a duration to share the object with the --duration option')
         sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending shared item: '+args.itemName)
@@ -747,7 +749,7 @@ if args.undoItemName:
         print('Specify a nickname with the --nickname option')
         sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending undo of shared item: '+args.undoItemName)
@@ -773,7 +775,7 @@ if args.like:
         print('Specify a password with the --password option')
         sys.exit()
         
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending like of '+args.like)
@@ -798,7 +800,7 @@ if args.undolike:
         print('Specify a password with the --password option')
         sys.exit()
         
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending undo like of '+args.undolike)
@@ -823,7 +825,7 @@ if args.delete:
         print('Specify a password with the --password option')
         sys.exit()
         
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending delete request of '+args.delete)
@@ -857,7 +859,7 @@ if args.follow:
         sys.exit()        
     followDomain,followPort=getDomainFromActor(args.follow)
 
-    session = createSession(useTor)
+    session=createSession(useTor)
     personCache={}
     cachedWebfingers={}
     followHttpPrefix=httpPrefix
@@ -895,7 +897,7 @@ if args.unfollow:
         sys.exit()        
     followDomain,followPort=getDomainFromActor(args.unfollow)
 
-    session = createSession(useTor)
+    session=createSession(useTor)
     personCache={}
     cachedWebfingers={}
     followHttpPrefix=httpPrefix
@@ -994,24 +996,34 @@ if args.actor:
         else:
             sys.exit()
         
-    asHeader = {'Accept': 'application/activity+json; profile="https://www.w3.org/ns/activitystreams"'}
+    asHeader={
+        'Accept': 'application/activity+json; profile="https://www.w3.org/ns/activitystreams"'
+    }
     if not personUrl:
-        personUrl = getUserUrl(wfRequest)
+        personUrl=getUserUrl(wfRequest)
     if nickname==domain:
         personUrl=personUrl.replace('/users/','/actor/').replace('/channel/','/actor/').replace('/profile/','/actor/')
     if not personUrl:
         # try single user instance
         personUrl=httpPrefix+'://'+domain
-        asHeader = {'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'}
+        asHeader={
+            'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+        }
     if '/channel/' in personUrl:
-        asHeader = {'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'}
+        asHeader={
+            'Accept': 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'
+        }
 
-    personJson = getJson(session,personUrl,asHeader,None,__version__,httpPrefix,None)
+    personJson= \
+        getJson(session,personUrl,asHeader,None,__version__,httpPrefix,None)
     if personJson:
         pprint(personJson)
     else:
-        asHeader = {'Accept': 'application/jrd+json; profile="https://www.w3.org/ns/activitystreams"'}
-        personJson = getJson(session,personUrl,asHeader,None,__version__,httpPrefix,None)
+        asHeader={
+            'Accept': 'application/jrd+json; profile="https://www.w3.org/ns/activitystreams"'
+        }
+        personJson= \
+            getJson(session,personUrl,asHeader,None,__version__,httpPrefix,None)
         if personJson:
             pprint(personJson)
         else:
@@ -1237,7 +1249,7 @@ if args.skill:
         print('Skill level should be a percentage in the range 0-100')
         sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending '+args.skill+' skill level '+str(args.skillLevelPercent)+' for '+nickname)
@@ -1263,7 +1275,7 @@ if args.availability:
         print('Specify a password with the --password option')
         sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending availability status of '+nickname+' as '+args.availability)
@@ -1308,7 +1320,7 @@ if args.block:
             print(args.block+' does not look like an actor url')
             sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending block of '+args.block)
@@ -1344,7 +1356,7 @@ if args.delegate:
         delegatedNickname=args.delegate.split('@')[0]
         args.delegate=blockedActor
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending delegation for '+args.delegate+' with role '+args.role+' in project '+args.project)
@@ -1378,7 +1390,7 @@ if args.undelegate:
         delegatedNickname=args.undelegate.split('@')[0]
         args.undelegate=blockedActor
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending delegation removal for '+args.undelegate+' from role '+args.role+' in project '+args.project)
@@ -1414,7 +1426,7 @@ if args.unblock:
             print(args.unblock+' does not look like an actor url')
             sys.exit()
 
-    session = createSession(useTor)        
+    session=createSession(useTor)        
     personCache={}
     cachedWebfingers={}
     print('Sending undo block of '+args.unblock)

+ 7 - 7
filters.py

@@ -1,10 +1,10 @@
-__filename__ = "filters.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="filters.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 

+ 51 - 43
follow.py

@@ -1,10 +1,10 @@
-__filename__ = "follow.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="follow.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 import time
@@ -56,7 +56,7 @@ def removeFromFollowBase(baseDir: str, \
         return
     if acceptOrDenyHandle not in open(approveFollowsFilename).read():
         return
-    approvefilenew = open(approveFollowsFilename+'.new', 'w+')
+    approvefilenew=open(approveFollowsFilename+'.new', 'w+')
     with open(approveFollowsFilename, 'r') as approvefile:
         for approveHandle in approvefile:
             if not approveHandle.startswith(acceptOrDenyHandle):
@@ -137,8 +137,8 @@ def getFollowersOfPerson(baseDir: str, \
         return followers
     for subdir, dirs, files in os.walk(baseDir+'/accounts'):
         for account in dirs:
-            filename = os.path.join(subdir, account)+'/'+followFile
-            if account == handle or account.startswith('inbox@'):
+            filename=os.path.join(subdir, account)+'/'+followFile
+            if account==handle or account.startswith('inbox@'):
                 continue
             if not os.path.isfile(filename):
                 continue
@@ -195,7 +195,7 @@ def unfollowPerson(baseDir: str,nickname: str, domain: str, \
             print('DEBUG: handle to unfollow '+handleToUnfollow+' is not in '+filename)
         return
     with open(filename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
     with open(filename, "w") as f:
         for line in lines:
             if line.strip("\n") != handleToUnfollow:
@@ -254,9 +254,9 @@ def getNoOfFollows(baseDir: str,nickname: str,domain: str, \
     filename=baseDir+'/accounts/'+handle+'/'+followFile
     if not os.path.isfile(filename):
         return 0
-    ctr = 0
+    ctr=0
     with open(filename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
         for line in lines:
             if '#' not in line:
                 if '@' in line and '.' in line and not line.startswith('http'):
@@ -315,25 +315,27 @@ def getFollowingFeed(baseDir: str,domain: str,port: int,path: str, \
                 domain=domain+':'+str(port)
 
     if headerOnly:
-        following = {
+        following={
             '@context': 'https://www.w3.org/ns/activitystreams',
             'first': httpPrefix+'://'+domain+'/users/'+nickname+'/'+followFile+'?page=1',
             'id': httpPrefix+'://'+domain+'/users/'+nickname+'/'+followFile,
             'totalItems': getNoOfFollows(baseDir,nickname,domain,authenticated),
-            'type': 'OrderedCollection'}
+            'type': 'OrderedCollection'
+        }
         return following
 
     if not pageNumber:
         pageNumber=1
 
     nextPageNumber=int(pageNumber+1)
-    following = {
+    following={
         '@context': 'https://www.w3.org/ns/activitystreams',
         'id': httpPrefix+'://'+domain+'/users/'+nickname+'/'+followFile+'?page='+str(pageNumber),
         'orderedItems': [],
         'partOf': httpPrefix+'://'+domain+'/users/'+nickname+'/'+followFile,
         'totalItems': 0,
-        'type': 'OrderedCollectionPage'}        
+        'type': 'OrderedCollectionPage'
+    }
 
     handleDomain=domain
     if ':' in handleDomain:
@@ -346,15 +348,15 @@ def getFollowingFeed(baseDir: str,domain: str,port: int,path: str, \
     pageCtr=0
     totalCtr=0
     with open(filename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
         for line in lines:
             if '#' not in line:
                 if '@' in line and not line.startswith('http'):
                     pageCtr += 1
                     totalCtr += 1
                     if currPage==pageNumber:
-                        url = httpPrefix + '://' + line.lower().replace('\n','').split('@')[1] + \
-                            '/users/' + line.lower().replace('\n','').split('@')[0]
+                        url=httpPrefix+'://' + line.lower().replace('\n','').split('@')[1] + \
+                            '/users/'+line.lower().replace('\n','').split('@')[0]
                         following['orderedItems'].append(url)
                 elif (line.startswith('http') or line.startswith('dat')) and '/users/' in line:
                     pageCtr += 1
@@ -411,7 +413,7 @@ def noOfFollowRequests(baseDir: str, \
         return 0
     ctr=0
     with open(approveFollowsFilename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
         if followType != "onion":
             return len(lines)
         for l in lines:
@@ -590,7 +592,7 @@ def receiveFollowRequest(session,baseDir: str,httpPrefix: str, \
                 if approveHandle not in open(followersFilename).read():
                     try:
                         with open(followersFilename, 'r+') as followersFile:
-                            content = followersFile.read()
+                            content=followersFile.read()
                             followersFile.seek(0, 0)
                             followersFile.write(approveHandle+'\n'+content)
                     except Exception as e:
@@ -746,7 +748,7 @@ def sendFollowRequest(session,baseDir: str, \
             if ':' not in followDomain:
                 requestDomain=followDomain+':'+str(followPort)
 
-    statusNumber,published = getStatusNumber()
+    statusNumber,published=getStatusNumber()
     
     if followNickname:
         followedId=followHttpPrefix+'://'+requestDomain+'/users/'+followNickname
@@ -758,7 +760,7 @@ def sendFollowRequest(session,baseDir: str, \
         singleUserNickname='dev'
         followHandle=singleUserNickname+'@'+requestDomain
 
-    newFollowJson = {
+    newFollowJson={
         '@context': 'https://www.w3.org/ns/activitystreams',
         'id': followActor+'/statuses/'+str(statusNumber),
         'type': 'Follow',
@@ -813,8 +815,8 @@ def sendFollowRequestViaServer(baseDir: str,session, \
     followActor=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname    
     followedId=httpPrefix+'://'+followDomainFull+'/users/'+followNickname
 
-    statusNumber,published = getStatusNumber()
-    newFollowJson = {
+    statusNumber,published=getStatusNumber()
+    newFollowJson={
         '@context': 'https://www.w3.org/ns/activitystreams',
         'id': followActor+'/statuses/'+str(statusNumber),
         'type': 'Follow',
@@ -825,8 +827,9 @@ def sendFollowRequestViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                fromDomain,projectVersion)
+    wfRequest= \
+        webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                        fromDomain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -835,7 +838,7 @@ def sendFollowRequestViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -851,10 +854,12 @@ def sendFollowRequestViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,newFollowJson,[],inboxUrl,headers,"inbox:write")
     #if not postResult:
     #    if debug:
@@ -892,9 +897,9 @@ def sendUnfollowRequestViaServer(baseDir: str,session, \
 
     followActor=httpPrefix+'://'+fromDomainFull+'/users/'+fromNickname    
     followedId=httpPrefix+'://'+followDomainFull+'/users/'+followNickname
-    statusNumber,published = getStatusNumber()
+    statusNumber,published=getStatusNumber()
 
-    unfollowJson = {
+    unfollowJson={
         '@context': 'https://www.w3.org/ns/activitystreams',
         'id': followActor+'/statuses/'+str(statusNumber)+'/undo',
         'type': 'Undo',
@@ -910,8 +915,9 @@ def sendUnfollowRequestViaServer(baseDir: str,session, \
     handle=httpPrefix+'://'+fromDomainFull+'/@'+fromNickname
 
     # lookup the inbox for the To handle
-    wfRequest = webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
-                                fromDomain,projectVersion)
+    wfRequest= \
+        webfingerHandle(session,handle,httpPrefix,cachedWebfingers, \
+                        fromDomain,projectVersion)
     if not wfRequest:
         if debug:
             print('DEBUG: announce webfinger failed for '+handle)
@@ -920,7 +926,7 @@ def sendUnfollowRequestViaServer(baseDir: str,session, \
     postToBox='outbox'
 
     # get the actor inbox for the To handle
-    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName = \
+    inboxUrl,pubKeyId,pubKey,fromPersonId,sharedInbox,capabilityAcquisition,avatarUrl,displayName= \
         getPersonBox(baseDir,session,wfRequest,personCache, \
                      projectVersion,httpPrefix,fromNickname, \
                      fromDomain,postToBox)
@@ -936,10 +942,12 @@ def sendUnfollowRequestViaServer(baseDir: str,session, \
     
     authHeader=createBasicAuthHeader(fromNickname,password)
      
-    headers = {'host': fromDomain, \
-               'Content-type': 'application/json', \
-               'Authorization': authHeader}
-    postResult = \
+    headers={
+        'host': fromDomain, \
+        'Content-type': 'application/json', \
+        'Authorization': authHeader
+    }
+    postResult= \
         postJson(session,unfollowJson,[],inboxUrl,headers,"inbox:write")
     #if not postResult:
     #    if debug:
@@ -980,7 +988,7 @@ def getFollowersOfActor(baseDir :str,actor :str,debug: bool) -> {}:
     for subdir, dirs, files in os.walk(baseDir+'/accounts'):
         for account in dirs:
             if '@' in account and not account.startswith('inbox@'):
-                followingFilename = os.path.join(subdir, account)+'/following.txt'
+                followingFilename=os.path.join(subdir, account)+'/following.txt'
                 if debug:
                     print('DEBUG: examining follows of '+account)
                     print(followingFilename)

+ 8 - 8
happening.py

@@ -1,10 +1,10 @@
-__filename__ = "happening.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="happening.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 import time
@@ -380,7 +380,7 @@ def removeCalendarEvent(baseDir: str,nickname: str,domain: str, \
         return
     lines=None
     with open(calendarFilename, "r") as f:
-        lines = f.readlines()
+        lines=f.readlines()
     if not lines:
         return
     with open(calendarFilename, "w+") as f:

+ 37 - 28
httpsig.py

@@ -1,11 +1,11 @@
-__filename__ = "posts.py"
-__author__ = "Bob Mottram"
-__credits__ = ['lamia']
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="posts.py"
+__author__="Bob Mottram"
+__credits__=['lamia']
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 # see https://tools.ietf.org/html/draft-cavage-http-signatures-06
 
@@ -63,27 +63,27 @@ def signPostHeaders(dateStr: str,privateKeyPem: str, \
     #    '(request-target)': f'post {path}',
     #})
     # build a digest for signing
-    signedHeaderKeys = headers.keys()
-    signedHeaderText = ''
+    signedHeaderKeys=headers.keys()
+    signedHeaderText=''
     for headerKey in signedHeaderKeys:
         signedHeaderText += f'{headerKey}: {headers[headerKey]}\n'
         #print(f'*********************signing:  headerKey: {headerKey}: {headers[headerKey]}')
-    signedHeaderText = signedHeaderText.strip()
+    signedHeaderText=signedHeaderText.strip()
     #print('******************************Send: signedHeaderText: '+signedHeaderText)
-    headerDigest = SHA256.new(signedHeaderText.encode('ascii'))
+    headerDigest=SHA256.new(signedHeaderText.encode('ascii'))
 
     # Sign the digest
-    rawSignature = pkcs1_15.new(privateKeyPem).sign(headerDigest)
-    signature = base64.b64encode(rawSignature).decode('ascii')
+    rawSignature=pkcs1_15.new(privateKeyPem).sign(headerDigest)
+    signature=base64.b64encode(rawSignature).decode('ascii')
 
     # Put it into a valid HTTP signature format
-    signatureDict = {
+    signatureDict={
         'keyId': keyID,
         'algorithm': 'rsa-sha256',
         'headers': ' '.join(signedHeaderKeys),
         'signature': signature
     }
-    signatureHeader = ','.join(
+    signatureHeader=','.join(
         [f'{k}="{v}"' for k, v in signatureDict.items()])
     return signatureHeader
 
@@ -104,8 +104,10 @@ def createSignedHeader(privateKeyPem: str,nickname: str, \
 
     dateStr=strftime("%a, %d %b %Y %H:%M:%S %Z", gmtime())
     if not withDigest:
-        headers = {'(request-target)': f'post {path}','host': headerDomain,'date': dateStr}
-        signatureHeader = \
+        headers={
+            '(request-target)': f'post {path}','host': headerDomain,'date': dateStr
+        }
+        signatureHeader= \
             signPostHeaders(dateStr,privateKeyPem,nickname, \
                             domain,port,toDomain,toPort, \
                             path,httpPrefix,None)
@@ -119,13 +121,20 @@ def createSignedHeader(privateKeyPem: str,nickname: str, \
         #print('***************************Send Content-type: '+contentType)
         #print('***************************Send Content-Length: '+str(len(messageBodyJsonStr)))
         #print('***************************Send messageBodyJsonStr: '+messageBodyJsonStr)
-        headers = {'(request-target)': f'post {path}','host': headerDomain,'date': dateStr,'digest': f'SHA-256={bodyDigest}','content-length': str(contentLength),'content-type': contentType}
-        signatureHeader = \
+        headers={
+            '(request-target)': f'post {path}',
+            'host': headerDomain,
+            'date': dateStr,
+            'digest': f'SHA-256={bodyDigest}',
+            'content-length': str(contentLength),
+            'content-type': contentType
+        }
+        signatureHeader= \
             signPostHeaders(dateStr,privateKeyPem,nickname, \
                             domain,port, \
                             toDomain,toPort, \
                             path,httpPrefix,messageBodyJsonStr)
-    headers['signature'] = signatureHeader
+    headers['signature']=signatureHeader
     return headers
 
 def verifyRecentSignature(signedDateStr: str) -> bool:
@@ -167,10 +176,10 @@ def verifyPostHeaders(httpPrefix: str,publicKeyPem: str,headers: dict, \
     if debug:
         print('DEBUG: verifyPostHeaders '+method)
         
-    publicKeyPem = RSA.import_key(publicKeyPem)
+    publicKeyPem=RSA.import_key(publicKeyPem)
     # Build a dictionary of the signature values
-    signatureHeader = headers['signature']
-    signatureDict = {
+    signatureHeader=headers['signature']
+    signatureDict={
         k: v[1:-1]
         for k, v in [i.split('=', 1) for i in signatureHeader.split(',')]
     }
@@ -179,7 +188,7 @@ def verifyPostHeaders(httpPrefix: str,publicKeyPem: str,headers: dict, \
 
     # Unpack the signed headers and set values based on current headers and
     # body (if a digest was included)
-    signedHeaderList = []
+    signedHeaderList=[]
     for signedHeader in signatureDict['headers'].split(' '):
         if debug:
             print('DEBUG: verifyPostHeaders signedHeader='+signedHeader)
@@ -236,12 +245,12 @@ def verifyPostHeaders(httpPrefix: str,publicKeyPem: str,headers: dict, \
     if debug:
         print('DEBUG: signedHeaderList: '+str(signedHeaderList))
     # Now we have our header data digest
-    signedHeaderText = '\n'.join(signedHeaderList)
+    signedHeaderText='\n'.join(signedHeaderList)
     #print('***********************Verify: signedHeaderText: '+signedHeaderText)
-    headerDigest = SHA256.new(signedHeaderText.encode('ascii'))
+    headerDigest=SHA256.new(signedHeaderText.encode('ascii'))
 
     # Get the signature, verify with public key, return result
-    signature = base64.b64decode(signatureDict['signature'])
+    signature=base64.b64decode(signatureDict['signature'])
 
     try:
         pkcs1_15.new(publicKeyPem).verify(headerDigest, signature)

+ 19 - 19
inbox.py

@@ -1,10 +1,10 @@
-__filename__ = "inbox.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="inbox.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import json
 import os
@@ -101,7 +101,7 @@ def storeHashTags(baseDir: str,nickname: str,postJsonObject: {}) -> None:
             if postUrl not in open(tagsFilename).read():
                 try:
                     with open(tagsFilename, 'r+') as tagsFile:
-                        content = tagsFile.read()
+                        content=tagsFile.read()
                         tagsFile.seek(0, 0)
                         tagsFile.write(tagline+content)
                 except Exception as e:
@@ -142,7 +142,7 @@ def validInbox(baseDir: str,nickname: str,domain: str) -> bool:
         return True
     for subdir, dirs, files in os.walk(inboxDir):
         for f in files:
-            filename = os.path.join(subdir, f)
+            filename=os.path.join(subdir, f)
             if not os.path.isfile(filename):
                 print('filename: '+filename)
                 return False
@@ -164,7 +164,7 @@ def validInboxFilenames(baseDir: str,nickname: str,domain: str, \
     expectedStr=expectedDomain+':'+str(expectedPort)
     for subdir, dirs, files in os.walk(inboxDir):
         for f in files:
-            filename = os.path.join(subdir, f)
+            filename=os.path.join(subdir, f)
             if not os.path.isfile(filename):
                 print('filename: '+filename)
                 return False
@@ -185,7 +185,7 @@ def getPersonPubKey(baseDir: str,session,personUrl: str, \
         if debug:
             print('DEBUG: Obtaining public key for shared inbox')
         personUrl=personUrl.replace('/users/inbox','/inbox')        
-    personJson = getPersonFromCache(baseDir,personUrl,personCache)
+    personJson=getPersonFromCache(baseDir,personUrl,personCache)
     if not personJson:
         if debug:
             print('DEBUG: Obtaining public key for '+personUrl)
@@ -193,10 +193,10 @@ def getPersonPubKey(baseDir: str,session,personUrl: str, \
         if onionDomain:
             if '.onion/' in personUrl:
                 personDomain=onionDomain
-        asHeader = {
+        asHeader={
             'Accept': 'application/activity+json; profile="https://www.w3.org/ns/activitystreams"'
         }
-        personJson = \
+        personJson= \
             getJson(session,personUrl,asHeader,None,projectVersion, \
                     httpPrefix,personDomain)
         if not personJson:
@@ -258,7 +258,7 @@ def inboxPermittedMessage(domain: str,messageJson: {},federationList: []) -> boo
 def validPublishedDate(published: str) -> bool:
     currTime=datetime.datetime.utcnow()
     pubDate=datetime.datetime.strptime(published,"%Y-%m-%dT%H:%M:%SZ")
-    daysSincePublished = (currTime - pubTime).days
+    daysSincePublished=(currTime - pubTime).days
     if daysSincePublished>30:
         return False
     return True
@@ -340,7 +340,7 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str, \
         postId=postJsonObject['id'].replace('/activity','').replace('/undo','')
         published=currTime.strftime("%Y-%m-%dT%H:%M:%SZ")
     if not postId:
-        statusNumber,published = getStatusNumber()
+        statusNumber,published=getStatusNumber()
         if actor:
             postId=actor+'/statuses/'+statusNumber
         else:
@@ -372,7 +372,7 @@ def savePostToInboxQueue(baseDir: str,httpPrefix: str, \
             timeDiffStr='0'+timeDiffStr
         print('DIGEST|'+timeDiffStr+'|'+filename)
 
-    newQueueItem = {
+    newQueueItem={
         'originalId': originalPostId,
         'id': postId,
         'actor': actor,
@@ -531,7 +531,7 @@ def inboxPostRecipients(baseDir :str,postJsonObject :{}, \
                 domain=domain+':'+str(port)
     domainMatch='/'+domain+'/users/'
 
-    actor = postJsonObject['actor']
+    actor=postJsonObject['actor']
     # first get any specific people which the post is addressed to
     
     followerRecipients=False
@@ -1417,7 +1417,7 @@ def populateReplies(baseDir :str,httpPrefix :str,domain :str, \
     postRepliesFilename=postFilename.replace('.json','.replies')
     messageId=messageJson['id'].replace('/activity','').replace('/undo','')
     if os.path.isfile(postRepliesFilename):
-        numLines = sum(1 for line in open(postRepliesFilename))
+        numLines=sum(1 for line in open(postRepliesFilename))
         if numLines>maxReplies:
             return False
         if messageId not in open(postRepliesFilename).read():
@@ -1727,7 +1727,7 @@ def inboxUpdateIndex(boxname: str,baseDir: str,handle: str,destinationFilename:
     if os.path.isfile(indexFilename):
         try:
             with open(indexFilename, 'r+') as indexFile:
-                content = indexFile.read()
+                content=indexFile.read()
                 indexFile.seek(0, 0)
                 indexFile.write(destinationFilename+'\n'+content)
                 return True

+ 31 - 26
like.py

@@ -1,10 +1,10 @@
-__filename__ = "like.py"
-__author__ = "Bob Mottram"
-__license__ = "AGPL3+"
-__version__ = "1.1.0"
-__maintainer__ = "Bob Mottram"
-__email__ = "bob@freedombone.net"
-__status__ = "Production"
+__filename__="like.py"
+__author__="Bob Mottram"
+__license__="AGPL3+"
+__version__="1.1.0"
+__maintainer__="Bob Mottram"
+__email__="bob@freedombone.net"
+__status__="Production"
 
 import os
 import json
@@ -135,7 +135,7 @@ def updateLikesCollection(recentPostsCache: {}, \
         if not postJsonObject['object'].get('likes'):
             if debug:
                 print('DEBUG: Adding initial likes to '+objectUrl)
-            likesJson = {
+            likesJson={
                 "@context": "https://www.w3.org/ns/activitystreams",
                 'id': objectUrl,
                 'type': 'Collection',
@@ -193,7 +193,7 @@ def like(recentPostsCache: {}, \
     if '/statuses/' in objectUrl:
         likeTo=[objectUrl.split('/statuses/')[0]]
 
-    newLikeJson = {