From 0f70a98ed440dd9e4008a9322f963fe2bdad3d9b Mon Sep 17 00:00:00 2001 From: Bob Mottram Date: Wed, 24 Mar 2021 13:52:20 +0000 Subject: [PATCH] Get followers list via c2s --- epicyon.py | 41 +++++++++++++++++++++++++++--- follow.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+), 3 deletions(-) diff --git a/epicyon.py b/epicyon.py index fb2f5808d..7a1437404 100644 --- a/epicyon.py +++ b/epicyon.py @@ -47,6 +47,7 @@ from filters import removeFilter from pprint import pprint from daemon import runDaemon from follow import getFollowingViaServer +from follow import getFollowersViaServer from follow import clearFollows from follow import followerOfPerson from follow import sendFollowRequestViaServer @@ -249,12 +250,18 @@ parser.add_argument('--rss', dest='rss', type=str, default=None, help='Show an rss feed for a given url') parser.add_argument('-f', '--federate', nargs='+', dest='federationList', help='Specify federation list separated by spaces') -parser.add_argument("--following", "--following", - dest='following', +parser.add_argument("--following", "--followingList", + dest='followingList', type=str2bool, nargs='?', const=True, default=False, help="Get the following list. Use nickname and " + "domain options to specify the account") +parser.add_argument("--followersList", + dest='followersList', + type=str2bool, nargs='?', + const=True, default=False, + help="Get the followers list. Use nickname and " + + "domain options to specify the account") parser.add_argument("--repliesEnabled", "--commentsEnabled", dest='commentsEnabled', type=str2bool, nargs='?', @@ -1491,7 +1498,7 @@ if args.unfollow: print('Ok') sys.exit() -if args.following: +if args.followingList: # following list via c2s protocol if not args.nickname: print('Please specify the nickname for the account with --nickname') @@ -1519,6 +1526,34 @@ if args.following: pprint(followingJson) sys.exit() +if args.followersList: + # following list via c2s protocol + if not args.nickname: + print('Please specify the nickname for the account with --nickname') + sys.exit() + if not args.password: + args.password = getpass.getpass('Password: ') + if not args.password: + print('Specify a password with the --password option') + sys.exit() + args.password = args.password.replace('\n', '') + + session = createSession(proxyType) + personCache = {} + cachedWebfingers = {} + followHttpPrefix = httpPrefix + + followersJson = \ + getFollowersViaServer(baseDir, session, + args.nickname, args.password, + domain, port, + httpPrefix, args.pageNumber, + cachedWebfingers, personCache, + debug, __version__) + if followersJson: + pprint(followersJson) + sys.exit() + nickname = 'admin' if args.domain: domain = args.domain diff --git a/follow.py b/follow.py index 471cc15b8..a39e2f803 100644 --- a/follow.py +++ b/follow.py @@ -1207,6 +1207,80 @@ def getFollowingViaServer(baseDir: str, session, return followingJson +def getFollowersViaServer(baseDir: str, session, + nickname: str, password: str, + domain: str, port: int, + httpPrefix: str, pageNumber: int, + cachedWebfingers: {}, personCache: {}, + debug: bool, projectVersion: str) -> {}: + """Gets a page from the followers collection as json + """ + if not session: + print('WARN: No session for getFollowersViaServer') + return 6 + + domainFull = getFullDomain(domain, port) + + followActor = httpPrefix + '://' + domainFull + '/users/' + nickname + handle = httpPrefix + '://' + domainFull + '/@' + nickname + + # lookup the inbox for the To handle + wfRequest = \ + webfingerHandle(session, handle, httpPrefix, cachedWebfingers, + domain, projectVersion, debug) + if not wfRequest: + if debug: + print('DEBUG: followers list webfinger failed for ' + handle) + return 1 + if not isinstance(wfRequest, dict): + print('WARN: followers list Webfinger for ' + handle + + ' did not return a dict. ' + str(wfRequest)) + return 1 + + postToBox = 'outbox' + + # get the actor inbox for the To handle + (inboxUrl, pubKeyId, pubKey, + fromPersonId, sharedInbox, avatarUrl, + displayName) = getPersonBox(baseDir, session, wfRequest, personCache, + projectVersion, httpPrefix, nickname, + domain, postToBox, 52025) + + if not inboxUrl: + if debug: + print('DEBUG: followers list no ' + postToBox + + ' was found for ' + handle) + return 3 + if not fromPersonId: + if debug: + print('DEBUG: followers list no actor was found for ' + handle) + return 4 + + authHeader = createBasicAuthHeader(nickname, password) + + headers = { + 'host': domain, + 'Content-type': 'application/json', + 'Authorization': authHeader + } + + if pageNumber < 1: + pageNumber = 1 + url = followActor + '/followers?page=' + str(pageNumber) + followersJson = \ + getJson(session, url, headers, {}, debug, + __version__, httpPrefix, domain, 10, True) + if not followersJson: + if debug: + print('DEBUG: GET followers list failed for c2s to ' + url) + return 5 + + if debug: + print('DEBUG: c2s GET followers list request success') + + return followersJson + + def getFollowersOfActor(baseDir: str, actor: str, debug: bool) -> {}: """In a shared inbox if we receive a post we know who it's from and if it's addressed to followers then we need to get a list of those.