flake8 format

merge-requests/30/head
Bob Mottram 2020-04-03 18:12:08 +00:00
parent 2bbfd60969
commit 7d47d27dec
1 changed files with 555 additions and 451 deletions

294
person.py
View File

@ -6,10 +6,8 @@ __maintainer__="Bob Mottram"
__email__ = "bob@freedombone.net" __email__ = "bob@freedombone.net"
__status__ = "Production" __status__ = "Production"
import json
import time import time
import os import os
import fileinput
import subprocess import subprocess
import shutil import shutil
from random import randint from random import randint
@ -37,25 +35,27 @@ from utils import validNickname
from utils import noOfAccounts from utils import noOfAccounts
from utils import loadJson from utils import loadJson
from utils import saveJson from utils import saveJson
from auth import createPassword
from config import setConfigParam from config import setConfigParam
from config import getConfigParam from config import getConfigParam
def generateRSAKey() -> (str, str): def generateRSAKey() -> (str, str):
key = RSA.generate(2048) key = RSA.generate(2048)
privateKeyPem = key.exportKey("PEM").decode("utf-8") privateKeyPem = key.exportKey("PEM").decode("utf-8")
publicKeyPem = key.publickey().exportKey("PEM").decode("utf-8") publicKeyPem = key.publickey().exportKey("PEM").decode("utf-8")
return privateKeyPem, publicKeyPem return privateKeyPem, publicKeyPem
def setProfileImage(baseDir: str,httpPrefix :str,nickname: str,domain: str, \
port :int,imageFilename: str,imageType :str,resolution :str) -> bool: def setProfileImage(baseDir: str, httpPrefix: str, nickname: str, domain: str,
port: int, imageFilename: str, imageType: str,
resolution: str) -> bool:
"""Saves the given image file as an avatar or background """Saves the given image file as an avatar or background
image for the given person image for the given person
""" """
imageFilename = imageFilename.replace('\n', '') imageFilename = imageFilename.replace('\n', '')
if not (imageFilename.endswith('.png') or \ if not (imageFilename.endswith('.png') or
imageFilename.endswith('.jpg') or \ imageFilename.endswith('.jpg') or
imageFilename.endswith('.jpeg') or \ imageFilename.endswith('.jpeg') or
imageFilename.endswith('.gif')): imageFilename.endswith('.gif')):
print('Profile image must be png, jpg or gif format') print('Profile image must be png, jpg or gif format')
return False return False
@ -101,7 +101,8 @@ def setProfileImage(baseDir: str,httpPrefix :str,nickname: str,domain: str, \
if personJson: if personJson:
personJson[iconFilenameBase]['mediaType'] = mediaType personJson[iconFilenameBase]['mediaType'] = mediaType
personJson[iconFilenameBase]['url'] = \ personJson[iconFilenameBase]['url'] = \
httpPrefix+'://'+fullDomain+'/users/'+nickname+'/'+iconFilename httpPrefix + '://' + fullDomain + '/users/' + \
nickname + '/'+iconFilename
saveJson(personJson, personFilename) saveJson(personJson, personFilename)
cmd = \ cmd = \
@ -112,7 +113,8 @@ def setProfileImage(baseDir: str,httpPrefix :str,nickname: str,domain: str, \
return True return True
return False return False
def setOrganizationScheme(baseDir: str,nickname: str,domain: str, \
def setOrganizationScheme(baseDir: str, nickname: str, domain: str,
schema: str) -> bool: schema: str) -> bool:
"""Set the organization schema within which a person exists """Set the organization schema within which a person exists
This will define how roles, skills and availability are assembled This will define how roles, skills and availability are assembled
@ -131,6 +133,7 @@ def setOrganizationScheme(baseDir: str,nickname: str,domain: str, \
saveJson(actorJson, actorFilename) saveJson(actorJson, actorFilename)
return True return True
def accountExists(baseDir: str, nickname: str, domain: str) -> bool: def accountExists(baseDir: str, nickname: str, domain: str) -> bool:
"""Returns true if the given account exists """Returns true if the given account exists
""" """
@ -139,6 +142,7 @@ def accountExists(baseDir: str,nickname: str,domain: str) -> bool:
return os.path.isdir(baseDir + '/accounts/' + nickname + '@' + domain) or \ return os.path.isdir(baseDir + '/accounts/' + nickname + '@' + domain) or \
os.path.isdir(baseDir + '/deactivated/' + nickname + '@' + domain) os.path.isdir(baseDir + '/deactivated/' + nickname + '@' + domain)
def randomizeActorImages(personJson: {}) -> None: def randomizeActorImages(personJson: {}) -> None:
"""Randomizes the filenames for avatar image and background """Randomizes the filenames for avatar image and background
This causes other instances to update their cached avatar image This causes other instances to update their cached avatar image
@ -146,20 +150,28 @@ def randomizeActorImages(personJson: {}) -> None:
personId = personJson['id'] personId = personJson['id']
lastPartOfFilename = personJson['icon']['url'].split('/')[-1] lastPartOfFilename = personJson['icon']['url'].split('/')[-1]
existingExtension = lastPartOfFilename.split('.')[1] existingExtension = lastPartOfFilename.split('.')[1]
personJson['icon']['url']=personId+'/avatar'+str(randint(10000000000000,99999999999999))+'.'+existingExtension personJson['icon']['url'] = \
personId + '/avatar' + str(randint(10000000000000, 99999999999999)) + \
'.' + existingExtension
lastPartOfFilename = personJson['image']['url'].split('/')[-1] lastPartOfFilename = personJson['image']['url'].split('/')[-1]
existingExtension = lastPartOfFilename.split('.')[1] existingExtension = lastPartOfFilename.split('.')[1]
personJson['image']['url']=personId+'/image'+str(randint(10000000000000,99999999999999))+'.'+existingExtension personJson['image']['url'] = \
personId + '/image' + str(randint(10000000000000, 99999999999999)) + \
'.' + existingExtension
def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}): def createPersonBase(baseDir: str, nickname: str, domain: str, port: int,
httpPrefix: str, saveToFile: bool,
password=None) -> (str, str, {}, {}):
"""Returns the private key, public key, actor and webfinger endpoint """Returns the private key, public key, actor and webfinger endpoint
""" """
privateKeyPem, publicKeyPem = generateRSAKey() privateKeyPem, publicKeyPem = generateRSAKey()
webfingerEndpoint = \ webfingerEndpoint = \
createWebfingerEndpoint(nickname,domain,port,httpPrefix,publicKeyPem) createWebfingerEndpoint(nickname, domain, port,
httpPrefix, publicKeyPem)
if saveToFile: if saveToFile:
storeWebfingerEndpoint(nickname,domain,port,baseDir,webfingerEndpoint) storeWebfingerEndpoint(nickname, domain, port,
baseDir, webfingerEndpoint)
handle = nickname.lower() + '@' + domain.lower() handle = nickname.lower() + '@' + domain.lower()
originalDomain = domain originalDomain = domain
@ -178,24 +190,45 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
# shared inbox # shared inbox
inboxStr = httpPrefix + '://' + domain + '/actor/inbox' inboxStr = httpPrefix + '://' + domain + '/actor/inbox'
personId = httpPrefix + '://' + domain + '/actor' personId = httpPrefix + '://' + domain + '/actor'
personUrl=httpPrefix+'://'+domain+'/about/more?instance_actor=true' personUrl = httpPrefix + '://' + domain + \
'/about/more?instance_actor=true'
personName = originalDomain personName = originalDomain
approveFollowers = True approveFollowers = True
personType = 'Application' personType = 'Application'
newPerson={ imageUrl = \
'@context': ['https://www.w3.org/ns/activitystreams', personId + '/image' + \
'https://w3id.org/security/v1', str(randint(10000000000000, 99999999999999)) + '.png'
{'Emoji': 'toot:Emoji',
iconUrl = \
personId + '/avatar' + \
str(randint(10000000000000, 99999999999999)) + '.png'
contextDict = {
'Emoji': 'toot:Emoji',
'Hashtag': 'as:Hashtag', 'Hashtag': 'as:Hashtag',
'IdentityProof': 'toot:IdentityProof', 'IdentityProof': 'toot:IdentityProof',
'PropertyValue': 'schema:PropertyValue', 'PropertyValue': 'schema:PropertyValue',
'alsoKnownAs': {'@id': 'as:alsoKnownAs', '@type': '@id'}, 'alsoKnownAs': {
'focalPoint': {'@container': '@list', '@id': 'toot:focalPoint'}, '@id': 'as:alsoKnownAs', '@type': '@id'
},
'focalPoint': {
'@container': '@list', '@id': 'toot:focalPoint'
},
'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers', 'manuallyApprovesFollowers': 'as:manuallyApprovesFollowers',
'movedTo': {'@id': 'as:movedTo', '@type': '@id'}, 'movedTo': {
'@id': 'as:movedTo', '@type': '@id'
},
'schema': 'http://schema.org#', 'schema': 'http://schema.org#',
'value': 'schema:value'}], 'value': 'schema:value'
}
newPerson = {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
contextDict
],
'attachment': [], 'attachment': [],
'alsoKnownAs': [], 'alsoKnownAs': [],
'discoverable': False, 'discoverable': False,
@ -214,13 +247,13 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
'icon': { 'icon': {
'mediaType': 'image/png', 'mediaType': 'image/png',
'type': 'Image', 'type': 'Image',
'url': personId+'/avatar'+str(randint(10000000000000,99999999999999))+'.png' 'url': iconUrl
}, },
'id': personId, 'id': personId,
'image': { 'image': {
'mediaType': 'image/png', 'mediaType': 'image/png',
'type': 'Image', 'type': 'Image',
'url': personId+'/image'+str(randint(10000000000000,99999999999999))+'.png' 'url': imageUrl
}, },
'inbox': inboxStr, 'inbox': inboxStr,
'manuallyApprovesFollowers': approveFollowers, 'manuallyApprovesFollowers': approveFollowers,
@ -268,7 +301,8 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
os.mkdir(baseDir + peopleSubdir + '/' + handle) os.mkdir(baseDir + peopleSubdir + '/' + handle)
if not os.path.isdir(baseDir + peopleSubdir + '/' + handle + '/inbox'): if not os.path.isdir(baseDir + peopleSubdir + '/' + handle + '/inbox'):
os.mkdir(baseDir + peopleSubdir + '/' + handle + '/inbox') os.mkdir(baseDir + peopleSubdir + '/' + handle + '/inbox')
if not os.path.isdir(baseDir+peopleSubdir+'/'+handle+'/outbox'): if not os.path.isdir(baseDir + peopleSubdir + '/' +
handle + '/outbox'):
os.mkdir(baseDir + peopleSubdir + '/' + handle + '/outbox') os.mkdir(baseDir + peopleSubdir + '/' + handle + '/outbox')
if not os.path.isdir(baseDir + peopleSubdir + '/' + handle + '/ocap'): if not os.path.isdir(baseDir + peopleSubdir + '/' + handle + '/ocap'):
os.mkdir(baseDir + peopleSubdir + '/' + handle + '/ocap') os.mkdir(baseDir + peopleSubdir + '/' + handle + '/ocap')
@ -282,7 +316,8 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
os.mkdir(baseDir + '/cache') os.mkdir(baseDir + '/cache')
if not os.path.isdir(baseDir + '/cache/actors'): if not os.path.isdir(baseDir + '/cache/actors'):
os.mkdir(baseDir + '/cache/actors') os.mkdir(baseDir + '/cache/actors')
cacheFilename=baseDir+'/cache/actors/'+newPerson['id'].replace('/','#')+'.json' cacheFilename = baseDir + '/cache/actors/' + \
newPerson['id'].replace('/', '#') + '.json'
saveJson(newPerson, cacheFilename) saveJson(newPerson, cacheFilename)
# save the private key # save the private key
@ -308,7 +343,8 @@ def createPersonBase(baseDir: str,nickname: str,domain: str,port: int, \
return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint
def registerAccount(baseDir: str,httpPrefix: str,domain: str,port: int, \
def registerAccount(baseDir: str, httpPrefix: str, domain: str, port: int,
nickname: str, password: str) -> bool: nickname: str, password: str) -> bool:
"""Registers a new account from the web interface """Registers a new account from the web interface
""" """
@ -320,25 +356,33 @@ def registerAccount(baseDir: str,httpPrefix: str,domain: str,port: int, \
if len(password) < 8: if len(password) < 8:
print('REGISTER: Password should be at least 8 characters') print('REGISTER: Password should be at least 8 characters')
return False return False
privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint= \ (privateKeyPem, publicKeyPem,
createPerson(baseDir,nickname,domain,port, \ newPerson, webfingerEndpoint) = createPerson(baseDir, nickname,
httpPrefix,True,password) domain, port,
httpPrefix, True,
password)
if privateKeyPem: if privateKeyPem:
return True return True
return False return False
def createGroup(baseDir: str,nickname: str,domain: str,port: int, \
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}): def createGroup(baseDir: str, nickname: str, domain: str, port: int,
httpPrefix: str, saveToFile: bool,
password=None) -> (str, str, {}, {}):
"""Returns a group """Returns a group
""" """
privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint= \ (privateKeyPem, publicKeyPem,
createPerson(baseDir,nickname,domain,port, \ newPerson, webfingerEndpoint) = createPerson(baseDir, nickname,
httpPrefix,saveToFile,password) domain, port,
httpPrefix, saveToFile,
password)
newPerson['type'] = 'Group' newPerson['type'] = 'Group'
return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint
def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
httpPrefix: str, saveToFile: bool,password=None) -> (str,str,{},{}): def createPerson(baseDir: str, nickname: str, domain: str, port: int,
httpPrefix: str, saveToFile: bool,
password=None) -> (str, str, {}, {}):
"""Returns the private key, public key, actor and webfinger endpoint """Returns the private key, public key, actor and webfinger endpoint
""" """
if not validNickname(domain, nickname): if not validNickname(domain, nickname):
@ -352,8 +396,11 @@ def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
if registrationsRemaining <= 0: if registrationsRemaining <= 0:
return None, None, None, None return None, None, None, None
privateKeyPem,publicKeyPem,newPerson,webfingerEndpoint= \ (privateKeyPem, publicKeyPem,
createPersonBase(baseDir,nickname,domain,port,httpPrefix,saveToFile,password) newPerson, webfingerEndpoint) = createPersonBase(baseDir, nickname,
domain, port,
httpPrefix,
saveToFile, password)
if noOfAccounts(baseDir) == 1: if noOfAccounts(baseDir) == 1:
# print(nickname+' becomes the instance admin and a moderator') # print(nickname+' becomes the instance admin and a moderator')
setRole(baseDir, nickname, domain, 'instance', 'admin') setRole(baseDir, nickname, domain, 'instance', 'admin')
@ -367,38 +414,50 @@ def createPerson(baseDir: str,nickname: str,domain: str,port: int, \
os.mkdir(baseDir + '/accounts/' + nickname + '@' + domain) os.mkdir(baseDir + '/accounts/' + nickname + '@' + domain)
if os.path.isfile(baseDir + '/img/default-avatar.png'): if os.path.isfile(baseDir + '/img/default-avatar.png'):
copyfile(baseDir+'/img/default-avatar.png',baseDir+'/accounts/'+nickname+'@'+domain+'/avatar.png') copyfile(baseDir + '/img/default-avatar.png',
baseDir + '/accounts/' + nickname + '@' + domain +
'/avatar.png')
theme = getConfigParam(baseDir, 'theme') theme = getConfigParam(baseDir, 'theme')
defaultProfileImageFilename = baseDir + '/img/image.png' defaultProfileImageFilename = baseDir + '/img/image.png'
if theme: if theme:
if os.path.isfile(baseDir + '/img/image_' + theme + '.png'): if os.path.isfile(baseDir + '/img/image_' + theme + '.png'):
defaultBannerFilename = baseDir + '/img/image_' + theme + '.png' defaultBannerFilename = baseDir + '/img/image_' + theme + '.png'
if os.path.isfile(defaultProfileImageFilename): if os.path.isfile(defaultProfileImageFilename):
copyfile(defaultProfileImageFilename,baseDir+'/accounts/'+nickname+'@'+domain+'/image.png') copyfile(defaultProfileImageFilename, baseDir +
'/accounts/' + nickname + '@' + domain + '/image.png')
defaultBannerFilename = baseDir + '/img/banner.png' defaultBannerFilename = baseDir + '/img/banner.png'
if theme: if theme:
if os.path.isfile(baseDir + '/img/banner_' + theme + '.png'): if os.path.isfile(baseDir + '/img/banner_' + theme + '.png'):
defaultBannerFilename = baseDir + '/img/banner_' + theme + '.png' defaultBannerFilename = baseDir + '/img/banner_' + theme + '.png'
if os.path.isfile(defaultBannerFilename): if os.path.isfile(defaultBannerFilename):
copyfile(defaultBannerFilename,baseDir+'/accounts/'+nickname+'@'+domain+'/banner.png') copyfile(defaultBannerFilename, baseDir + '/accounts/' +
nickname + '@' + domain + '/banner.png')
if remainingConfigExists: if remainingConfigExists:
registrationsRemaining -= 1 registrationsRemaining -= 1
setConfigParam(baseDir,'registrationsRemaining',str(registrationsRemaining)) setConfigParam(baseDir, 'registrationsRemaining',
str(registrationsRemaining))
return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint return privateKeyPem, publicKeyPem, newPerson, webfingerEndpoint
def createSharedInbox(baseDir: str,nickname: str,domain: str,port: int, \
def createSharedInbox(baseDir: str, nickname: str, domain: str, port: int,
httpPrefix: str) -> (str, str, {}, {}): httpPrefix: str) -> (str, str, {}, {}):
"""Generates the shared inbox """Generates the shared inbox
""" """
return createPersonBase(baseDir,nickname,domain,port,httpPrefix,True,None) return createPersonBase(baseDir, nickname, domain, port, httpPrefix,
True, None)
def createCapabilitiesInbox(baseDir: str,nickname: str,domain: str,port: int, \
def createCapabilitiesInbox(baseDir: str, nickname: str,
domain: str, port: int,
httpPrefix: str) -> (str, str, {}, {}): httpPrefix: str) -> (str, str, {}, {}):
"""Generates the capabilities inbox to sign requests """Generates the capabilities inbox to sign requests
""" """
return createPersonBase(baseDir,nickname,domain,port,httpPrefix,True,None) return createPersonBase(baseDir, nickname, domain, port,
httpPrefix, True, None)
def personUpgradeActor(baseDir: str,personJson: {},handle: str,filename: str) -> None:
def personUpgradeActor(baseDir: str, personJson: {},
handle: str, filename: str) -> None:
"""Alter the actor to add any new properties """Alter the actor to add any new properties
""" """
updateActor = False updateActor = False
@ -431,10 +490,12 @@ def personUpgradeActor(baseDir: str,personJson: {},handle: str,filename: str) ->
# update domain/@nickname in actors cache # update domain/@nickname in actors cache
actorCacheFilename = \ actorCacheFilename = \
baseDir + '/accounts/cache/actors/' + \ baseDir + '/accounts/cache/actors/' + \
personJson['id'].replace('/users/','/@').replace('/','#')+'.json' personJson['id'].replace('/users/', '/@').replace('/', '#') + \
'.json'
if os.path.isfile(actorCacheFilename): if os.path.isfile(actorCacheFilename):
saveJson(personJson, actorCacheFilename) saveJson(personJson, actorCacheFilename)
def personLookup(domain: str, path: str, baseDir: str) -> {}: def personLookup(domain: str, path: str, baseDir: str) -> {}:
"""Lookup the person for an given nickname """Lookup the person for an given nickname
""" """
@ -447,9 +508,9 @@ def personLookup(domain: str,path: str,baseDir: str) -> {}:
path = '/users/' + domain path = '/users/' + domain
isSharedInbox = True isSharedInbox = True
else: else:
notPersonLookup=['/inbox','/outbox','/outboxarchive', \ notPersonLookup = ('/inbox', '/outbox', '/outboxarchive',
'/followers','/following','/featured', \ '/followers', '/following', '/featured',
'.png','.jpg','.gif','.mpv'] '.png', '.jpg', '.gif', '.mpv')
for ending in notPersonLookup: for ending in notPersonLookup:
if path.endswith(ending): if path.endswith(ending):
return None return None
@ -474,9 +535,10 @@ def personLookup(domain: str,path: str,baseDir: str) -> {}:
# personJson={"user": "unknown"} # personJson={"user": "unknown"}
return personJson return personJson
def personBoxJson(recentPostsCache: {}, \
session,baseDir: str,domain: str,port: int,path: str, \ def personBoxJson(recentPostsCache: {},
httpPrefix: str,noOfItems: int,boxname: str, \ session, baseDir: str, domain: str, port: int, path: str,
httpPrefix: str, noOfItems: int, boxname: str,
authorized: bool, ocapAlways: bool) -> {}: authorized: bool, ocapAlways: bool) -> {}:
"""Obtain the inbox/outbox/moderation feed for the given person """Obtain the inbox/outbox/moderation feed for the given person
""" """
@ -502,7 +564,7 @@ def personBoxJson(recentPostsCache: {}, \
else: else:
try: try:
pageNumber = int(pageNumber) pageNumber = int(pageNumber)
except: except BaseException:
pass pass
path = path.split('?page=')[0] path = path.split('?page=')[0]
headerOnly = False headerOnly = False
@ -519,39 +581,54 @@ def personBoxJson(recentPostsCache: {}, \
if not validNickname(domain, nickname): if not validNickname(domain, nickname):
return None return None
if boxname == 'inbox': if boxname == 'inbox':
return createInbox(recentPostsCache, \ return createInbox(recentPostsCache,
session,baseDir,nickname,domain,port,httpPrefix, \ session, baseDir, nickname, domain, port,
httpPrefix,
noOfItems, headerOnly, ocapAlways, pageNumber) noOfItems, headerOnly, ocapAlways, pageNumber)
elif boxname == 'dm': elif boxname == 'dm':
return createDMTimeline(session,baseDir,nickname,domain,port,httpPrefix, \ return createDMTimeline(session, baseDir, nickname, domain, port,
httpPrefix,
noOfItems, headerOnly, ocapAlways, pageNumber) noOfItems, headerOnly, ocapAlways, pageNumber)
elif boxname == 'tlbookmarks': elif boxname == 'tlbookmarks':
return createBookmarksTimeline(session,baseDir,nickname,domain,port,httpPrefix, \ return createBookmarksTimeline(session, baseDir, nickname, domain,
noOfItems,headerOnly,ocapAlways,pageNumber) port, httpPrefix,
noOfItems, headerOnly, ocapAlways,
pageNumber)
elif boxname == 'tlreplies': elif boxname == 'tlreplies':
return createRepliesTimeline(session,baseDir,nickname,domain,port,httpPrefix, \ return createRepliesTimeline(session, baseDir, nickname, domain,
noOfItems,headerOnly,ocapAlways,pageNumber) port, httpPrefix,
noOfItems, headerOnly, ocapAlways,
pageNumber)
elif boxname == 'tlmedia': elif boxname == 'tlmedia':
return createMediaTimeline(session,baseDir,nickname,domain,port,httpPrefix, \ return createMediaTimeline(session, baseDir, nickname, domain, port,
noOfItems,headerOnly,ocapAlways,pageNumber) httpPrefix,
noOfItems, headerOnly, ocapAlways,
pageNumber)
elif boxname == 'tlblogs': elif boxname == 'tlblogs':
return createBlogsTimeline(session,baseDir,nickname,domain,port,httpPrefix, \ return createBlogsTimeline(session, baseDir, nickname, domain, port,
noOfItems,headerOnly,ocapAlways,pageNumber) httpPrefix,
noOfItems, headerOnly, ocapAlways,
pageNumber)
elif boxname == 'outbox': elif boxname == 'outbox':
return createOutbox(session,baseDir,nickname,domain,port,httpPrefix, \ return createOutbox(session, baseDir, nickname, domain, port,
noOfItems,headerOnly,authorized,pageNumber) httpPrefix,
noOfItems, headerOnly, authorized,
pageNumber)
elif boxname == 'moderation': elif boxname == 'moderation':
return createModeration(baseDir,nickname,domain,port,httpPrefix, \ return createModeration(baseDir, nickname, domain, port,
noOfItems,headerOnly,authorized,pageNumber) httpPrefix,
noOfItems, headerOnly, authorized,
pageNumber)
return None return None
def personInboxJson(recentPostsCache: {}, \
baseDir: str,domain: str,port: int,path: str, \ def personInboxJson(recentPostsCache: {},
baseDir: str, domain: str, port: int, path: str,
httpPrefix: str, noOfItems: int, ocapAlways: bool) -> []: httpPrefix: str, noOfItems: int, ocapAlways: bool) -> []:
"""Obtain the inbox feed for the given person """Obtain the inbox feed for the given person
Authentication is expected to have already happened Authentication is expected to have already happened
""" """
if not '/inbox' in path: if '/inbox' not in path:
return None return None
# Only show the header by default # Only show the header by default
@ -566,7 +643,7 @@ def personInboxJson(recentPostsCache: {}, \
else: else:
try: try:
pageNumber = int(pageNumber) pageNumber = int(pageNumber)
except: except BaseException:
pass pass
path = path.split('?page=')[0] path = path.split('?page=')[0]
headerOnly = False headerOnly = False
@ -582,10 +659,12 @@ def personInboxJson(recentPostsCache: {}, \
return None return None
if not validNickname(domain, nickname): if not validNickname(domain, nickname):
return None return None
return createInbox(recentPostsCache,baseDir,nickname,domain,port,httpPrefix, \ return createInbox(recentPostsCache, baseDir, nickname,
domain, port, httpPrefix,
noOfItems, headerOnly, ocapAlways, pageNumber) noOfItems, headerOnly, ocapAlways, pageNumber)
def setDisplayNickname(baseDir: str,nickname: str, domain: str, \
def setDisplayNickname(baseDir: str, nickname: str, domain: str,
displayName: str) -> bool: displayName: str) -> bool:
if len(displayName) > 32: if len(displayName) > 32:
return False return False
@ -601,6 +680,7 @@ def setDisplayNickname(baseDir: str,nickname: str, domain: str, \
saveJson(personJson, filename) saveJson(personJson, filename)
return True return True
def setBio(baseDir: str, nickname: str, domain: str, bio: str) -> bool: def setBio(baseDir: str, nickname: str, domain: str, bio: str) -> bool:
if len(bio) > 32: if len(bio) > 32:
return False return False
@ -619,6 +699,7 @@ def setBio(baseDir: str,nickname: str, domain: str, bio: str) -> bool:
saveJson(personJson, filename) saveJson(personJson, filename)
return True return True
def isSuspended(baseDir: str, nickname: str) -> bool: def isSuspended(baseDir: str, nickname: str) -> bool:
"""Returns true if the given nickname is suspended """Returns true if the given nickname is suspended
""" """
@ -630,12 +711,12 @@ def isSuspended(baseDir: str,nickname: str) -> bool:
if os.path.isfile(suspendedFilename): if os.path.isfile(suspendedFilename):
with open(suspendedFilename, "r") as f: with open(suspendedFilename, "r") as f:
lines = f.readlines() lines = f.readlines()
suspendedFile=open(suspendedFilename,"w+")
for suspended in lines: for suspended in lines:
if suspended.strip('\n') == nickname: if suspended.strip('\n') == nickname:
return True return True
return False return False
def unsuspendAccount(baseDir: str, nickname: str) -> None: def unsuspendAccount(baseDir: str, nickname: str) -> None:
"""Removes an account suspention """Removes an account suspention
""" """
@ -649,6 +730,7 @@ def unsuspendAccount(baseDir: str,nickname: str) -> None:
suspendedFile.write(suspended) suspendedFile.write(suspended)
suspendedFile.close() suspendedFile.close()
def suspendAccount(baseDir: str, nickname: str, domain: str) -> None: def suspendAccount(baseDir: str, nickname: str, domain: str) -> None:
"""Suspends the given account """Suspends the given account
""" """
@ -666,10 +748,12 @@ def suspendAccount(baseDir: str,nickname: str,domain: str) -> None:
if moderator.strip('\n') == nickname: if moderator.strip('\n') == nickname:
return return
saltFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/.salt' saltFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/.salt'
if os.path.isfile(saltFilename): if os.path.isfile(saltFilename):
os.remove(saltFilename) os.remove(saltFilename)
tokenFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/.token' tokenFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/.token'
if os.path.isfile(tokenFilename): if os.path.isfile(tokenFilename):
os.remove(tokenFilename) os.remove(tokenFilename)
@ -690,7 +774,9 @@ def suspendAccount(baseDir: str,nickname: str,domain: str) -> None:
suspendedFile.write(nickname + '\n') suspendedFile.write(nickname + '\n')
suspendedFile.close() suspendedFile.close()
def canRemovePost(baseDir: str,nickname: str,domain: str,port: int,postId: str) -> bool:
def canRemovePost(baseDir: str, nickname: str,
domain: str, port: int, postId: str) -> bool:
"""Returns true if the given post can be removed """Returns true if the given post can be removed
""" """
if '/statuses/' not in postId: if '/statuses/' not in postId:
@ -717,7 +803,9 @@ def canRemovePost(baseDir: str,nickname: str,domain: str,port: int,postId: str)
return False return False
return True return True
def removeTagsForNickname(baseDir: str,nickname: str,domain: str,port: int) -> None:
def removeTagsForNickname(baseDir: str, nickname: str,
domain: str, port: int) -> None:
"""Removes tags for a nickname """Removes tags for a nickname
""" """
if not os.path.isdir(baseDir + '/tags'): if not os.path.isdir(baseDir + '/tags'):
@ -748,7 +836,9 @@ def removeTagsForNickname(baseDir: str,nickname: str,domain: str,port: int) -> N
tagFile.write(tagline) tagFile.write(tagline)
tagFile.close() tagFile.close()
def removeAccount(baseDir: str,nickname: str,domain: str,port: int) -> bool:
def removeAccount(baseDir: str, nickname: str,
domain: str, port: int) -> bool:
"""Removes an account """Removes an account
""" """
# Don't remove the admin # Don't remove the admin
@ -789,6 +879,7 @@ def removeAccount(baseDir: str,nickname: str,domain: str,port: int) -> bool:
shutil.rmtree(baseDir + '/sharefilesdeactivated/' + nickname) shutil.rmtree(baseDir + '/sharefilesdeactivated/' + nickname)
return True return True
def deactivateAccount(baseDir: str, nickname: str, domain: str) -> bool: def deactivateAccount(baseDir: str, nickname: str, domain: str) -> bool:
"""Makes an account temporarily unavailable """Makes an account temporarily unavailable
""" """
@ -806,15 +897,18 @@ def deactivateAccount(baseDir: str,nickname: str,domain: str) -> bool:
deactivatedWebfingerDir = baseDir + '/wfdeactivated' deactivatedWebfingerDir = baseDir + '/wfdeactivated'
if not os.path.isdir(deactivatedWebfingerDir): if not os.path.isdir(deactivatedWebfingerDir):
os.mkdir(deactivatedWebfingerDir) os.mkdir(deactivatedWebfingerDir)
shutil.move(baseDir+'/wfendpoints/'+handle+'.json',deactivatedWebfingerDir+'/'+handle+'.json') shutil.move(baseDir + '/wfendpoints/' + handle + '.json',
deactivatedWebfingerDir + '/' + handle + '.json')
if os.path.isdir(baseDir + '/sharefiles/' + nickname): if os.path.isdir(baseDir + '/sharefiles/' + nickname):
deactivatedSharefilesDir = baseDir + '/sharefilesdeactivated' deactivatedSharefilesDir = baseDir + '/sharefilesdeactivated'
if not os.path.isdir(deactivatedSharefilesDir): if not os.path.isdir(deactivatedSharefilesDir):
os.mkdir(deactivatedSharefilesDir) os.mkdir(deactivatedSharefilesDir)
shutil.move(baseDir+'/sharefiles/'+nickname,deactivatedSharefilesDir+'/'+nickname) shutil.move(baseDir + '/sharefiles/' + nickname,
deactivatedSharefilesDir + '/' + nickname)
return os.path.isdir(deactivatedDir + '/' + nickname + '@' + domain) return os.path.isdir(deactivatedDir + '/' + nickname + '@' + domain)
def activateAccount(baseDir: str, nickname: str, domain: str) -> None: def activateAccount(baseDir: str, nickname: str, domain: str) -> None:
"""Makes a deactivated account available """Makes a deactivated account available
""" """
@ -829,17 +923,22 @@ def activateAccount(baseDir: str,nickname: str,domain: str) -> None:
deactivatedWebfingerDir = baseDir + '/wfdeactivated' deactivatedWebfingerDir = baseDir + '/wfdeactivated'
if os.path.isfile(deactivatedWebfingerDir + '/' + handle + '.json'): if os.path.isfile(deactivatedWebfingerDir + '/' + handle + '.json'):
shutil.move(deactivatedWebfingerDir+'/'+handle+'.json',baseDir+'/wfendpoints/'+handle+'.json') shutil.move(deactivatedWebfingerDir + '/' + handle + '.json',
baseDir + '/wfendpoints/' + handle + '.json')
deactivatedSharefilesDir = baseDir + '/sharefilesdeactivated' deactivatedSharefilesDir = baseDir + '/sharefilesdeactivated'
if os.path.isdir(deactivatedSharefilesDir + '/' + nickname): if os.path.isdir(deactivatedSharefilesDir + '/' + nickname):
if not os.path.isdir(baseDir + '/sharefiles/' + nickname): if not os.path.isdir(baseDir + '/sharefiles/' + nickname):
shutil.move(deactivatedSharefilesDir+'/'+nickname,baseDir+'/sharefiles/'+nickname) shutil.move(deactivatedSharefilesDir + '/' + nickname,
baseDir + '/sharefiles/' + nickname)
def isPersonSnoozed(baseDir: str,nickname: str,domain: str,snoozeActor: str) -> bool:
def isPersonSnoozed(baseDir: str, nickname: str, domain: str,
snoozeActor: str) -> bool:
"""Returns true if the given actor is snoozed """Returns true if the given actor is snoozed
""" """
snoozedFilename=baseDir+'/accounts/'+nickname+'@'+domain+'/snoozed.txt' snoozedFilename = baseDir + '/accounts/' + \
nickname + '@' + domain + '/snoozed.txt'
if not os.path.isfile(snoozedFilename): if not os.path.isfile(snoozedFilename):
return False return False
if snoozeActor + ' ' not in open(snoozedFilename).read(): if snoozeActor + ' ' not in open(snoozedFilename).read():
@ -875,7 +974,9 @@ def isPersonSnoozed(baseDir: str,nickname: str,domain: str,snoozeActor: str) ->
return True return True
return False return False
def personSnooze(baseDir: str,nickname: str,domain: str,snoozeActor: str) -> None:
def personSnooze(baseDir: str, nickname: str, domain: str,
snoozeActor: str) -> None:
"""Temporarily ignores the given actor """Temporarily ignores the given actor
""" """
accountDir = baseDir + '/accounts/' + nickname + '@' + domain accountDir = baseDir + '/accounts/' + nickname + '@' + domain
@ -888,10 +989,13 @@ def personSnooze(baseDir: str,nickname: str,domain: str,snoozeActor: str) -> Non
return return
snoozedFile = open(snoozedFilename, "a+") snoozedFile = open(snoozedFilename, "a+")
if snoozedFile: if snoozedFile:
snoozedFile.write(snoozeActor+' '+str(int(time.time()))+'\n') snoozedFile.write(snoozeActor + ' ' +
str(int(time.time())) + '\n')
snoozedFile.close() snoozedFile.close()
def personUnsnooze(baseDir: str,nickname: str,domain: str,snoozeActor: str) -> None:
def personUnsnooze(baseDir: str, nickname: str, domain: str,
snoozeActor: str) -> None:
"""Undoes a temporarily ignore of the given actor """Undoes a temporarily ignore of the given actor
""" """
accountDir = baseDir + '/accounts/' + nickname + '@' + domain accountDir = baseDir + '/accounts/' + nickname + '@' + domain