diff --git a/README_commandline.md b/README_commandline.md index 62c28f28a..c6b392aec 100644 --- a/README_commandline.md +++ b/README_commandline.md @@ -137,6 +137,16 @@ If you want to view the raw JSON: python3 epicyon.py --postsraw nickname@domain ``` +## Getting the JSON for your timelines + +The **--posts** option applies for any ActivityPub compatible fediverse account with visible public posts. You can also use an authenticated version to obtain the paginated JSON for your inbox, outbox, direct messages, etc. + +``` bash +python3 epicyon.py --nickname [yournick] --domain [yourdomain] --box [inbox|outbox|dm] --page [number] --password [yourpassword] +``` + +You could use this to make your own c2s client, or create your own notification system. + ## Listing referenced domains To list the domains referenced in public posts: diff --git a/epicyon.py b/epicyon.py index 674c1f5d6..3052c1f06 100644 --- a/epicyon.py +++ b/epicyon.py @@ -22,6 +22,7 @@ from person import deactivateAccount from skills import setSkillLevel from roles import setRole from webfinger import webfingerHandle +from posts import c2sBoxJson from posts import downloadFollowCollection from posts import getPublicPostDomains from posts import getPublicPostDomainsBlocked @@ -405,6 +406,13 @@ parser.add_argument("--allowdeletion", type=str2bool, nargs='?', parser.add_argument('--repeat', '--announce', dest='announce', type=str, default=None, help='Announce/repeat a url') +parser.add_argument('--box', type=str, + default=None, + help='Returns the json for a given timeline, ' + + 'with authentication') +parser.add_argument('--page', '--pageNumber', dest='pageNumber', type=int, + default=1, + help='Page number when using the --box option') parser.add_argument('--favorite', '--like', dest='like', type=str, default=None, help='Like a url') parser.add_argument('--undolike', '--unlike', dest='undolike', type=str, @@ -1112,6 +1120,46 @@ if args.announce: time.sleep(1) sys.exit() +if args.box: + if not domain: + print('Specify a domain with the --domain option') + sys.exit() + + if not args.nickname: + print('Specify a nickname with the --nickname option') + 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', '') + + proxyType = None + if args.tor or domain.endswith('.onion'): + proxyType = 'tor' + if domain.endswith('.onion'): + args.port = 80 + elif args.i2p or domain.endswith('.i2p'): + proxyType = 'i2p' + if domain.endswith('.i2p'): + args.port = 80 + elif args.gnunet: + proxyType = 'gnunet' + + session = createSession(proxyType) + boxJson = c2sBoxJson(baseDir, session, + args.nickname, args.password, + domain, port, httpPrefix, + args.box, args.pageNumber, + args.debug) + if boxJson: + pprint(boxJson) + else: + print('Box not found: ' + args.box) + sys.exit() + if args.itemName: if not args.password: args.password = getpass.getpass('Password: ') diff --git a/posts.py b/posts.py index cf6c63d3b..af0505a7b 100644 --- a/posts.py +++ b/posts.py @@ -4307,3 +4307,39 @@ def postIsMuted(baseDir: str, nickname: str, domain: str, if os.path.isfile(muteFilename): return True return False + + +def c2sBoxJson(baseDir: str, session, + nickname: str, password: str, + domain: str, port: int, + httpPrefix: str, + boxName: str, pageNumber: int, + debug: bool) -> {}: + """C2S Authenticated GET of posts for a timeline + """ + if not session: + print('WARN: No session for c2sBoxJson') + return None + + domainFull = getFullDomain(domain, port) + actor = httpPrefix + '://' + domainFull + '/users/' + nickname + + authHeader = createBasicAuthHeader(nickname, password) + + profileStr = 'https://www.w3.org/ns/activitystreams' + headers = { + 'host': domain, + 'Content-type': 'application/json', + 'Authorization': authHeader, + 'Accept': 'application/ld+json; profile="' + profileStr + '"' + } + + # GET json + url = actor + '/' + boxName + '?page=' + str(pageNumber) + boxJson = getJson(session, url, headers, None, + debug, __version__, httpPrefix, None) + + if boxJson is not None and debug: + print('DEBUG: GET c2sBoxJson success') + + return boxJson