2020logger = logging .getLogger ("FediFetcher" )
2121robotParser = urllib .robotparser .RobotFileParser ()
2222
23- VERSION = "7.1.12 "
23+ VERSION = "7.1.16 "
2424
2525argparser = argparse .ArgumentParser ()
2626
@@ -367,19 +367,12 @@ def get_timeline(server, access_token, max):
367367
368368 if response .status_code == 200 :
369369 toots = response .json ()
370- elif response .status_code == 401 :
371- raise Exception (
372- f"Error getting URL { url } . Status code: { response .status_code } . "
373- "Ensure your access token is correct"
374- )
375- elif response .status_code == 403 :
376- raise Exception (
377- f"Error getting URL { url } . Status code: { response .status_code } . "
378- "Make sure you have the read:statuses scope enabled for your access token."
379- )
380370 else :
381- raise Exception (
382- f"Error getting URL { url } . Status code: { response .status_code } "
371+ report_mastodon_error (
372+ f"Error getting URL { url } " ,
373+ response .status_code ,
374+ access_token ,
375+ "read:statuses"
383376 )
384377
385378 # Paginate as needed
@@ -401,19 +394,12 @@ def get_toots(url, access_token):
401394
402395 if response .status_code == 200 :
403396 return response
404- elif response .status_code == 401 :
405- raise Exception (
406- f"Error getting URL { url } . Status code: { response .status_code } . "
407- "It looks like your access token is incorrect."
408- )
409- elif response .status_code == 403 :
410- raise Exception (
411- f"Error getting URL { url } . Status code: { response .status_code } . "
412- "Make sure you have the read:statuses scope enabled for your access token."
413- )
414397 else :
415- raise Exception (
416- f"Error getting URL { url } . Status code: { response .status_code } "
398+ report_mastodon_error (
399+ f"Error getting URL { url } " ,
400+ response .status_code ,
401+ access_token ,
402+ "read:statuses"
417403 )
418404
419405def get_active_user_ids (server , access_token , reply_interval_hours ):
@@ -432,19 +418,12 @@ def get_active_user_ids(server, access_token, reply_interval_hours):
432418 if last_active > since :
433419 logger .info (f"Found active user: { user ['username' ]} " )
434420 yield user ["id" ]
435- elif resp .status_code == 401 :
436- raise Exception (
437- f"Error getting user IDs on server { server } . Status code: { resp .status_code } . "
438- "Ensure your access token is correct"
439- )
440- elif resp .status_code == 403 :
441- raise Exception (
442- f"Error getting user IDs on server { server } . Status code: { resp .status_code } . "
443- "Make sure you have the admin:read:accounts scope enabled for your access token."
444- )
445421 else :
446- raise Exception (
447- f"Error getting user IDs on server { server } . Status code: { resp .status_code } "
422+ report_mastodon_error (
423+ f"Error getting user IDs on server { server } " ,
424+ resp .status_code ,
425+ access_token ,
426+ "admin:read:accounts"
448427 )
449428
450429
@@ -491,16 +470,14 @@ def get_reply_toots(user_id, server, access_token, seen_urls, reply_since):
491470 for toot in toots :
492471 logger .debug (f"Found reply toot: { toot ['url' ]} " )
493472 return toots
494- elif resp .status_code == 403 :
495- raise Exception (
496- f"Error getting replies for user { user_id } on server { server } . Status code: { resp .status_code } . "
497- "Make sure you have the read:statuses scope enabled for your access token."
473+ else :
474+ report_mastodon_error (
475+ f"Error getting replies for user { user_id } on server { server } " ,
476+ resp .status_code ,
477+ access_token ,
478+ "read:statuses"
498479 )
499480
500- raise Exception (
501- f"Error getting replies for user { user_id } on server { server } . Status code: { resp .status_code } "
502- )
503-
504481
505482def toot_context_can_be_fetched (toot ):
506483 fetchable = toot ["visibility" ] in ["public" , "unlisted" ]
@@ -651,6 +628,11 @@ def parse_url(url, parsed_urls):
651628 if match is not None :
652629 parsed_urls [url ] = match
653630
631+ if url not in parsed_urls :
632+ match = parse_pleroma_uri (url )
633+ if match is not None :
634+ parsed_urls [url ] = match
635+
654636 if url not in parsed_urls :
655637 match = parse_lemmy_url (url )
656638 if match is not None :
@@ -719,6 +701,13 @@ def parse_pleroma_url(url):
719701 return None
720702 return None
721703
704+ def parse_pleroma_uri (uri ):
705+ """parse a Pleroma URL and return the server and ID"""
706+ match = re .match (r"https://(?P<server>[^/]+)/notice/(?P<toot_id>[^/]+)" , uri )
707+ if match is not None :
708+ return (match .group ("server" ), match .group ("toot_id" ))
709+ return None
710+
722711def parse_pleroma_profile_url (url ):
723712 """parse a Pleroma Profile URL and return the server and username"""
724713 match = re .match (r"https://(?P<server>[^/]+)/users/(?P<username>[^/]+)" , url )
@@ -1033,20 +1022,11 @@ def get_paginated_mastodon(url, max, headers = {}, timeout = 0, max_tries = 5):
10331022 response = get (furl , headers , timeout , max_tries )
10341023
10351024 if response .status_code != 200 :
1036- if response .status_code == 401 :
1037- raise Exception (
1038- f"Error getting URL { url } . Status code: { response .status_code } . "
1039- "Ensure your access token is correct"
1040- )
1041- elif response .status_code == 403 :
1042- raise Exception (
1043- f"Error getting URL { url } . Status code: { response .status_code } . "
1044- "Make sure you have the correct scopes enabled for your access token."
1045- )
1046- else :
1047- raise Exception (
1048- f"Error getting URL { url } . Status code: { response .status_code } "
1049- )
1025+ report_mastodon_error (
1026+ f"Error getting URL { url } " ,
1027+ response .status_code ,
1028+ headers .get ('Authorization' , '' ).replace ("Bearer " , "" ),
1029+ )
10501030
10511031 result = response .json ()
10521032
@@ -1470,6 +1450,22 @@ def fetch_timeline_context(timeline_posts, token, parsed_urls, seen_hosts, seen_
14701450
14711451 add_user_posts (arguments .server , token , filter_known_users (mentioned_users , all_known_users ), recently_checked_users , all_known_users , seen_urls , seen_hosts )
14721452
1453+ def report_mastodon_error (error_message , error_code , access_token , required_scope = '' ):
1454+ subline = ""
1455+ match error_code :
1456+ case 401 :
1457+ subline = "\n It looks like your access token is incorrect. Consider generating a new access token, and/or ensure you have copy and pasted the whole token correctly."
1458+ case 403 :
1459+ if (required_scope != "" ):
1460+ subline = f"\n Add the { required_scope } scope to your access token, and regenerate the token."
1461+ else :
1462+ subline = "\n Make sure you have enabled the required scope(s) for your token."
1463+
1464+ raise Exception (
1465+ f"{ error_message } with token { access_token [:+ 5 ]} { '*' * (len (access_token ) - 10 )} { access_token [- 5 :]} . Status code: { error_code } "
1466+ f"{ subline } "
1467+ )
1468+
14731469if __name__ == "__main__" :
14741470 start = datetime .now ()
14751471
@@ -1519,7 +1515,7 @@ def fetch_timeline_context(timeline_posts, token, parsed_urls, seen_hosts, seen_
15191515 if tokens := [token for envvar , token in os .environ .items () if envvar .lower ().startswith ("ff_access_token" )]:
15201516 arguments .access_token = tokens
15211517
1522- logger .info ("Starting FediFetcher" )
1518+ logger .info (f "Starting FediFetcher v { VERSION } " )
15231519
15241520 if (arguments .server == None or arguments .access_token == None ):
15251521 logger .critical ("You must supply at least a server name and an access token" )
0 commit comments