diff --git a/README_commandline.md b/README_commandline.md index 14e54a9ee..28206529a 100644 --- a/README_commandline.md +++ b/README_commandline.md @@ -474,6 +474,8 @@ prev Previous page in the timeline read [post number] Read a post from a timeline open [post number] Open web links within a timeline post profile [post number] Show profile for the person who made the given post +following [page number] Show accounts that you are following +followers [page number] Show accounts that are following you ``` If you have a GPG key configured on your local system and are sending a direct message to someone who has a PGP key (the exported key, not just the key ID) set as a tag on their profile then it will try to encrypt the message automatically. So under some conditions end-to-end encryption is possible, such that the instance server only sees ciphertext. Conversely, for arriving direct messages if they are PGP encrypted then the desktop client will try to obtain the relevant public key and decrypt. diff --git a/daemon.py b/daemon.py index 48e0cf892..d37f5f32b 100644 --- a/daemon.py +++ b/daemon.py @@ -9284,7 +9284,8 @@ class PubServer(BaseHTTPRequestHandler): """ following = \ getFollowingFeed(baseDir, domain, port, path, - httpPrefix, authorized, followsPerPage) + httpPrefix, authorized, followsPerPage, + 'following') if following: if self._requestHTTP(): pageNumber = 1 @@ -9666,9 +9667,7 @@ class PubServer(BaseHTTPRequestHandler): divertToLoginScreen = False else: if path.endswith('/following') or \ - '/following?page=' in path or \ path.endswith('/followers') or \ - '/followers?page=' in path or \ path.endswith('/skills') or \ path.endswith('/roles') or \ path.endswith('/shares'): @@ -10276,6 +10275,29 @@ class PubServer(BaseHTTPRequestHandler): return True return False + def _getFollowingJson(self, baseDir: str, path: str, + callingDomain: str, + httpPrefix: str, + domain: str, port: int, + followingItemsPerPage: int, + debug: bool, listName='following') -> None: + """Returns json collection for following.txt + """ + followingJson = \ + getFollowingFeed(baseDir, domain, port, path, httpPrefix, + True, followingItemsPerPage, listName) + if not followingJson: + if debug: + print(listName + ' json feed not found for ' + path) + self._404() + return + msg = json.dumps(followingJson, + ensure_ascii=False).encode('utf-8') + msglen = len(msg) + self._set_headers('application/json', + msglen, None, callingDomain) + self._write(msg) + def do_GET(self): callingDomain = self.server.domainFull if self.headers.get('Host'): @@ -10573,6 +10595,39 @@ class PubServer(BaseHTTPRequestHandler): if '/users/' in self.path: usersInPath = True + if authorized and not htmlGET and usersInPath: + if '/following?page=' in self.path: + self._getFollowingJson(self.server.baseDir, + self.path, + callingDomain, + self.server.httpPrefix, + self.server.domain, + self.server.port, + self.server.followingItemsPerPage, + self.server.debug, 'following') + return + elif '/followers?page=' in self.path: + self._getFollowingJson(self.server.baseDir, + self.path, + callingDomain, + self.server.httpPrefix, + self.server.domain, + self.server.port, + self.server.followingItemsPerPage, + self.server.debug, 'followers') + return + elif '/followrequests?page=' in self.path: + self._getFollowingJson(self.server.baseDir, + self.path, + callingDomain, + self.server.httpPrefix, + self.server.domain, + self.server.port, + self.server.followingItemsPerPage, + self.server.debug, + 'followrequests') + return + # authorized endpoint used for TTS of posts # arriving in your inbox if authorized and usersInPath and \ @@ -14510,6 +14565,7 @@ def runDaemon(brochMode: bool, # for it to be considered dormant? httpd.dormantMonths = dormantMonths + httpd.followingItemsPerPage = 12 if registration == 'open': httpd.registration = True else: diff --git a/desktop_client.py b/desktop_client.py index 3347b967c..70c1c847f 100644 --- a/desktop_client.py +++ b/desktop_client.py @@ -29,6 +29,9 @@ from speaker import getSpeakerRate from speaker import getSpeakerRange from like import sendLikeViaServer from like import sendUndoLikeViaServer +from follow import getFollowRequestsViaServer +from follow import getFollowingViaServer +from follow import getFollowersViaServer from follow import sendFollowRequestViaServer from follow import sendUnfollowRequestViaServer from posts import sendBlockViaServer @@ -110,6 +113,10 @@ def _desktopHelp() -> None: 'Open web links within a timeline post') print(indent + 'profile [post number] ' + 'Show profile for the person who made the given post') + print(indent + 'following [page number] ' + + 'Show accounts that you are following') + print(indent + 'followers [page number] ' + + 'Show accounts that are following you') print('') @@ -871,7 +878,10 @@ def _highlightText(text: str) -> str: return '\33[7m' + text + '\33[0m' -def _desktopShowBox(yourActor: str, boxName: str, boxJson: {}, +def _desktopShowBox(indent: str, + followRequestsJson: {}, + yourActor: str, boxName: str, boxJson: {}, + translate: {}, screenreader: str, systemLanguage: str, espeak, pageNumber=1, newReplies=False, @@ -881,7 +891,6 @@ def _desktopShowBox(yourActor: str, boxName: str, boxJson: {}, numberWidth = 2 nameWidth = 16 contentWidth = 50 - indent = ' ' # title _desktopClearScreen() @@ -893,11 +902,10 @@ def _desktopShowBox(yourActor: str, boxName: str, boxJson: {}, else: boxNameStr = boxName titleStr = _highlightText(boxNameStr.upper()) - - if newDMs: - notificationIcons += ' 📩' - if newReplies: - notificationIcons += ' 📨' + # if newDMs: + # notificationIcons += ' 📩' + # if newReplies: + # notificationIcons += ' 📨' if notificationIcons: while len(titleStr) < 95 - len(notificationIcons): @@ -1023,6 +1031,9 @@ def _desktopShowBox(yourActor: str, boxName: str, boxJson: {}, print(lineStr) ctr += 1 + if followRequestsJson: + _desktopShowFollowRequests(followRequestsJson, translate) + print('') # say the post number range @@ -1175,6 +1186,46 @@ def _desktopNewDMbase(session, toHandle: str, _sayCommand(sayStr, sayStr, screenreader, systemLanguage, espeak) +def _desktopShowFollowRequests(followRequestsJson: {}, translate: {}) -> None: + """Shows any follow requests + """ + if not followRequestsJson['orderedItems']: + return + indent = ' ' + print('') + print(indent + 'Follow requests:') + print('') + for item in followRequestsJson['orderedItems']: + handleNickname = getNicknameFromActor(item) + handleDomain, handlePort = getDomainFromActor(item) + handleDomainFull = \ + getFullDomain(handleDomain, handlePort) + print(indent + ' 👤 ' + + handleNickname + '@' + handleDomainFull) + + +def _desktopShowFollowing(followingJson: {}, translate: {}, + pageNumber: int, indent: str, + followType='following') -> None: + """Shows a page of accounts followed + """ + if not followingJson['orderedItems']: + return + print('') + if followType == 'following': + print(indent + 'Following page ' + str(pageNumber)) + elif followType == 'followers': + print(indent + 'Followers page ' + str(pageNumber)) + print('') + for item in followingJson['orderedItems']: + handleNickname = getNicknameFromActor(item) + handleDomain, handlePort = getDomainFromActor(item) + handleDomainFull = \ + getFullDomain(handleDomain, handlePort) + print(indent + ' 👤 ' + + handleNickname + '@' + handleDomainFull) + + def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, nickname: str, domain: str, port: int, password: str, screenreader: str, @@ -1296,6 +1347,14 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) + followRequestsJson = \ + getFollowRequestsViaServer(baseDir, session, + nickname, password, + domain, port, + httpPrefix, 1, + cachedWebfingers, personCache, + debug, __version__) + if not (currTimeline == 'inbox' and pageNumber == 1): # monitor the inbox to generate notifications inboxJson = c2sBoxJson(baseDir, session, @@ -1329,7 +1388,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, timelineFirstId = _getFirstItemId(boxJson) if timelineFirstId != prevTimelineFirstId: _desktopClearScreen() - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, None, systemLanguage, espeak, pageNumber, newRepliesExist, @@ -1367,7 +1428,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1382,7 +1445,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1398,7 +1463,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1415,7 +1482,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1440,7 +1509,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, currTimeline, pageNumber, debug) if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1450,7 +1521,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, else: postIndexStr = commandStr.split('read ')[1] if boxJson and postIndexStr.isdigit(): - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1479,7 +1552,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, postIndexStr = commandStr.split('profile ')[1] if not actorJson and boxJson and postIndexStr.isdigit(): - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) @@ -1887,6 +1962,65 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, True, __version__) refreshTimeline = True print('') + elif (commandStr == 'follow requests' or + commandStr.startswith('follow requests ')): + currPage = 1 + if ' ' in commandStr: + pageNum = commandStr.split(' ')[-1].strip() + if pageNum.isdigit(): + currPage = int(pageNum) + followRequestsJson = \ + getFollowRequestsViaServer(baseDir, session, + nickname, password, + domain, port, + httpPrefix, currPage, + cachedWebfingers, personCache, + debug, __version__) + if followRequestsJson: + if isinstance(followRequestsJson, dict): + _desktopShowFollowRequests(followRequestsJson, + translate) + print('') + elif (commandStr == 'following' or + commandStr.startswith('following ')): + currPage = 1 + if ' ' in commandStr: + pageNum = commandStr.split(' ')[-1].strip() + if pageNum.isdigit(): + currPage = int(pageNum) + followingJson = \ + getFollowingViaServer(baseDir, session, + nickname, password, + domain, port, + httpPrefix, currPage, + cachedWebfingers, personCache, + debug, __version__) + if followingJson: + if isinstance(followingJson, dict): + _desktopShowFollowing(followingJson, translate, + currPage, indent, + 'following') + print('') + elif (commandStr == 'followers' or + commandStr.startswith('followers ')): + currPage = 1 + if ' ' in commandStr: + pageNum = commandStr.split(' ')[-1].strip() + if pageNum.isdigit(): + currPage = int(pageNum) + followersJson = \ + getFollowersViaServer(baseDir, session, + nickname, password, + domain, port, + httpPrefix, currPage, + cachedWebfingers, personCache, + debug, __version__) + if followersJson: + if isinstance(followersJson, dict): + _desktopShowFollowing(followersJson, translate, + currPage, indent, + 'followers') + print('') elif (commandStr == 'follow' or commandStr.startswith('follow ')): if commandStr == 'follow': @@ -2105,7 +2239,9 @@ def runDesktopClient(baseDir: str, proxyType: str, httpPrefix: str, if refreshTimeline: if boxJson: - _desktopShowBox(yourActor, currTimeline, boxJson, + _desktopShowBox(indent, followRequestsJson, + yourActor, currTimeline, boxJson, + translate, screenreader, systemLanguage, espeak, pageNumber, newRepliesExist, newDMsExist) diff --git a/epicyon.py b/epicyon.py index b5575c1a4..a6d265f25 100644 --- a/epicyon.py +++ b/epicyon.py @@ -46,6 +46,9 @@ from filters import addFilter from filters import removeFilter from pprint import pprint from daemon import runDaemon +from follow import getFollowRequestsViaServer +from follow import getFollowingViaServer +from follow import getFollowersViaServer from follow import clearFollows from follow import followerOfPerson from follow import sendFollowRequestViaServer @@ -248,6 +251,24 @@ 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", "--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("--followRequestsList", + dest='followRequestsList', + type=str2bool, nargs='?', + const=True, default=False, + help="Get the follow requests list. Use nickname and " + + "domain options to specify the account") parser.add_argument("--repliesEnabled", "--commentsEnabled", dest='commentsEnabled', type=str2bool, nargs='?', @@ -1484,6 +1505,90 @@ if args.unfollow: print('Ok') sys.exit() +if args.followingList: + # 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 + + followingJson = \ + getFollowingViaServer(baseDir, session, + args.nickname, args.password, + domain, port, + httpPrefix, args.pageNumber, + cachedWebfingers, personCache, + debug, __version__) + if followingJson: + 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() + +if args.followRequestsList: + # follow requests 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 + + followRequestsJson = \ + getFollowRequestsViaServer(baseDir, session, + args.nickname, args.password, + domain, port, + httpPrefix, args.pageNumber, + cachedWebfingers, personCache, + debug, __version__) + if followRequestsJson: + pprint(followRequestsJson) + sys.exit() + nickname = 'admin' if args.domain: domain = args.domain diff --git a/follow.py b/follow.py index 51b116a89..87cccca78 100644 --- a/follow.py +++ b/follow.py @@ -26,6 +26,7 @@ from acceptreject import createAccept from acceptreject import createReject from webfinger import webfingerHandle from auth import createBasicAuthHeader +from session import getJson from session import postJson @@ -351,14 +352,14 @@ def _getNoOfFollowers(baseDir: str, def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, - httpPrefix: str, authenticated: bool, + httpPrefix: str, authorized: bool, followsPerPage=12, followFile='following') -> {}: """Returns the following and followers feeds from GET requests. This accesses the following.txt or followers.txt and builds a collection. """ - # Show a small number of follows to non-authenticated viewers - if not authenticated: + # Show a small number of follows to non-authorized viewers + if not authorized: followsPerPage = 6 if '/' + followFile not in path: @@ -368,7 +369,7 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, pageNumber = None if '?page=' in path: pageNumber = path.split('?page=')[1] - if pageNumber == 'true' or not authenticated: + if pageNumber == 'true' or not authorized: pageNumber = 1 else: try: @@ -400,7 +401,7 @@ def getFollowingFeed(baseDir: str, domain: str, port: int, path: str, httpPrefix + '://' + domain + '/users/' + \ nickname + '/' + followFile totalStr = \ - _getNoOfFollows(baseDir, nickname, domain, authenticated) + _getNoOfFollows(baseDir, nickname, domain, authorized) following = { '@context': 'https://www.w3.org/ns/activitystreams', 'first': firstStr, @@ -1131,6 +1132,231 @@ def sendUnfollowRequestViaServer(baseDir: str, session, return unfollowJson +def getFollowingViaServer(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 following collection as json + """ + if not session: + print('WARN: No session for getFollowingViaServer') + 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: following list webfinger failed for ' + handle) + return 1 + if not isinstance(wfRequest, dict): + print('WARN: following 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: following list no ' + postToBox + + ' was found for ' + handle) + return 3 + if not fromPersonId: + if debug: + print('DEBUG: following 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 + '/following?page=' + str(pageNumber) + followingJson = \ + getJson(session, url, headers, {}, debug, + __version__, httpPrefix, + domain, 10, True) + if not followingJson: + if debug: + print('DEBUG: GET following list failed for c2s to ' + url) + return 5 + + if debug: + print('DEBUG: c2s GET following list request success') + + 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 getFollowRequestsViaServer(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 follow requests collection as json + """ + if not session: + print('WARN: No session for getFollowRequestsViaServer') + 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: follow requests list webfinger failed for ' + + handle) + return 1 + if not isinstance(wfRequest, dict): + print('WARN: follow requests 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, 42759) + + if not inboxUrl: + if debug: + print('DEBUG: follow requests list no ' + postToBox + + ' was found for ' + handle) + return 3 + if not fromPersonId: + if debug: + print('DEBUG: follow requests 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 + '/followrequests?page=' + str(pageNumber) + followersJson = \ + getJson(session, url, headers, {}, debug, + __version__, httpPrefix, domain, 10, True) + if not followersJson: + if debug: + print('DEBUG: GET follow requests list failed for c2s to ' + url) + return 5 + + if debug: + print('DEBUG: c2s GET follow requests 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.