2
2
import json
3
3
import sys
4
4
import urllib
5
+ import os
6
+ import codecs
5
7
6
8
from geopy .geocoders import Nominatim
7
9
from instagram_private_api import Client as AppClient
10
+ from instagram_private_api import ClientCookieExpiredError , ClientLoginRequiredError , ClientError
11
+
8
12
from prettytable import PrettyTable
9
13
10
14
from src import printcolors as pc
@@ -25,7 +29,7 @@ def __init__(self, target, is_file, is_json):
25
29
u = self .__getUsername__ ()
26
30
p = self .__getPassword__ ()
27
31
print ("\n Attempt to login..." )
28
- self .api = AppClient ( auto_patch = True , authenticate = True , username = u , password = p )
32
+ self .login ( u , p )
29
33
self .setTarget (target )
30
34
self .writeFile = is_file
31
35
self .jsonDump = is_json
@@ -88,10 +92,11 @@ def __get_comments__(self, media_id):
88
92
def __printTargetBanner__ (self ):
89
93
pc .printout ("\n Logged as " , pc .GREEN )
90
94
pc .printout (self .api .username , pc .CYAN )
91
- pc .printout (" (" + str (self .api .authenticated_user_id ) + ") " )
92
- pc .printout ("target: " , pc .GREEN )
95
+ pc .printout (". Target: " , pc .GREEN )
93
96
pc .printout (str (self .target ), pc .CYAN )
94
- pc .printout (" (private: " + str (self .is_private ) + ")" )
97
+ pc .printout (" [" + str (self .target_id ) + "] " )
98
+ if self .is_private :
99
+ pc .printout ("[PRIVATE PROFILE]" , pc .RED )
95
100
print ('\n ' )
96
101
97
102
def change_target (self ):
@@ -240,6 +245,7 @@ def get_total_comments(self):
240
245
241
246
for post in data :
242
247
comments_counter += post ['comment_count' ]
248
+ posts += 1
243
249
244
250
if self .writeFile :
245
251
file_name = "output/" + self .target + "_comments.txt"
@@ -488,6 +494,7 @@ def get_total_likes(self):
488
494
489
495
for post in data :
490
496
like_counter += post ['like_count' ]
497
+ posts += 1
491
498
492
499
if self .writeFile :
493
500
file_name = "output/" + self .target + "_likes.txt"
@@ -907,3 +914,57 @@ def set_json_dump(self, flag):
907
914
pc .printout ("\n " )
908
915
909
916
self .jsonDump = flag
917
+
918
+ def login (self , u , p ):
919
+ try :
920
+ settings_file = "config/settings.json"
921
+ if not os .path .isfile (settings_file ):
922
+ # settings file does not exist
923
+ print ('Unable to find file: {0!s}' .format (settings_file ))
924
+
925
+ # login new
926
+ self .api = AppClient (auto_patch = True , authenticate = True , username = u , password = p ,
927
+ on_login = lambda x : self .onlogin_callback (x , settings_file ))
928
+
929
+ else :
930
+ with open (settings_file ) as file_data :
931
+ cached_settings = json .load (file_data , object_hook = self .from_json )
932
+ #print('Reusing settings: {0!s}'.format(settings_file))
933
+
934
+ # reuse auth settings
935
+ self .api = AppClient (
936
+ username = u , password = p ,
937
+ settings = cached_settings ,
938
+ on_login = lambda x : self .onlogin_callback (x , settings_file ))
939
+
940
+ except (ClientCookieExpiredError , ClientLoginRequiredError ) as e :
941
+ print ('ClientCookieExpiredError/ClientLoginRequiredError: {0!s}' .format (e ))
942
+
943
+ # Login expired
944
+ # Do relogin but use default ua, keys and such
945
+ self .api = AppClient (auto_patch = True , authenticate = True , username = u , password = p ,
946
+ on_login = lambda x : self .onlogin_callback (x , settings_file ))
947
+
948
+ except ClientError as e :
949
+ #pc.printout('ClientError {0!s} (Code: {1:d}, Response: {2!s})'.format(e.msg, e.code, e.error_response), pc.RED)
950
+ error = json .loads (e .error_response )
951
+ pc .printout (error ['message' ], pc .RED )
952
+ pc .printout ("\n " )
953
+ exit (9 )
954
+
955
+ def to_json (self , python_object ):
956
+ if isinstance (python_object , bytes ):
957
+ return {'__class__' : 'bytes' ,
958
+ '__value__' : codecs .encode (python_object , 'base64' ).decode ()}
959
+ raise TypeError (repr (python_object ) + ' is not JSON serializable' )
960
+
961
+ def from_json (self , json_object ):
962
+ if '__class__' in json_object and json_object ['__class__' ] == 'bytes' :
963
+ return codecs .decode (json_object ['__value__' ].encode (), 'base64' )
964
+ return json_object
965
+
966
+ def onlogin_callback (self , api , new_settings_file ):
967
+ cache_settings = api .settings
968
+ with open (new_settings_file , 'w' ) as outfile :
969
+ json .dump (cache_settings , outfile , default = self .to_json )
970
+ #print('SAVED: {0!s}'.format(new_settings_file))
0 commit comments