Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 6
0
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
Exemplo n.º 7
0
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("")
Exemplo n.º 8
0
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