diff --git a/igmirror.py b/igmirror.py index 589a9d9..109a26d 100644 --- a/igmirror.py +++ b/igmirror.py @@ -105,7 +105,7 @@ def update_igaccount(acc_id, profileset=True): pixelfed_setinfo(acc_id, data['graphql']['user']['biography'],\ data['graphql']['user']['external_url']) - # sincronize posts (images/videos/stories...) + # sincronize posts (images/videos...) pixelfed_dlposts(acc_id, data['graphql']['user']) return 0 @@ -242,27 +242,45 @@ def pixelfed_token_url(url='', _cookies=None): _token = re.search(r'name="_token".+value="([^"]+)"', r.text).group(1) return r.cookies, _token -def pixelfed_dlposts(acc_id, data): +def pixelfed_dlstories_async(): + threading.Thread(target=pixelfed_dlstories).start() + +def pixelfed_dlstories(): + # get reels_tray of the account (stories are called like this) + data = json.loads(instagram_get('https://i.instagram.com/api/v1/feed/reels_tray/', 1000000, { + 'Host': 'i.instagram.com', + })) + for item in data['tray']: + # for now stories don't support videos: + # https://github.com/pixelfed/pixelfed/issues/2169 + # So, we will upload them as posts + print(json.dumps(item, indent=4)) + +def pixelfed_dlposts(acc_id, data, is_story=False): ts = [] - for edge in data['edge_owner_to_timeline_media']['edges']: - ts.append(edge['node']['taken_at_timestamp']) - for edge in data['edge_felix_video_timeline']['edges']: - ts.append(edge['node']['taken_at_timestamp']) - ts = sorted(ts) items = [] - for t in ts: - brkit = False + if not is_story: for edge in data['edge_owner_to_timeline_media']['edges']: - if edge['node']['taken_at_timestamp'] == t: - items.append(edge['node']) - brkit = True - break - if brkit: - continue + ts.append(edge['node']['taken_at_timestamp']) for edge in data['edge_felix_video_timeline']['edges']: - if edge['node']['taken_at_timestamp'] == t: - items.append(edge['node']) - break + ts.append(edge['node']['taken_at_timestamp']) + ts = sorted(ts) + for t in ts: + brkit = False + for edge in data['edge_owner_to_timeline_media']['edges']: + if edge['node']['taken_at_timestamp'] == t: + items.append(edge['node']) + brkit = True + break + if brkit: + continue + for edge in data['edge_felix_video_timeline']['edges']: + if edge['node']['taken_at_timestamp'] == t: + items.append(edge['node']) + break + else: + print(data) + return # mirror posts from the account (only the last N, without loading more), # but only the ones that has not already been imported @@ -542,7 +560,7 @@ def getig_user_fullname(data): data['graphql']['user']['full_name']) # runs a basic GET request emulating Tor Browser -def instagram_get(url, CACHE_SECS=600): +def instagram_get(url, CACHE_SECS=600, add_headers={}): headers = get_random_headers() default_headers = { 'Accept': '*/*', @@ -558,7 +576,10 @@ def instagram_get(url, CACHE_SECS=600): for key in default_headers.keys(): if not key in headers: headers[key] = default_headers[key] - url = 'https://www.instagram.com{}'.format(url) + for key in add_headers.keys(): + headers[key] = add_headers[key] + if not '.instagram.com/' in url: + url = 'https://www.instagram.com{}'.format(url) cachef = './cache/'+md5sum(url) now = str(time.time()) now = int(now[:now.index('.')]) diff --git a/server.py b/server.py index 5a20f01..ba9c9f2 100644 --- a/server.py +++ b/server.py @@ -14,14 +14,13 @@ class MyServer(BaseHTTPRequestHandler): parts = path.split('/') if len(parts) == 1: - response(self, 200, 'html') action = parts[0].lower() - if False: pass # list accounts (plain text) elif action == 'list': + response(self, 200, 'html') accounts = os.listdir('./db/accounts') for acc in sorted(set(accounts)): echo(self, acc) @@ -30,9 +29,16 @@ class MyServer(BaseHTTPRequestHandler): # lists accounts on a pretty HTML + CSS # making sure there is no XSS possible on account names elif action == 'mirrors': + response(self, 200, 'html') html = igmirror.pixelfed_htmlfill_mirrors( igmirror.template('mirrors') ) return echo(self, html) + elif action == 'stories_update': + response(self, 200, 'json') + igmirror.pixelfed_dlstories_async() + return echo(self, {'status': 'ok', 'message': 'Stories mirroring asyncronous process started!'}) + + response(self, 200, 'json') return echo(self, {'status': 'error', 'message': '1st parameter action not defined: {}'.format(action)}) if len(parts) == 2: