2019-06-28 18:55:29 +00:00
__filename__ = " epicyon.py "
__author__ = " Bob Mottram "
__license__ = " AGPL3+ "
__version__ = " 0.0.1 "
__maintainer__ = " Bob Mottram "
__email__ = " bob@freedombone.net "
__status__ = " Production "
2019-07-12 19:08:46 +00:00
2019-06-28 18:55:29 +00:00
from person import createPerson
2019-07-05 11:27:18 +00:00
from person import createSharedInbox
2019-07-05 21:24:16 +00:00
from person import createCapabilitiesInbox
2019-07-03 09:40:27 +00:00
from person import setPreferredNickname
2019-06-28 20:00:25 +00:00
from person import setBio
2019-07-05 21:27:49 +00:00
from person import validNickname
2019-07-12 14:31:56 +00:00
from person import setProfileImage
2019-07-14 12:29:08 +00:00
from person import setSkillLevel
from person import setRole
2019-07-14 13:30:59 +00:00
from person import setAvailability
2019-07-14 14:42:00 +00:00
from person import setOrganizationScheme
2019-06-28 18:55:29 +00:00
from webfinger import webfingerHandle
2019-07-02 09:25:29 +00:00
from posts import getPosts
2019-06-29 10:08:59 +00:00
from posts import createPublicPost
2019-06-29 11:47:33 +00:00
from posts import deleteAllPosts
2019-06-29 13:17:02 +00:00
from posts import createOutbox
2019-06-29 13:44:21 +00:00
from posts import archivePosts
2019-07-16 16:43:28 +00:00
from posts import sendPostViaServer
2019-07-03 10:31:02 +00:00
from posts import getPublicPostsOfPerson
2019-07-05 15:53:26 +00:00
from posts import getUserUrl
2019-07-12 20:43:55 +00:00
from posts import archivePosts
2019-06-28 18:55:29 +00:00
from session import createSession
2019-06-29 16:47:37 +00:00
from session import getJson
2019-07-14 19:57:05 +00:00
from blocking import addBlock
from blocking import removeBlock
2019-07-14 20:50:27 +00:00
from filters import addFilter
from filters import removeFilter
2019-06-28 18:55:29 +00:00
import json
2019-06-30 22:56:37 +00:00
import os
2019-07-04 22:51:40 +00:00
import shutil
2019-06-28 18:55:29 +00:00
import sys
import requests
from pprint import pprint
2019-06-30 20:14:03 +00:00
from tests import testHttpsig
2019-06-28 18:55:29 +00:00
from daemon import runDaemon
2019-06-28 19:52:35 +00:00
import socket
2019-06-29 18:23:13 +00:00
from follow import clearFollows
2019-06-29 20:21:37 +00:00
from follow import clearFollowers
2019-07-06 19:24:52 +00:00
from utils import followPerson
2019-06-29 18:23:13 +00:00
from follow import followerOfPerson
from follow import unfollowPerson
from follow import unfollowerOfPerson
2019-07-05 12:35:29 +00:00
from follow import getFollowersOfPerson
2019-06-30 21:20:02 +00:00
from tests import testPostMessageBetweenServers
2019-07-06 13:49:25 +00:00
from tests import testFollowBetweenServers
2019-07-16 10:19:04 +00:00
from tests import testClientToServer
2019-06-30 21:20:02 +00:00
from tests import runAllTests
2019-07-05 09:20:54 +00:00
from config import setConfigParam
from config import getConfigParam
2019-07-05 09:44:15 +00:00
from auth import storeBasicCredentials
2019-07-05 09:49:57 +00:00
from auth import removePassword
2019-07-05 11:27:18 +00:00
from auth import createPassword
2019-07-09 15:51:31 +00:00
from utils import getDomainFromActor
from utils import getNicknameFromActor
2019-07-12 20:43:55 +00:00
from media import archiveMedia
2019-07-03 09:24:55 +00:00
import argparse
2019-06-30 21:20:02 +00:00
2019-07-03 09:24:55 +00:00
def str2bool ( v ) :
if isinstance ( v , bool ) :
return v
if v . lower ( ) in ( ' yes ' , ' true ' , ' t ' , ' y ' , ' 1 ' ) :
return True
elif v . lower ( ) in ( ' no ' , ' false ' , ' f ' , ' n ' , ' 0 ' ) :
return False
else :
raise argparse . ArgumentTypeError ( ' Boolean value expected. ' )
2019-07-05 09:20:54 +00:00
2019-07-03 09:24:55 +00:00
parser = argparse . ArgumentParser ( description = ' ActivityPub Server ' )
2019-07-09 15:51:31 +00:00
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 , \
help = ' Handle of account to follow. eg. nickname@domain ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' -d ' , ' --domain ' , dest = ' domain ' , type = str , default = None , \
2019-07-03 09:24:55 +00:00
help = ' Domain name of the server ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' -p ' , ' --port ' , dest = ' port ' , type = int , default = None , \
2019-07-03 09:24:55 +00:00
help = ' Port number to run on ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --path ' , dest = ' baseDir ' , \
type = str , default = os . getcwd ( ) , \
2019-07-03 09:24:55 +00:00
help = ' Directory in which to store posts ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' -a ' , ' --addaccount ' , dest = ' addaccount ' , \
type = str , default = None , \
2019-07-04 22:44:32 +00:00
help = ' Adds a new account ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' -r ' , ' --rmaccount ' , dest = ' rmaccount ' , \
type = str , default = None , \
2019-07-04 22:50:40 +00:00
help = ' Remove an account ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --pass ' , ' --password ' , dest = ' password ' , \
type = str , default = None , \
2019-07-04 22:44:32 +00:00
help = ' Set a password for an account ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --chpass ' , ' --changepassword ' , \
nargs = ' + ' , dest = ' changepassword ' , \
2019-07-05 09:44:15 +00:00
help = ' Change the password for an account ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --actor ' , dest = ' actor ' , type = str , default = None , \
2019-07-05 15:53:26 +00:00
help = ' Show the json actor the given handle ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --posts ' , dest = ' posts ' , type = str , default = None , \
2019-07-03 10:31:02 +00:00
help = ' Show posts for the given handle ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' --postsraw ' , dest = ' postsraw ' , type = str , default = None , \
2019-07-03 11:24:38 +00:00
help = ' Show raw json of posts for the given handle ' )
2019-07-12 10:53:49 +00:00
parser . add_argument ( ' --json ' , dest = ' json ' , type = str , default = None , \
help = ' Show the json for a given activitypub url ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( ' -f ' , ' --federate ' , nargs = ' + ' , dest = ' federationList ' , \
2019-07-03 09:24:55 +00:00
help = ' Specify federation list separated by spaces ' )
2019-07-06 20:19:49 +00:00
parser . add_argument ( " --debug " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Show debug messages " )
parser . add_argument ( " --http " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Use http only " )
parser . add_argument ( " --dat " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Use dat protocol only " )
parser . add_argument ( " --tor " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Route via Tor " )
parser . add_argument ( " --tests " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Run unit tests " )
parser . add_argument ( " --testsnetwork " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Run network unit tests " )
parser . add_argument ( " --testdata " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Generate some data for testing purposes " )
2019-07-07 17:47:37 +00:00
parser . add_argument ( " --ocap " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Always strictly enforce object capabilities " )
2019-07-09 17:54:08 +00:00
parser . add_argument ( " --noreply " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Default capabilities don ' t allow replies on posts " )
parser . add_argument ( " --nolike " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Default capabilities don ' t allow likes/favourites on posts " )
2019-07-09 18:11:23 +00:00
parser . add_argument ( " --nopics " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Default capabilities don ' t allow attached pictures " )
parser . add_argument ( " --noannounce " , " --norepeat " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Default capabilities don ' t allow announce/repeat " )
parser . add_argument ( " --cw " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Default capabilities don ' t allow posts without content warnings " )
2019-07-12 14:31:56 +00:00
parser . add_argument ( ' --icon ' , ' --avatar ' , dest = ' avatar ' , type = str , default = None , \
help = ' Set the avatar filename for an account ' )
2019-07-12 14:40:03 +00:00
parser . add_argument ( ' --image ' , ' --background ' , dest = ' backgroundImage ' , type = str , default = None , \
help = ' Set the profile background image for an account ' )
2019-07-12 20:43:55 +00:00
parser . add_argument ( ' --archive ' , dest = ' archive ' , type = str , default = None , \
help = ' Archive old files to the given directory ' )
parser . add_argument ( ' --archiveweeks ' , dest = ' archiveWeeks ' , type = str , default = None , \
help = ' Specify the number of weeks after which data will be archived ' )
parser . add_argument ( ' --maxposts ' , dest = ' archiveMaxPosts ' , type = str , default = None , \
help = ' Maximum number of posts in in/outbox ' )
2019-07-12 22:29:10 +00:00
parser . add_argument ( ' --message ' , dest = ' message ' , type = str , default = None , \
help = ' Message content ' )
2019-07-16 20:08:30 +00:00
parser . add_argument ( ' --repeat ' , ' --announce ' , dest = ' announce ' , type = str , default = None , \
help = ' Announce/repeat a url ' )
2019-07-12 22:29:10 +00:00
parser . add_argument ( ' --sendto ' , nargs = ' + ' , dest = ' sendto ' , \
help = ' List of post recipients ' )
parser . add_argument ( ' --attach ' , dest = ' attach ' , type = str , default = None , \
help = ' File to attach to a post ' )
parser . add_argument ( ' --imagedescription ' , dest = ' imageDescription ' , type = str , default = None , \
help = ' Description of an attached image ' )
parser . add_argument ( " --blurhash " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Create blurhash for an image " )
2019-07-15 14:45:57 +00:00
parser . add_argument ( ' --warning ' , ' --warn ' , ' --cwsubject ' , ' --subject ' , dest = ' subject ' , type = str , default = None , \
2019-07-12 22:29:10 +00:00
help = ' Subject of content warning ' )
parser . add_argument ( ' --reply ' , ' --replyto ' , dest = ' replyto ' , type = str , default = None , \
help = ' Url of post to reply to ' )
2019-07-13 09:22:25 +00:00
parser . add_argument ( " --followersonly " , type = str2bool , nargs = ' ? ' , \
const = True , default = True , \
help = " Send to followers only " )
parser . add_argument ( " -c " , " --client " , type = str2bool , nargs = ' ? ' , \
const = True , default = False , \
help = " Use as an ActivityPub client " )
2019-07-13 21:00:12 +00:00
parser . add_argument ( ' --maxreplies ' , dest = ' maxReplies ' , type = int , default = 64 , \
help = ' Maximum number of replies to a post ' )
2019-07-14 13:07:54 +00:00
parser . add_argument ( ' --role ' , dest = ' role ' , type = str , default = None , \
help = ' Set a role for a person ' )
parser . add_argument ( ' --organization ' , ' --project ' , dest = ' project ' , type = str , default = None , \
help = ' Set a project for a person ' )
parser . add_argument ( ' --skill ' , dest = ' skill ' , type = str , default = None , \
help = ' Set a skill for a person ' )
parser . add_argument ( ' --level ' , dest = ' skillLevelPercent ' , type = int , default = None , \
help = ' Set a skill level for a person as a percentage, or zero to remove ' )
2019-07-14 13:30:59 +00:00
parser . add_argument ( ' --status ' , ' --availability ' , dest = ' availability ' , type = str , default = None , \
help = ' Set an availability status ' )
2019-07-14 19:57:05 +00:00
parser . add_argument ( ' --block ' , dest = ' block ' , type = str , default = None , \
help = ' Block a particular address ' )
parser . add_argument ( ' --unblock ' , dest = ' unblock ' , type = str , default = None , \
help = ' Remove a block on a particular address ' )
2019-07-14 20:50:27 +00:00
parser . add_argument ( ' --filter ' , dest = ' filterStr ' , type = str , default = None , \
help = ' Adds a word or phrase which if present will cause a message to be ignored ' )
parser . add_argument ( ' --unfilter ' , dest = ' unfilterStr ' , type = str , default = None , \
help = ' Remove a filter on a particular word or phrase ' )
2019-07-15 10:27:53 +00:00
parser . add_argument ( ' --domainmax ' , dest = ' domainMaxPostsPerDay ' , type = int , default = 8640 , \
2019-07-15 10:22:19 +00:00
help = ' Maximum number of received posts from a domain per day ' )
2019-07-15 10:27:53 +00:00
parser . add_argument ( ' --accountmax ' , dest = ' accountMaxPostsPerDay ' , type = int , default = 8640 , \
2019-07-15 10:22:19 +00:00
help = ' Maximum number of received posts from an account per day ' )
2019-07-03 09:24:55 +00:00
args = parser . parse_args ( )
2019-07-03 10:31:02 +00:00
2019-07-03 16:14:45 +00:00
debug = False
if args . debug :
debug = True
2019-07-03 09:24:55 +00:00
if args . tests :
runAllTests ( )
sys . exit ( )
2019-07-03 10:31:02 +00:00
if args . testsnetwork :
print ( ' Network Tests ' )
2019-07-16 21:38:06 +00:00
#testPostMessageBetweenServers()
#testFollowBetweenServers()
2019-07-16 10:19:04 +00:00
testClientToServer ( )
2019-07-03 10:31:02 +00:00
sys . exit ( )
2019-07-05 15:53:26 +00:00
2019-07-03 10:33:55 +00:00
if args . posts :
2019-07-05 15:53:26 +00:00
if ' @ ' not in args . posts :
print ( ' Syntax: --posts nickname@domain ' )
sys . exit ( )
2019-07-03 10:33:55 +00:00
nickname = args . posts . split ( ' @ ' ) [ 0 ]
domain = args . posts . split ( ' @ ' ) [ 1 ]
2019-07-03 11:24:38 +00:00
getPublicPostsOfPerson ( nickname , domain , False , True )
sys . exit ( )
if args . postsraw :
2019-07-06 21:58:56 +00:00
if ' @ ' not in args . postsraw :
2019-07-05 15:53:26 +00:00
print ( ' Syntax: --postsraw nickname@domain ' )
sys . exit ( )
2019-07-03 11:24:38 +00:00
nickname = args . postsraw . split ( ' @ ' ) [ 0 ]
domain = args . postsraw . split ( ' @ ' ) [ 1 ]
getPublicPostsOfPerson ( nickname , domain , True , False )
2019-07-03 10:33:55 +00:00
sys . exit ( )
2019-07-04 22:44:32 +00:00
baseDir = args . baseDir
if baseDir . endswith ( ' / ' ) :
print ( " --path option should not end with ' / ' " )
2019-07-03 10:31:02 +00:00
sys . exit ( )
2019-07-05 09:20:54 +00:00
# get domain name from configuration
configDomain = getConfigParam ( baseDir , ' domain ' )
if configDomain :
domain = configDomain
else :
domain = ' localhost '
# get port number from configuration
configPort = getConfigParam ( baseDir , ' port ' )
if configPort :
port = configPort
else :
port = 8085
2019-07-09 15:51:31 +00:00
nickname = None
if args . nickname :
nickname = nickname
httpPrefix = ' https '
if args . http :
httpPrefix = ' http '
federationList = [ ]
if args . federationList :
if len ( args . federationList ) == 1 :
if not ( args . federationList [ 0 ] . lower ( ) == ' any ' or \
args . federationList [ 0 ] . lower ( ) == ' all ' or \
args . federationList [ 0 ] . lower ( ) == ' * ' ) :
for federationDomain in args . federationList :
if ' @ ' in federationDomain :
print ( federationDomain + ' : Federate with domains, not individual accounts ' )
sys . exit ( )
federationList = args . federationList . copy ( )
setConfigParam ( baseDir , ' federationList ' , federationList )
else :
configFederationList = getConfigParam ( baseDir , ' federationList ' )
if configFederationList :
federationList = configFederationList
2019-07-09 15:58:51 +00:00
useTor = args . tor
if domain . endswith ( ' .onion ' ) :
useTor = True
2019-07-16 16:43:28 +00:00
if args . message :
if not nickname :
print ( ' Specify a nickname with the --nickname option ' )
sys . exit ( )
if not args . password :
print ( ' Specify a password with the --password option ' )
sys . exit ( )
2019-07-12 22:29:10 +00:00
session = createSession ( domain , port , useTor )
2019-07-16 16:43:28 +00:00
if not args . sendto :
print ( ' Specify an account to sent to: --sendto [nickname@domain] ' )
sys . exit ( )
if ' @ ' not in args . sendto :
print ( ' syntax: --sendto [nickname@domain] ' )
2019-07-12 22:29:10 +00:00
sys . exit ( )
2019-07-16 16:43:28 +00:00
toNickname = args . sendto . split ( ' @ ' ) [ 0 ]
toDomain = args . sendto . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' )
toPort = 443
if ' : ' in toDomain :
toPort = toDomain . split ( ' : ' ) [ 1 ]
toDomain = toDomain . split ( ' : ' ) [ 0 ]
#ccUrl=httpPrefix+'://'+domain+'/users/'+nickname+'/followers'
ccUrl = None
sendMessage = args . message
followersOnly = args . followersonly
clientToServer = args . client
attachedImageDescription = args . imageDescription
useBlurhash = args . blurhash
sendThreads = [ ]
postLog = [ ]
personCache = { }
cachedWebfingers = { }
subject = args . subject
attach = args . attach
replyTo = args . replyTo
followersOnly = False
print ( ' Sending post to ' + args . sendto )
sendPostViaServer ( session , nickname , args . password , \
domain , port , \
toNickname , toDomain , toPort , ccUrl , \
httpPrefix , sendMessage , followersOnly , \
attach , attachedImageDescription , useBlurhash , \
cachedWebfingers , personCache , \
args . debug , replyTo , replyTo , subject )
for i in range ( 10 ) :
# TODO detect send success/fail
time . sleep ( 1 )
sys . exit ( )
2019-07-16 20:08:30 +00:00
if args . announce :
if not nickname :
print ( ' Specify a nickname with the --nickname option ' )
sys . exit ( )
if not args . password :
print ( ' Specify a password with the --password option ' )
sys . exit ( )
session = createSession ( domain , port , useTor )
personCache = { }
cachedWebfingers = { }
print ( ' Sending announce/repeat of ' + args . announce )
sendAnnounceViaServer ( session , nickname , args . password ,
domain , port , \
httpPrefix , args . announce , \
cachedWebfingers , personCache , \
True )
for i in range ( 10 ) :
# TODO detect send success/fail
time . sleep ( 1 )
sys . exit ( )
2019-07-09 15:51:31 +00:00
if args . follow and nickname :
if not os . path . isdir ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain ) :
print ( nickname + ' is not an account on the system. use --addaccount if necessary. ' )
sys . exit ( )
if ' . ' not in args . follow :
print ( " This doesn ' t look like a fediverse handle " )
sys . exit ( )
followNickname = getNicknameFromActor ( args . follow )
followDomain , followPort = getDomainFromActor ( args . follow )
if os . path . isfile ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /following.txt ' ) :
if followNickname + ' @ ' + followDomain in open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /following.txt ' ) . read ( ) :
print ( nickname + ' @ ' + domain + ' is already following ' + followNickname + ' @ ' + followDomain )
sys . exit ( )
2019-07-09 15:58:51 +00:00
session = createSession ( domain , port , useTor )
2019-07-09 15:51:31 +00:00
personCache = { }
cachedWebfingers = { }
sendThreads = [ ]
sendThreads = [ ]
postLog = [ ]
followHttpPrefix = httpPrefix
if args . follow . startswith ( ' https ' ) :
followHttpPrefix = ' https '
sendFollowRequest ( session , baseDir , \
nickname , domain , port , httpPrefix , \
followNickname , followDomain , followPort , \
followHttpPrefix , \
False , federationList , \
sendThreads , postLog , \
cachedWebfingers , personCache , debug )
for t in range ( 30 ) :
time . sleep ( 1 )
if os . path . isfile ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /following.txt ' ) :
if followNickname + ' @ ' + followDomain in open ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain + ' /following.txt ' ) . read ( ) :
print ( ' Ok ' )
sys . exit ( )
print ( ' Follow attempt failed ' )
sys . exit ( )
2019-07-03 09:40:27 +00:00
nickname = ' admin '
2019-07-05 09:20:54 +00:00
if args . domain :
domain = args . domain
setConfigParam ( baseDir , ' domain ' , domain )
if args . port :
port = args . port
setConfigParam ( baseDir , ' port ' , port )
2019-07-07 17:47:37 +00:00
ocapAlways = False
if args . ocap :
ocapAlways = args . ocap
2019-07-03 19:00:03 +00:00
if args . dat :
httpPrefix = ' dat '
2019-07-04 22:44:32 +00:00
2019-07-05 15:53:26 +00:00
if args . actor :
if ' @ ' not in args . actor :
print ( ' Syntax: --actor nickname@domain ' )
sys . exit ( )
nickname = args . actor . split ( ' @ ' ) [ 0 ]
domain = args . actor . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' )
wfCache = { }
if domain . endswith ( ' .onion ' ) :
httpPrefix = ' http '
port = 80
else :
httpPrefix = ' https '
port = 443
session = createSession ( domain , port , useTor )
wfRequest = webfingerHandle ( session , nickname + ' @ ' + domain , httpPrefix , wfCache )
if not wfRequest :
print ( ' Unable to webfinger ' + nickname + ' @ ' + domain )
sys . exit ( )
asHeader = { ' Accept ' : ' application/ld+json; profile= " https://www.w3.org/ns/activitystreams " ' }
personUrl = getUserUrl ( wfRequest )
personJson = getJson ( session , personUrl , asHeader , None )
if personJson :
pprint ( personJson )
else :
print ( ' Failed to get ' + personUrl )
sys . exit ( )
2019-07-12 10:53:49 +00:00
if args . json :
2019-07-12 10:58:08 +00:00
session = createSession ( domain , port , True )
2019-07-12 10:53:49 +00:00
asHeader = { ' Accept ' : ' application/ld+json; profile= " https://www.w3.org/ns/activitystreams " ' }
testJson = getJson ( session , args . json , asHeader , None )
pprint ( testJson )
sys . exit ( )
2019-07-04 22:44:32 +00:00
if args . addaccount :
if ' @ ' in args . addaccount :
2019-07-04 22:50:40 +00:00
nickname = args . addaccount . split ( ' @ ' ) [ 0 ]
domain = args . addaccount . split ( ' @ ' ) [ 1 ]
2019-07-04 22:44:32 +00:00
else :
2019-07-04 22:50:40 +00:00
nickname = args . addaccount
2019-07-05 09:20:54 +00:00
if not args . domain or not getConfigParam ( baseDir , ' domain ' ) :
2019-07-04 22:44:32 +00:00
print ( ' Use the --domain option to set the domain name ' )
sys . exit ( )
2019-07-05 21:27:49 +00:00
if not validNickname ( nickname ) :
print ( nickname + ' is a reserved name. Use something different. ' )
sys . exit ( )
2019-07-05 09:20:54 +00:00
if not args . password :
print ( ' Use the --password option to set the password for ' + nickname )
sys . exit ( )
if len ( args . password . strip ( ) ) < 8 :
print ( ' Password should be at least 8 characters ' )
sys . exit ( )
2019-07-04 22:50:40 +00:00
if os . path . isdir ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain ) :
print ( ' Account already exists ' )
sys . exit ( )
2019-07-05 09:20:54 +00:00
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , args . password . strip ( ) )
2019-07-04 22:44:32 +00:00
if os . path . isdir ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain ) :
print ( ' Account created for ' + nickname + ' @ ' + domain )
2019-07-05 09:20:54 +00:00
else :
print ( ' Account creation failed ' )
2019-07-04 22:44:32 +00:00
sys . exit ( )
2019-07-04 22:50:40 +00:00
if args . rmaccount :
if ' @ ' in args . rmaccount :
nickname = args . rmaccount . split ( ' @ ' ) [ 0 ]
domain = args . rmaccount . split ( ' @ ' ) [ 1 ]
else :
nickname = args . rmaccount
2019-07-05 09:20:54 +00:00
if not args . domain or not getConfigParam ( baseDir , ' domain ' ) :
2019-07-04 22:50:40 +00:00
print ( ' Use the --domain option to set the domain name ' )
sys . exit ( )
2019-07-05 09:20:54 +00:00
handle = nickname + ' @ ' + domain
accountRemoved = False
2019-07-05 09:49:57 +00:00
removePassword ( baseDir , nickname )
2019-07-05 09:20:54 +00:00
if os . path . isdir ( baseDir + ' /accounts/ ' + handle ) :
shutil . rmtree ( baseDir + ' /accounts/ ' + handle )
accountRemoved = True
if os . path . isfile ( baseDir + ' /accounts/ ' + handle + ' .json ' ) :
os . remove ( baseDir + ' /accounts/ ' + handle + ' .json ' )
accountRemoved = True
if os . path . isfile ( baseDir + ' /wfendpoints/ ' + handle + ' .json ' ) :
os . remove ( baseDir + ' /wfendpoints/ ' + handle + ' .json ' )
accountRemoved = True
if os . path . isfile ( baseDir + ' /keys/private/ ' + handle + ' .key ' ) :
os . remove ( baseDir + ' /keys/private/ ' + handle + ' .key ' )
accountRemoved = True
2019-07-05 09:22:06 +00:00
if os . path . isfile ( baseDir + ' /keys/public/ ' + handle + ' .pem ' ) :
2019-07-05 09:20:54 +00:00
os . remove ( baseDir + ' /keys/public/ ' + handle + ' .pem ' )
accountRemoved = True
if accountRemoved :
print ( ' Account for ' + handle + ' was removed ' )
2019-07-04 22:50:40 +00:00
sys . exit ( )
2019-07-05 09:44:15 +00:00
if args . changepassword :
if len ( args . changepassword ) != 2 :
print ( ' --changepassword [nickname] [new password] ' )
sys . exit ( )
if ' @ ' in args . changepassword [ 0 ] :
nickname = args . changepassword [ 0 ] . split ( ' @ ' ) [ 0 ]
domain = args . changepassword [ 0 ] . split ( ' @ ' ) [ 1 ]
else :
nickname = args . changepassword [ 0 ]
if not args . domain or not getConfigParam ( baseDir , ' domain ' ) :
print ( ' Use the --domain option to set the domain name ' )
sys . exit ( )
newPassword = args . changepassword [ 1 ]
if len ( newPassword ) < 8 :
print ( ' Password should be at least 8 characters ' )
sys . exit ( )
2019-07-05 09:58:58 +00:00
if not os . path . isdir ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain ) :
print ( ' Account ' + nickname + ' @ ' + domain + ' not found ' )
sys . exit ( )
2019-07-05 09:44:15 +00:00
passwordFile = baseDir + ' /accounts/passwords '
if os . path . isfile ( passwordFile ) :
if nickname + ' : ' in open ( passwordFile ) . read ( ) :
storeBasicCredentials ( baseDir , nickname , newPassword )
print ( ' Password for ' + nickname + ' was changed ' )
else :
print ( nickname + ' is not in the passwords file ' )
else :
print ( ' Passwords file not found ' )
sys . exit ( )
2019-07-12 20:51:02 +00:00
archiveWeeks = 4
if args . archiveWeeks :
archiveWeeks = args . archiveWeeks
archiveMaxPosts = 256
if args . archiveMaxPosts :
archiveMaxPosts = args . archiveMaxPosts
if args . archive :
if args . archive . lower ( ) . endswith ( ' null ' ) or \
args . archive . lower ( ) . endswith ( ' delete ' ) or \
args . archive . lower ( ) . endswith ( ' none ' ) :
args . archive = None
print ( ' Archiving with deletion of old posts... ' )
else :
print ( ' Archiving to ' + args . archive + ' ... ' )
archiveMedia ( baseDir , args . archive , archiveWeeks )
2019-07-14 17:02:41 +00:00
archivePosts ( baseDir , httpPrefix , args . archive , archiveMaxPosts )
2019-07-12 20:51:02 +00:00
print ( ' Archiving complete ' )
2019-07-14 15:43:02 +00:00
sys . exit ( )
2019-07-12 20:51:02 +00:00
2019-07-05 10:03:25 +00:00
if not args . domain and not domain :
2019-07-04 22:44:32 +00:00
print ( ' Specify a domain with --domain [name] ' )
2019-07-03 09:24:55 +00:00
sys . exit ( )
2019-07-05 09:44:15 +00:00
2019-07-12 14:31:56 +00:00
if args . avatar :
if not os . path . isfile ( args . avatar ) :
print ( args . avatar + ' is not an image filename ' )
sys . exit ( )
if not args . nickname :
print ( ' Specify a nickname with --nickname [name] ' )
sys . exit ( )
if setProfileImage ( baseDir , httpPrefix , args . nickname , domain , \
2019-07-12 14:40:03 +00:00
port , args . avatar , ' avatar ' , ' 128x128 ' ) :
2019-07-12 14:31:56 +00:00
print ( ' Avatar added for ' + args . nickname )
else :
print ( ' Avatar was not added for ' + args . nickname )
sys . exit ( )
2019-07-12 14:40:03 +00:00
if args . backgroundImage :
if not os . path . isfile ( args . backgroundImage ) :
print ( args . backgroundImage + ' is not an image filename ' )
sys . exit ( )
if not args . nickname :
print ( ' Specify a nickname with --nickname [name] ' )
sys . exit ( )
if setProfileImage ( baseDir , httpPrefix , args . nickname , domain , \
port , args . backgroundImage , ' background ' , ' 256x256 ' ) :
print ( ' Background image added for ' + args . nickname )
else :
print ( ' Background image was not added for ' + args . nickname )
sys . exit ( )
2019-07-14 13:07:54 +00:00
2019-07-14 13:30:59 +00:00
if args . availability :
if not nickname :
print ( ' No nickname given ' )
sys . exit ( )
if setAvailability ( baseDir , nickname , domain , args . availability ) :
print ( ' Availablity set to ' + args . availability )
sys . exit ( )
2019-07-14 13:07:54 +00:00
if args . project :
if not nickname :
print ( ' No nickname given ' )
sys . exit ( )
if args . role . lower ( ) == ' none ' or \
args . role . lower ( ) == ' remove ' or \
args . role . lower ( ) == ' delete ' :
args . role = None
if args . role :
if setRole ( baseDir , nickname , domain , args . project , args . role ) :
print ( ' Role within ' + args . project + ' set to ' + args . role )
else :
if setRole ( baseDir , nickname , domain , args . project , None ) :
print ( ' Left ' + args . project )
sys . exit ( )
if args . skill :
if args . skillLevelPercent == 0 :
args . skillLevelPercent = None
if args . skillLevelPercent :
if setSkillLevel ( baseDir , nickname , domain , args . skill , args . skillLevelPercent ) :
print ( ' Skill level for ' + args . skill + ' set to ' + str ( args . skillLevelPercent ) + ' % ' )
else :
if setSkillLevel ( baseDir , nickname , domain , args . skill , args . skillLevelPercent ) :
print ( ' Skill ' + args . skill + ' removed ' )
sys . exit ( )
2019-07-05 09:20:54 +00:00
if federationList :
2019-07-03 16:16:36 +00:00
print ( ' Federating with: ' + str ( federationList ) )
2019-06-28 18:55:29 +00:00
2019-07-03 12:24:54 +00:00
if not os . path . isdir ( baseDir + ' /accounts/ ' + nickname + ' @ ' + domain ) :
2019-07-03 12:25:42 +00:00
print ( ' Creating default admin account ' + nickname + ' @ ' + domain )
2019-07-05 11:27:18 +00:00
print ( ' See config.json for the password. You can remove the password from config.json after moving it elsewhere. ' )
adminPassword = createPassword ( 10 )
setConfigParam ( baseDir , ' adminPassword ' , adminPassword )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , adminPassword )
2019-07-03 12:24:54 +00:00
2019-07-14 19:57:05 +00:00
if args . block :
if not args . nickname :
print ( ' Please specify a nickname ' )
sys . exit ( )
if ' @ ' not in args . block :
print ( ' syntax: --block nickname@domain ' )
sys . exit ( )
if addBlock ( baseDir , args . nickname , domain , args . block . split ( ' @ ' ) [ 0 ] , args . block . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' ) ) :
print ( args . block + ' is blocked by ' + args . nickname )
sys . exit ( )
if args . unblock :
if not args . nickname :
print ( ' Please specify a nickname ' )
sys . exit ( )
if ' @ ' not in args . block :
print ( ' syntax: --unblock nickname@domain ' )
sys . exit ( )
if removeBlock ( baseDir , args . nickname , domain , args . block . split ( ' @ ' ) [ 0 ] , args . block . split ( ' @ ' ) [ 1 ] . replace ( ' \n ' , ' ' ) ) :
print ( ' The block on ' + args . block + ' was removed by ' + args . nickname )
sys . exit ( )
2019-07-14 20:50:27 +00:00
if args . filterStr :
if not args . nickname :
print ( ' Please specify a nickname ' )
sys . exit ( )
if addFilter ( baseDir , args . nickname , domain , args . filterStr ) :
2019-07-14 20:58:50 +00:00
print ( ' Filter added to ' + args . nickname + ' : ' + args . filterStr )
2019-07-14 20:50:27 +00:00
sys . exit ( )
if args . unfilterStr :
if not args . nickname :
print ( ' Please specify a nickname ' )
sys . exit ( )
if removeFilter ( baseDir , args . nickname , domain , args . unfilterStr ) :
2019-07-14 20:58:50 +00:00
print ( ' Filter removed from ' + args . nickname + ' : ' + args . unfilterStr )
2019-07-14 20:50:27 +00:00
sys . exit ( )
2019-07-06 20:19:49 +00:00
if args . testdata :
2019-07-12 19:08:46 +00:00
useBlurhash = False
2019-07-06 21:45:09 +00:00
nickname = ' testuser567 '
2019-07-06 20:19:49 +00:00
print ( ' Generating some test data for user: ' + nickname )
createPerson ( baseDir , nickname , domain , port , httpPrefix , True , ' likewhateveryouwantscoob ' )
2019-07-14 12:29:08 +00:00
setSkillLevel ( baseDir , nickname , domain , ' testing ' , 60 )
setSkillLevel ( baseDir , nickname , domain , ' typing ' , 50 )
setRole ( baseDir , nickname , domain , ' epicyon ' , ' tester ' )
setRole ( baseDir , nickname , domain , ' epicyon ' , ' hacker ' )
setRole ( baseDir , nickname , domain , ' someproject ' , ' assistant ' )
2019-07-14 13:30:59 +00:00
setAvailability ( baseDir , nickname , domain , ' busy ' )
2019-07-06 20:19:49 +00:00
deleteAllPosts ( baseDir , nickname , domain , ' inbox ' )
deleteAllPosts ( baseDir , nickname , domain , ' outbox ' )
followPerson ( baseDir , nickname , domain , ' admin ' , domain , federationList , True )
followerOfPerson ( baseDir , nickname , domain , ' admin ' , domain , federationList , True )
2019-07-12 19:08:46 +00:00
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " like, this is totally just a test, man " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " Zoiks!!! " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " Hey scoob we need like a hundred more milkshakes " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " Getting kinda spooky around here " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " And they would have gotten away with it too if it wasn ' t for those pesky hackers " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " man, these centralized sites are, like, the worst! " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " another mystery solved hey " , False , True , False , None , None , useBlurhash )
createPublicPost ( baseDir , nickname , domain , port , httpPrefix , " let ' s go bowling " , False , True , False , None , None , useBlurhash )
2019-07-13 09:37:17 +00:00
runDaemon ( args . client , baseDir , domain , port , httpPrefix , \
federationList , \
2019-07-09 18:11:23 +00:00
args . noreply , args . nolike , args . nopics , \
2019-07-13 21:00:12 +00:00
args . noannounce , args . cw , ocapAlways , \
2019-07-15 10:22:19 +00:00
useTor , args . maxReplies , \
args . domainMaxPostsPerDay , args . accountMaxPostsPerDay , \
debug )