def start_session(self, args, device_wrapper, app_version, save_profile_info=True): self.session_state = SessionState() self.session_state.args = args.__dict__ self.session_state.app_id = args.app_id self.session_state.app_version = app_version self.sessions.append(self.session_state) device_wrapper.get().wake_up() print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) close_instagram(device_wrapper.device_id, device_wrapper.app_id) sleeper.random_sleep() if __version__.__debug_mode__: device_wrapper.get().start_screen_record() open_instagram(args.device, args.app_id) sleeper.random_sleep() if save_profile_info: self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get(), self.username) return self.session_state
def start_session(self, args, device_wrapper): self.session_state = SessionState() self.session_state.args = args.__dict__ self.sessions.append(self.session_state) print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) open_instagram(self.device) self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get()) return self.session_state
def migrate_from_json_to_sql(my_username): """ Migration from JSON storage (v3.4.2) to SQL storage (v3.5.0). """ if my_username is None: return interacted_users_path = os.path.join(my_username, FILENAME_INTERACTED_USERS) if os.path.exists(interacted_users_path): try: database = get_db(my_username) if database is None: return print( f"[Migration] Loading data from {FILENAME_INTERACTED_USERS}..." ) with open(interacted_users_path, encoding="utf-8") as json_file: interacted_users = json.load(json_file) usernames = [] last_interactions = [] following_statuses = [] sources = [] interaction_types = [] providers = [] for username in interacted_users.keys(): usernames.append(username) user = interacted_users[username] last_interactions.append( datetime.strptime(user[USER_LAST_INTERACTION], '%Y-%m-%d %H:%M:%S.%f')) following_statuses.append( FollowingStatus[user[USER_FOLLOWING_STATUS].upper()]) sources.append(None) interaction_types.append(None) providers.append(Provider.UNKNOWN) update_interacted_users(database, usernames, last_interactions, following_statuses, sources, interaction_types, providers) print( COLOR_BOLD + f"[Migration] Done! You can now delete {FILENAME_INTERACTED_USERS}" + COLOR_ENDC) except ValueError as e: print(COLOR_FAIL + f"[Migration] Cannot load {FILENAME_INTERACTED_USERS}: {e}" + COLOR_ENDC) scrapped_users_path = os.path.join(my_username, FILENAME_SCRAPPED_USERS) if os.path.exists(scrapped_users_path): try: database = get_db(my_username) if database is None: return print( f"[Migration] Loading data from {FILENAME_SCRAPPED_USERS}...") with open(scrapped_users_path, encoding="utf-8") as json_file: scrapped_users = json.load(json_file) usernames = [] last_interactions = [] scraping_statuses = [] for username in scrapped_users.keys(): usernames.append(username) user = scrapped_users[username] last_interactions.append( datetime.strptime(user[USER_LAST_INTERACTION], '%Y-%m-%d %H:%M:%S.%f')) scraping_statuses.append( ScrappingStatus[user[USER_SCRAPPING_STATUS].upper()]) update_scraped_users(database, usernames, last_interactions, scraping_statuses) print( COLOR_BOLD + f"[Migration] Done! You can now delete {FILENAME_SCRAPPED_USERS}" + COLOR_ENDC) except ValueError as e: print(COLOR_FAIL + f"[Migration] Cannot load {FILENAME_SCRAPPED_USERS}: {e}" + COLOR_ENDC) filtered_users_path = os.path.join(my_username, FILENAME_FILTERED_USERS) if os.path.exists(filtered_users_path): try: database = get_db(my_username) if database is None: return print( f"[Migration] Loading data from {FILENAME_FILTERED_USERS}...") with open(filtered_users_path, encoding="utf-8") as json_file: filtered_users = json.load(json_file) usernames = [] filtered_at_list = [] for username in filtered_users.keys(): usernames.append(username) user = filtered_users[username] filtered_at_list.append( datetime.strptime(user[USER_FILTERED_AT], '%Y-%m-%d %H:%M:%S.%f')) update_filtered_users(database, usernames, filtered_at_list) print( COLOR_BOLD + f"[Migration] Done! You can now delete {FILENAME_FILTERED_USERS}" + COLOR_ENDC) except ValueError as e: print(COLOR_FAIL + f"[Migration] Cannot load {FILENAME_FILTERED_USERS}: {e}" + COLOR_ENDC) sessions_path = os.path.join(my_username, FILENAME_SESSIONS) if os.path.exists(sessions_path): try: database = get_db(my_username) if database is None: return print(f"[Migration] Loading data from {FILENAME_SESSIONS}...") sessions_persistent_list = Sessions() with open(sessions_path, encoding="utf-8") as json_file: sessions = json.load(json_file) for session in sessions: session_state = SessionState() session_state.id = session["id"] session_state.args = str(session["args"]) session_state.app_version = session.get("app_version", "") session_state.my_username = my_username session_state.my_followers_count = session["profile"].get( "followers", 0) session_state.my_following_count = session["profile"].get( "following", 0) session_state.totalInteractions = { None: session["total_interactions"] } session_state.successfulInteractions = { None: session["successful_interactions"] } session_state.totalFollowed = { None: session["total_followed"] } session_state.totalScraped = session.get( "total_scraped", {}) session_state.totalLikes = session["total_likes"] session_state.totalGetProfile = session.get( "total_get_profile", 0) session_state.totalUnfollowed = session.get( "total_unfollowed", 0) session_state.totalStoriesWatched = session.get( "total_stories_watched", 0) if "removed_mass_followers" in session: session_state.removedMassFollowers = session[ "removed_mass_followers"] if "total_removed_mass_followers" in session: session_state.removedMassFollowers = session[ "total_removed_mass_followers"] session_state.startTime = datetime.strptime( session["start_time"], '%Y-%m-%d %H:%M:%S.%f') if session.get("finish_time") != "None": session_state.finishTime = datetime.strptime( session["finish_time"], '%Y-%m-%d %H:%M:%S.%f') sessions_persistent_list.append(session_state) sessions_persistent_list.persist(my_username) print( COLOR_BOLD + f"[Migration] Done! You can now delete {FILENAME_SESSIONS}" + COLOR_ENDC) except ValueError as e: print(COLOR_FAIL + f"[Migration] Cannot load {FILENAME_SESSIONS}: {e}" + COLOR_ENDC)
class InsomniacSession(object): SESSION_ARGS = { "repeat": { "help": 'repeat the same session again after N minutes after completion, disabled by default. ' 'It can be a number of minutes (e.g. 180) or a range (e.g. 120-180)', "metavar": '120-180' }, "device": { "help": 'device identifier. Should be used only when multiple devices are connected at once', "metavar": '2443de990e017ece' }, "old": { 'help': 'add this flag to use an old version of uiautomator. Use it only if you experience ' 'problems with the default version', 'action': 'store_true' } } repeat = None device = None old = None def __init__(self): random.seed() colorama.init() self.sessions = sessions self.storage = None self.session_state = None self.actions_mgr = ActionRunnersManager() self.limits_mgr = LimitsManager() def get_session_args(self): all_args = {} all_args.update(self.SESSION_ARGS) all_args.update(self.actions_mgr.get_actions_args()) all_args.update(self.limits_mgr.get_limits_args()) return all_args def set_session_args(self, args): if args.repeat is not None: self.repeat = get_value(args.repeat, "Sleep time (min) before repeat: {}", 180) def parse_args_and_get_device_wrapper(self): ok, args = parse_arguments(self.get_session_args()) if not ok: return None, None device_wrapper = DeviceWrapper(args.device, args.old) device = device_wrapper.get() if device is None: return None, None print("Instagram version: " + get_instagram_version()) return args, device_wrapper def start_session(self, args, device_wrapper): self.session_state = SessionState() self.session_state.args = args.__dict__ self.sessions.append(self.session_state) print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) open_instagram(self.device) self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get()) return self.session_state def end_session(self, device_wrapper): close_instagram(device_wrapper.device_id) print_copyright() self.session_state.finishTime = datetime.now() print_timeless(COLOR_REPORT + "-------- FINISH: " + str(self.session_state.finishTime) + " --------" + COLOR_ENDC) def repeat_session(self, args): print_full_report(self.sessions) print_timeless("") self.sessions.persist(directory=self.session_state.my_username) print("Sleep for {} minutes".format(self.repeat)) try: sleep(60 * self.repeat) refresh_args_by_conf_file(args) except KeyboardInterrupt: print_full_report(self.sessions) self.sessions.persist(directory=self.session_state.my_username) sys.exit(0) def on_action_callback(self, action): self.session_state.add_action(action) self.limits_mgr.update_state(action) def run(self): args, device_wrapper = self.parse_args_and_get_device_wrapper() while True: if args is None or device_wrapper is None: return self.set_session_args(args) action_runner = self.actions_mgr.select_action_runner(args) if action_runner is None: return action_runner.set_params(args) self.limits_mgr.set_limits(args) try: self.start_session(args, device_wrapper) self.storage = Storage(self.session_state.my_username, args) action_runner.run(device_wrapper, self.storage, self.session_state, self.on_action_callback, self.limits_mgr.is_limit_reached_for_action) self.end_session(device_wrapper) except Exception as ex: if __debug_mode__: raise ex else: print_timeless(COLOR_FAIL + f"\nCaught an exception:\n{ex}" + COLOR_ENDC) save_crash(device_wrapper.get()) if self.repeat is not None: self.repeat_session(args) else: break print_full_report(self.sessions) self.sessions.persist(directory=self.session_state.my_username)
class InsomniacSession(object): SESSION_ARGS = { "repeat": { "help": 'repeat the same session again after N minutes after completion, disabled by default. ' 'It can be a number of minutes (e.g. 180) or a range (e.g. 120-180)', "metavar": '120-180' }, "device": { "help": 'device identifier. Should be used only when multiple devices are connected at once', "metavar": '2443de990e017ece' }, "wait_for_device": { 'help': 'keep waiting for ADB-device to be ready for connection (if no device-id is provided using ' '--device flag, will wait for any available device)', 'action': 'store_true', "default": False }, "no_speed_check": { 'help': 'skip internet speed check at start', 'action': 'store_true' }, "old": { 'help': 'add this flag to use an old version of uiautomator. Use it only if you experience ' 'problems with the default version', 'action': 'store_true' }, "app_id": { "help": 'apk package identifier. Should be used only if you are using cloned-app. ' 'Using \'com.instagram.android\' by default', "metavar": 'com.instagram.android', "default": 'com.instagram.android' }, "dont_indicate_softban": { "help": "by default, Insomniac tried to indicate if there is a softban on your acoount. set this flag in " "order to ignore those soft-ban indicators", 'action': 'store_true', "default": False }, "debug": { 'help': 'add this flag to insomniac in debug mode (more verbose logs)', 'action': 'store_true' }, "username": { "help": 'if you have configured multiple Instagram accounts in your app, use this parameter in order to ' 'switch into a specific one. Not trying to switch account by default. ' 'If the account does not exist - the session wont started', "metavar": 'my_account_name', "default": None }, "next_config_file": { "help": 'if you want to run multiple insomniac sessions one-by-one but with different parameters, ' 'for example - different action (interact and then unfollow), or same config but with different username, ' 'or any other variation of parameters you can think of, you can combine this parameter with the "repeat"-parameter, ' 'and after the sleep of the "repeat"-parameter, a new config file (referenced by this parameter) will be loaded. ' 'By default using the same config that been loaded in the first Insominac session. You must use "repeat"-parameter ' 'in order for that parameter take action!', "metavar": 'next_session_config_file_path', "default": None }, } repeat = None device = None old = None username = None next_config_file = None def __init__(self): random.seed() colorama.init() self.sessions = sessions self.storage = None self.session_state = None self.actions_mgr = ActionRunnersManager() self.limits_mgr = LimitsManager() def get_session_args(self): all_args = {} all_args.update(self.SESSION_ARGS) all_args.update(STORAGE_ARGS) all_args.update(self.actions_mgr.get_actions_args()) all_args.update(self.limits_mgr.get_limits_args()) return all_args def set_session_args(self, args): if args.repeat is not None: self.repeat = get_value(args.repeat, "Sleep time (min) before repeat: {}", 180) if args.debug is not None: insomniac.__version__.__debug_mode__ = True if args.dont_indicate_softban: insomniac.softban_indicator.should_indicate_softban = False if args.username is not None: self.username = args.username if args.next_config_file is not None: self.next_config_file = args.next_config_file def parse_args(self): ok, args = parse_arguments(self.get_session_args()) if not ok: return None return args def get_device_wrapper(self, args): device_wrapper = DeviceWrapper(args.device, args.old, args.wait_for_device, args.app_id) device = device_wrapper.get() if device is None: return None, None app_version = get_instagram_version(args.device, args.app_id) print("Instagram version: " + app_version) return device_wrapper, app_version def start_session(self, args, device_wrapper, app_version): self.session_state = SessionState() self.session_state.args = args.__dict__ self.session_state.app_version = app_version self.sessions.append(self.session_state) device_wrapper.get().wake_up() print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) close_instagram(device_wrapper.device_id, device_wrapper.app_id) sleeper.random_sleep() open_instagram(args.device, args.app_id) sleeper.random_sleep() self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get(), self.username) return self.session_state def end_session(self, device_wrapper): close_instagram(device_wrapper.device_id, device_wrapper.app_id) print_copyright() self.session_state.finishTime = datetime.now() print_timeless(COLOR_REPORT + "-------- FINISH: " + str(self.session_state.finishTime) + " --------" + COLOR_ENDC) print_full_report(self.sessions) print_timeless("") self.sessions.persist(self.session_state.my_username) def repeat_session(self, args): print("Sleep for {} minutes".format(self.repeat)) try: sleep(60 * self.repeat) return refresh_args_by_conf_file(args, self.next_config_file) except KeyboardInterrupt: print_full_report(self.sessions) self.sessions.persist(self.session_state.my_username) sys.exit(0) def on_action_callback(self, action): self.session_state.add_action(action) self.limits_mgr.update_state(action) def print_session_params(self, args): print_debug("All parameters:") for k, v in vars(args).items(): print_debug(f"{k}: {v} (value-type: {type(v)})") def run(self): args = self.parse_args() if args is None: return if not args.no_speed_check: print( "Checking your Internet speed to adjust the script speed, please wait for a minute..." ) print("(use " + COLOR_BOLD + "--no-speed-check" + COLOR_ENDC + " to skip this check)") sleeper.update_random_sleep_range() while True: self.print_session_params(args) device_wrapper, app_version = self.get_device_wrapper(args) if device_wrapper is None: return self.set_session_args(args) action_runner = self.actions_mgr.select_action_runner(args) if action_runner is None: return action_runner.set_params(args) self.limits_mgr.set_limits(args) try: self.start_session(args, device_wrapper, app_version) migrate_from_json_to_sql(self.session_state.my_username) self.storage = Storage(self.session_state.my_username, args) action_runner.run(device_wrapper, self.storage, self.session_state, self.on_action_callback, self.limits_mgr.is_limit_reached_for_action) except (KeyboardInterrupt, UserSwitchFailedException, DatabaseMigrationFailedException): self.end_session(device_wrapper) return except ActionBlockedError as ex: print_timeless("") print_timeless(COLOR_FAIL + str(ex) + COLOR_ENDC) self.end_session(device_wrapper) return except Exception as ex: if __debug_mode__: raise ex else: print_timeless(COLOR_FAIL + f"\nCaught an exception:\n{ex}" + COLOR_ENDC) print(COLOR_FAIL + traceback.format_exc() + COLOR_ENDC) save_crash(device_wrapper.get(), ex) self.end_session(device_wrapper) if self.repeat is not None: if not self.repeat_session(args): break else: break
class InsomniacSession(object): SESSION_ARGS = { "repeat": { "help": 'repeat the same session again after N minutes after completion, disabled by default. ' 'It can be a number of minutes (e.g. 180) or a range (e.g. 120-180)', "metavar": '120-180' }, "device": { "help": 'device identifier. Should be used only when multiple devices are connected at once', "metavar": '2443de990e017ece' }, "wait_for_device": { 'help': 'keep waiting for ADB-device to be ready for connection (if no device-id is provided using ' '--device flag, will wait for any available device)', 'action': 'store_true', "default": False }, "no_speed_check": { 'help': 'skip internet speed check at start', 'action': 'store_true' }, "old": { 'help': 'add this flag to use an old version of uiautomator. Use it only if you experience ' 'problems with the default version', 'action': 'store_true' }, "app_id": { "help": 'apk package identifier. Should be used only if you are using cloned-app. ' 'Using \'com.instagram.android\' by default', "metavar": 'com.instagram.android', "default": 'com.instagram.android' }, "dont_indicate_softban": { "help": "by default, Insomniac tried to indicate if there is a softban on your acoount. set this flag in " "order to ignore those soft-ban indicators", 'action': 'store_true', "default": False }, "debug": { 'help': 'add this flag to insomniac in debug mode (more verbose logs)', 'action': 'store_true' } } repeat = None device = None old = None def __init__(self): random.seed() colorama.init() self.sessions = sessions self.storage = None self.session_state = None self.actions_mgr = ActionRunnersManager() self.limits_mgr = LimitsManager() def get_session_args(self): all_args = {} all_args.update(self.SESSION_ARGS) all_args.update(STORAGE_ARGS) all_args.update(self.actions_mgr.get_actions_args()) all_args.update(self.limits_mgr.get_limits_args()) return all_args def set_session_args(self, args): if args.repeat is not None: self.repeat = get_value(args.repeat, "Sleep time (min) before repeat: {}", 180) if args.debug is not None: insomniac.__version__.__debug_mode__ = True if args.dont_indicate_softban: insomniac.softban_indicator.should_indicate_softban = False def parse_args_and_get_device_wrapper(self): ok, args = parse_arguments(self.get_session_args()) if not ok: return None, None, None device_wrapper = DeviceWrapper(args.device, args.old, args.wait_for_device, args.app_id) device = device_wrapper.get() if device is None: return None, None, None app_version = get_instagram_version(args.device, args.app_id) print("Instagram version: " + app_version) return args, device_wrapper, app_version def start_session(self, args, device_wrapper, app_version): self.session_state = SessionState() self.session_state.args = args.__dict__ self.session_state.app_version = app_version self.sessions.append(self.session_state) device_wrapper.get().wake_up() print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) open_instagram(args.device, args.app_id) sleeper.random_sleep() self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get()) return self.session_state def end_session(self, device_wrapper): close_instagram(device_wrapper.device_id, device_wrapper.app_id) print_copyright() self.session_state.finishTime = datetime.now() print_timeless(COLOR_REPORT + "-------- FINISH: " + str(self.session_state.finishTime) + " --------" + COLOR_ENDC) print_full_report(self.sessions) print_timeless("") self.sessions.persist(self.session_state.my_username) def repeat_session(self, args): print("Sleep for {} minutes".format(self.repeat)) try: sleep(60 * self.repeat) refresh_args_by_conf_file(args) except KeyboardInterrupt: print_full_report(self.sessions) self.sessions.persist(self.session_state.my_username) sys.exit(0) def on_action_callback(self, action): self.session_state.add_action(action) self.limits_mgr.update_state(action) def run(self): args, device_wrapper, app_version = self.parse_args_and_get_device_wrapper( ) if args is None or device_wrapper is None: return if not args.no_speed_check: print( "Checking your Internet speed to adjust the script speed, please wait for a minute..." ) print("(use " + COLOR_BOLD + "--no-speed-check" + COLOR_ENDC + " to skip this check)") sleeper.update_random_sleep_range() while True: self.set_session_args(args) action_runner = self.actions_mgr.select_action_runner(args) if action_runner is None: return action_runner.set_params(args) self.limits_mgr.set_limits(args) try: self.start_session(args, device_wrapper, app_version) migrate_from_json_to_sql(self.session_state.my_username) self.storage = Storage(self.session_state.my_username, args) action_runner.run(device_wrapper, self.storage, self.session_state, self.on_action_callback, self.limits_mgr.is_limit_reached_for_action) except KeyboardInterrupt: self.end_session(device_wrapper) return except ActionBlockedError as ex: print_timeless("") print_timeless(COLOR_FAIL + str(ex) + COLOR_ENDC) self.end_session(device_wrapper) return except Exception as ex: if __debug_mode__: raise ex else: print_timeless(COLOR_FAIL + f"\nCaught an exception:\n{ex}" + COLOR_ENDC) save_crash(device_wrapper.get(), ex) self.end_session(device_wrapper) if self.repeat is not None: self.repeat_session(args) else: break
class InsomniacSession(Session): INSOMNIAC_SESSION_ARGS = { "device": { "help": 'device identifier. Should be used only when multiple devices are connected at once', "metavar": '2443de990e017ece' }, "wait_for_device": { 'help': 'keep waiting for ADB-device to be ready for connection (if no device-id is provided using ' '--device flag, will wait for any available device)', 'action': 'store_true', "default": False }, "no_speed_check": { 'help': 'skip internet speed check at start', 'action': 'store_true' }, "app_id": { "help": 'apk package identifier. Should be used only if you are using cloned-app. ' 'Using \'com.instagram.android\' by default', "metavar": 'com.instagram.android', "default": 'com.instagram.android' }, "app_name": { "default": None }, "dont_indicate_softban": { "help": "by default Insomniac tries to indicate if there is a softban on your acoount. Set this flag in " "order to ignore those softban indicators", 'action': 'store_true', "default": False }, "dont_validate_profile_existence": { "help": "by default, when interacting with targets, Insomniac tries to indicate if the instagram-profile " "you are trying to interact-with truly exists. Set this flag in order to ignore those " "existence-indicators", 'action': 'store_true', "default": False }, "username": { "help": 'if you have configured multiple Instagram accounts in your app, use this parameter in order to ' 'switch into a specific one. Not trying to switch account by default. ' 'If the account does not exist - the session won\'t start', "metavar": 'my_account_name', "default": None } } device = None username = None def __init__(self, starter_conf_file_path=None): super().__init__(starter_conf_file_path) self.storage = None self.session_state = None self.actions_mgr = CoreActionRunnersManager() self.limits_mgr = LimitsManager() def get_session_args(self): all_args = super().get_session_args() all_args.update(self.INSOMNIAC_SESSION_ARGS) all_args.update(STORAGE_ARGS) all_args.update(self.actions_mgr.get_actions_args()) all_args.update(self.limits_mgr.get_limits_args()) return all_args def reset_params(self): super().reset_params() self.username = None softban_indicator.should_indicate_softban = True insomniac_validations.should_validate_profile_existence = True def set_session_args(self, args): super().set_session_args(args) if args.dont_indicate_softban: softban_indicator.should_indicate_softban = False if args.dont_validate_profile_existence: insomniac_validations.should_validate_profile_existence = False if args.username is not None: self.username = args.username def get_device_wrapper(self, args): device_wrapper = DeviceWrapper(args.device, args.old, args.wait_for_device, args.app_id, args.app_name, args.no_typing) device = device_wrapper.get() if device is None: return None, None app_version = get_instagram_version(device_wrapper.device_id, device_wrapper.app_id) print("Instagram version: " + app_version) self.verify_instagram_version(app_version) return device_wrapper, app_version def prepare_session_state(self, args, device_wrapper, app_version, save_profile_info=True): self.session_state = SessionState() self.session_state.args = args.__dict__ self.session_state.app_id = args.app_id self.session_state.app_version = app_version self.sessions.append(self.session_state) device_wrapper.get().wake_up() print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) if __version__.__debug_mode__: device_wrapper.get().start_screen_record() open_instagram(device_wrapper.device_id, device_wrapper.app_id) if save_profile_info: self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get(), self.username) return self.session_state def end_session(self, device_wrapper, with_app_closing=True): if with_app_closing: close_instagram_and_system_dialogs(device_wrapper.get()) if __version__.__debug_mode__: device_wrapper.get().stop_screen_record() print_copyright() self.session_state.end_session() print_timeless(COLOR_REPORT + "-------- FINISH: " + str(self.session_state.finishTime) + " --------" + COLOR_ENDC) print_full_report(self.sessions) print_timeless("") def on_action_callback(self, action): self.session_state.add_action(action) self.limits_mgr.update_state(action) def run(self): args = self.parse_args() if args is None: return while True: self.print_session_params(args) self.update_session_speed(args) device_wrapper, app_version = self.get_device_wrapper(args) if device_wrapper is None: return self.set_session_args(args) action_runner = self.actions_mgr.select_action_runner(args) if action_runner is None: return action_runner.reset_params() action_runner.set_params(args) self.limits_mgr.set_limits(args) try: self.prepare_session_state(args, device_wrapper, app_version, save_profile_info=True) migrate_from_json_to_sql(self.session_state.my_username) migrate_from_sql_to_peewee(self.session_state.my_username) self.storage = Storage(self.session_state.my_username, args) self.session_state.set_storage_layer(self.storage) self.session_state.start_session() action_runner.run(device_wrapper, self.storage, self.session_state, self.on_action_callback, self.limits_mgr.is_limit_reached_for_action) except (KeyboardInterrupt, UserSwitchFailedException, DatabaseMigrationFailedException): self.end_session(device_wrapper) return except ActionBlockedError as ex: print_timeless("") print(COLOR_FAIL + describe_exception(ex, with_stacktrace=False) + COLOR_ENDC) save_crash(device_wrapper.get()) if self.next_config_file is None: self.end_session(device_wrapper) return except Exception as ex: if __version__.__debug_mode__: raise ex else: print(COLOR_FAIL + describe_exception(ex) + COLOR_ENDC) save_crash(device_wrapper.get(), ex) self.end_session(device_wrapper, with_app_closing=(not self.is_next_app_id_same(args, device_wrapper))) if self.repeat is not None: if not self.repeat_session(args): break else: break @staticmethod def verify_instagram_version(installed_ig_version): code, body, _ = network.get(f"https://insomniac-bot.com/get_latest_supported_ig_version/") if code == HTTP_OK and body is not None: json_config = json.loads(body) latest_supported_ig_version = json_config['message'] else: return try: is_ok = versiontuple(installed_ig_version) <= versiontuple(latest_supported_ig_version) except ValueError: print_debug(COLOR_FAIL + "Cannot compare IG versions" + COLOR_ENDC) return if not is_ok: print_timeless("") print_timeless(COLOR_FAIL + f"IG version ({installed_ig_version}) is newer than " f"latest supported ({latest_supported_ig_version})." + COLOR_ENDC) if insomniac_globals.is_insomniac(): print_timeless(COLOR_FAIL + "Please uninstall IG and download recommended apk from here:" + COLOR_ENDC) print_timeless(COLOR_FAIL + COLOR_BOLD + "https://insomniac-bot.com/get_latest_supported_ig_apk/" + COLOR_ENDC) print_timeless("")
class InsomniacSession(object): SESSION_ARGS = { "repeat": { "help": 'repeat the same session again after N minutes after completion, disabled by default. ' 'It can be a number of minutes (e.g. 180) or a range (e.g. 120-180)', "metavar": '120-180' }, "device": { "help": 'device identifier. Should be used only when multiple devices are connected at once', "metavar": '2443de990e017ece' }, "wait_for_device": { 'help': 'keep waiting for ADB-device to be ready for connection (if no device-id is provided using ' '--device flag, will wait for any available device)', 'action': 'store_true', "default": False }, "no_speed_check": { 'help': 'skip internet speed check at start', 'action': 'store_true' }, "no_typing": { 'help': 'disable "typing" feature (typing symbols one-by-one as a human)', 'action': 'store_true' }, "old": { 'help': 'add this flag to use an old version of uiautomator. Use it only if you experience ' 'problems with the default version', 'action': 'store_true' }, "app_id": { "help": 'apk package identifier. Should be used only if you are using cloned-app. ' 'Using \'com.instagram.android\' by default', "metavar": 'com.instagram.android', "default": 'com.instagram.android' }, "dont_indicate_softban": { "help": "by default Insomniac tries to indicate if there is a softban on your acoount. Set this flag in " "order to ignore those softban indicators", 'action': 'store_true', "default": False }, "dont_validate_profile_existence": { "help": "by default, when interacting with targets, Insomniac tries to indicate if the instagram-profile " "you are trying to interact-with truly exists. Set this flag in order to ignore those " "existence-indicators", 'action': 'store_true', "default": False }, "debug": { 'help': 'add this flag to run insomniac in debug mode (more verbose logs)', 'action': 'store_true' }, "username": { "help": 'if you have configured multiple Instagram accounts in your app, use this parameter in order to ' 'switch into a specific one. Not trying to switch account by default. ' 'If the account does not exist - the session won\'t start', "metavar": 'my_account_name', "default": None }, "next_config_file": { "help": 'configuration that will be loaded after session is finished and the bot \"sleeps\" for time ' 'specified by the \"--repeat\" argument. You can use this argument to run multiple Insomniac ' 'sessions one by one with different parameters. E.g. different action (interact and then unfollow),' ' or different \"--username\". By default uses the same config file as been loaded for the first ' 'session. Note that you must use \"--repeat\" with this argument!', "metavar": 'CONFIG_FILE', "default": None }, "speed": { 'help': 'manually specify the speed setting, from 1 (slowest) to 4 (fastest)', 'metavar': '1-4', 'type': int, 'choices': range(1, 5) }, } repeat = None device = None old = None username = None next_config_file = None def __init__(self, starter_conf_file_path=None): self.starter_conf_file_path = starter_conf_file_path self.sessions = sessions self.storage = None self.session_state = None self.actions_mgr = ActionRunnersManager() self.limits_mgr = LimitsManager() def get_session_args(self): all_args = {} all_args.update(self.SESSION_ARGS) all_args.update(STORAGE_ARGS) all_args.update(self.actions_mgr.get_actions_args()) all_args.update(self.limits_mgr.get_limits_args()) return all_args def reset_params(self): self.repeat = None self.username = None self.next_config_file = None __version__.__debug_mode__ = False softban_indicator.should_indicate_softban = True insomniac_validations.should_validate_profile_existence = True def set_session_args(self, args): self.reset_params() if args.repeat is not None: self.repeat = get_value(args.repeat, "Sleep time (min) before repeat: {}", 180) if args.debug is not None and bool(args.debug): __version__.__debug_mode__ = True if args.dont_indicate_softban: softban_indicator.should_indicate_softban = False if args.dont_validate_profile_existence: insomniac_validations.should_validate_profile_existence = False if args.username is not None: self.username = args.username if args.next_config_file is not None: self.next_config_file = args.next_config_file def parse_args(self): ok, args = parse_arguments(self.get_session_args(), self.starter_conf_file_path) if not ok: return None return args def get_device_wrapper(self, args): device_wrapper = DeviceWrapper(args.device, args.old, args.wait_for_device, args.app_id, args.no_typing) device = device_wrapper.get() if device is None: return None, None app_version = get_instagram_version(args.device, args.app_id) print("Instagram version: " + app_version) return device_wrapper, app_version def start_session(self, args, device_wrapper, app_version, save_profile_info=True): self.session_state = SessionState() self.session_state.args = args.__dict__ self.session_state.app_id = args.app_id self.session_state.app_version = app_version self.sessions.append(self.session_state) device_wrapper.get().wake_up() print_timeless(COLOR_REPORT + "\n-------- START: " + str(self.session_state.startTime) + " --------" + COLOR_ENDC) close_instagram(device_wrapper.device_id, device_wrapper.app_id) sleeper.random_sleep() if __version__.__debug_mode__: device_wrapper.get().start_screen_record() open_instagram(args.device, args.app_id) sleeper.random_sleep() if save_profile_info: self.session_state.my_username, \ self.session_state.my_followers_count, \ self.session_state.my_following_count = get_my_profile_info(device_wrapper.get(), self.username) return self.session_state def end_session(self, device_wrapper): close_instagram(device_wrapper.device_id, device_wrapper.app_id) if __version__.__debug_mode__: device_wrapper.get().stop_screen_record() print_copyright() self.session_state.end_session() print_timeless(COLOR_REPORT + "-------- FINISH: " + str(self.session_state.finishTime) + " --------" + COLOR_ENDC) print_full_report(self.sessions) print_timeless("") def repeat_session(self, args): print("Sleep for {} minutes".format(self.repeat)) try: sleep(60 * self.repeat) return refresh_args_by_conf_file(args, self.next_config_file) except KeyboardInterrupt: print_full_report(self.sessions) sys.exit(0) def on_action_callback(self, action): self.session_state.add_action(action) self.limits_mgr.update_state(action) def print_session_params(self, args): if args.debug: print("All parameters:") for k, v in vars(args).items(): print(f"{k}: {v} (value-type: {type(v)})") def run(self): args = self.parse_args() if args is None: return while True: self.print_session_params(args) if args.speed is not None: sleeper.set_random_sleep_range(int(args.speed)) elif not args.no_speed_check: print( "Checking your Internet speed to adjust the script speed, please wait for a minute..." ) print("(use " + COLOR_BOLD + "--no-speed-check" + COLOR_ENDC + " to skip this check)") sleeper.update_random_sleep_range() device_wrapper, app_version = self.get_device_wrapper(args) if device_wrapper is None: return self.set_session_args(args) action_runner = self.actions_mgr.select_action_runner(args) if action_runner is None: return action_runner.set_params(args) self.limits_mgr.set_limits(args) try: self.start_session(args, device_wrapper, app_version, save_profile_info=True) migrate_from_json_to_sql(self.session_state.my_username) migrate_from_sql_to_peewee(self.session_state.my_username) self.storage = Storage(self.session_state.my_username, args) self.session_state.set_storage_layer(self.storage) action_runner.run(device_wrapper, self.storage, self.session_state, self.on_action_callback, self.limits_mgr.is_limit_reached_for_action) except (KeyboardInterrupt, UserSwitchFailedException, DatabaseMigrationFailedException): self.end_session(device_wrapper) return except ActionBlockedError as ex: print_timeless("") print_timeless(COLOR_FAIL + str(ex) + COLOR_ENDC) if self.next_config_file is None: self.end_session(device_wrapper) return except Exception as ex: if __version__.__debug_mode__: raise ex else: print_timeless(COLOR_FAIL + f"\nCaught an exception:\n" + COLOR_ENDC) print(COLOR_FAIL + describe_exception(ex) + COLOR_ENDC) save_crash(device_wrapper.get(), ex) self.end_session(device_wrapper) if self.repeat is not None: if not self.repeat_session(args): break else: break