Esempio n. 1
0
    def iterate_over_followers(self,
                               is_myself,
                               iteration_callback,
                               iteration_callback_pre_conditions,
                               iterate_without_sleep=False):
        FOLLOW_LIST_CONTAINER_ID_REGEX = case_insensitive_re(
            [f"{self.device.app_id}:id/follow_list_container"])
        ROW_SEARCH_ID_REGEX = case_insensitive_re(
            [f"{self.device.app_id}:id/row_search_edit_text"])
        LOAD_MORE_BUTTON_ID_REGEX = case_insensitive_re(
            [f"{self.device.app_id}:id/row_load_more_button"])

        # Wait until list is rendered
        self.device.find(resourceIdMatches=FOLLOW_LIST_CONTAINER_ID_REGEX,
                         className='android.widget.LinearLayout').wait()

        def scrolled_to_top():
            row_search = self.device.find(
                resourceIdMatches=ROW_SEARCH_ID_REGEX,
                className='android.widget.EditText')
            return row_search.exists()

        prev_screen_iterated_followers = []
        scroll_end_detector = ScrollEndDetector()
        while True:
            print("Iterate over visible followers")
            if not iterate_without_sleep:
                sleeper.random_sleep()

            screen_iterated_followers = []
            screen_skipped_followers_count = 0
            scroll_end_detector.notify_new_page()

            try:
                for item in self.device.find(
                        resourceIdMatches=FOLLOW_LIST_CONTAINER_ID_REGEX,
                        className='android.widget.LinearLayout'):
                    user_info_view = item.child(index=1)
                    user_name_view = user_info_view.child(index=0).child()
                    if not user_name_view.exists(quick=True):
                        print(
                            COLOR_OKGREEN +
                            "Next item not found: probably reached end of the screen."
                            + COLOR_ENDC)
                        break

                    try:
                        username = user_name_view.get_text()
                    except DeviceFacade.JsonRpcError:
                        print(
                            COLOR_OKGREEN +
                            "Next item was found, but its text is half-cutted / invisible, "
                            "moving on to next row." + COLOR_ENDC)
                        continue

                    screen_iterated_followers.append(username)
                    scroll_end_detector.notify_username_iterated(username)

                    if not iteration_callback_pre_conditions(
                            username, user_name_view):
                        screen_skipped_followers_count += 1
                        continue

                    to_continue = iteration_callback(username, user_name_view)
                    if not to_continue:
                        print(COLOR_OKBLUE + "Stopping followers iteration" +
                              COLOR_ENDC)
                        return

            except IndexError:
                print(
                    COLOR_FAIL +
                    "Cannot get next item: probably reached end of the screen."
                    + COLOR_ENDC)

            if is_myself and scrolled_to_top():
                print(COLOR_OKGREEN + "Scrolled to top, finish." + COLOR_ENDC)
                return
            elif len(screen_iterated_followers) > 0:
                load_more_button = self.device.find(
                    resourceIdMatches=LOAD_MORE_BUTTON_ID_REGEX)
                load_more_button_exists = load_more_button.exists(quick=True)

                if scroll_end_detector.is_the_end():
                    return

                need_swipe = screen_skipped_followers_count == len(
                    screen_iterated_followers)
                list_view = self.device.find(
                    resourceId='android:id/list',
                    className='android.widget.ListView')
                if not list_view.exists():
                    print(
                        COLOR_FAIL +
                        "Cannot find the list of followers. Trying to press back again."
                        + COLOR_ENDC)
                    self.device.back()
                    list_view = self.device.find(
                        resourceId='android:id/list',
                        className='android.widget.ListView')

                if is_myself:
                    print(COLOR_OKGREEN + "Need to scroll now" + COLOR_ENDC)
                    list_view.scroll(DeviceFacade.Direction.TOP)
                else:
                    pressed_retry = False
                    if load_more_button_exists:
                        retry_button = load_more_button.child(
                            className='android.widget.ImageView')
                        if retry_button.exists():
                            print("Press \"Load\" button")
                            retry_button.click()
                            sleeper.random_sleep()
                            pressed_retry = True

                    if need_swipe and not pressed_retry:
                        print(COLOR_OKGREEN +
                              "All followers skipped, let's do a swipe" +
                              COLOR_ENDC)
                        list_view.swipe(DeviceFacade.Direction.BOTTOM)
                    else:
                        print(COLOR_OKGREEN + "Need to scroll now" +
                              COLOR_ENDC)
                        list_view.scroll(DeviceFacade.Direction.BOTTOM)

                prev_screen_iterated_followers.clear()
                prev_screen_iterated_followers += screen_iterated_followers
            else:
                print(COLOR_OKGREEN + "No followers were iterated, finish." +
                      COLOR_ENDC)
                return
Esempio n. 2
0
def iterate_over_followers(device,
                           is_myself,
                           iteration_callback,
                           iteration_callback_pre_conditions,
                           iterate_without_sleep=False,
                           check_item_was_removed=False):
    # Wait until list is rendered
    device.find(resourceId=f'{device.app_id}:id/follow_list_container',
                className='android.widget.LinearLayout').wait()

    def scrolled_to_top():
        row_search = device.find(
            resourceId=f'{device.app_id}:id/row_search_edit_text',
            className='android.widget.EditText')
        return row_search.exists()

    prev_screen_iterated_followers = []
    scroll_end_detector = ScrollEndDetector()
    while True:
        try:
            print("Iterate over visible followers")
            if not iterate_without_sleep:
                sleeper.random_sleep()

            screen_iterated_followers = []
            screen_skipped_followers_count = 0
            scroll_end_detector.notify_new_page()

            try:
                for item in device.find(
                        resourceId=f'{device.app_id}:id/follow_list_container',
                        className='android.widget.LinearLayout'):
                    user_info_view = item.child(index=1)
                    user_name_view = user_info_view.child(index=0).child()
                    if not user_name_view.exists(quick=True):
                        print(
                            COLOR_OKGREEN +
                            "Next item not found: probably reached end of the screen."
                            + COLOR_ENDC)
                        break

                    username = user_name_view.get_text()
                    screen_iterated_followers.append(username)
                    scroll_end_detector.notify_username_iterated(username)

                    if not iteration_callback_pre_conditions(
                            username, user_name_view):
                        screen_skipped_followers_count += 1
                        continue

                    to_continue = iteration_callback(username, user_name_view)
                    if not to_continue:
                        print(COLOR_OKBLUE + "Stopping followers iteration" +
                              COLOR_ENDC)
                        return

                    if check_item_was_removed and \
                            (not user_name_view.exists()
                             or username != user_name_view.get_text()):
                        raise StopIteration("item was removed")

            except IndexError:
                print(
                    COLOR_FAIL +
                    "Cannot get next item: probably reached end of the screen."
                    + COLOR_ENDC)

            if is_myself and scrolled_to_top():
                print(COLOR_OKGREEN + "Scrolled to top, finish." + COLOR_ENDC)
                return
            elif len(screen_iterated_followers) > 0:
                load_more_button = device.find(
                    resourceId=f'{device.app_id}:id/row_load_more_button')
                load_more_button_exists = load_more_button.exists(quick=True)

                if scroll_end_detector.is_the_end():
                    return

                need_swipe = screen_skipped_followers_count == len(
                    screen_iterated_followers)
                list_view = device.find(resourceId='android:id/list',
                                        className='android.widget.ListView')
                if not list_view.exists():
                    print(
                        COLOR_FAIL +
                        "Cannot find the list of followers. Trying to press back again."
                        + COLOR_ENDC)
                    device.back()
                    list_view = device.find(
                        resourceId='android:id/list',
                        className='android.widget.ListView')

                if is_myself:
                    print(COLOR_OKGREEN + "Need to scroll now" + COLOR_ENDC)
                    list_view.scroll(DeviceFacade.Direction.TOP)
                else:
                    pressed_retry = False
                    if load_more_button_exists:
                        retry_button = load_more_button.child(
                            className='android.widget.ImageView')
                        if retry_button.exists():
                            print("Press \"Load\" button")
                            retry_button.click()
                            sleeper.random_sleep()
                            pressed_retry = True

                    if need_swipe and not pressed_retry:
                        print(COLOR_OKGREEN +
                              "All followers skipped, let's do a swipe" +
                              COLOR_ENDC)
                        list_view.swipe(DeviceFacade.Direction.BOTTOM)
                    else:
                        print(COLOR_OKGREEN + "Need to scroll now" +
                              COLOR_ENDC)
                        list_view.scroll(DeviceFacade.Direction.BOTTOM)

                prev_screen_iterated_followers.clear()
                prev_screen_iterated_followers += screen_iterated_followers
            else:
                print(COLOR_OKGREEN + "No followers were iterated, finish." +
                      COLOR_ENDC)
                return
        except StopIteration as e:
            print(COLOR_OKGREEN +
                  f"Starting the screen from the beginning because {e}" +
                  COLOR_ENDC)
Esempio n. 3
0
def _iterate_over_followers(device, interaction, is_follow_limit_reached, storage, on_interaction, is_myself):
    # Wait until list is rendered
    device.find(resourceId='com.instagram.android:id/follow_list_container',
                className='android.widget.LinearLayout').wait()

    def scrolled_to_top():
        row_search = device.find(resourceId='com.instagram.android:id/row_search_edit_text',
                                 className='android.widget.EditText')
        return row_search.exists()

    scroll_end_detector = ScrollEndDetector()
    while True:
        print("Iterate over visible followers")
        random_sleep()
        screen_iterated_followers = []
        screen_skipped_followers_count = 0
        scroll_end_detector.notify_new_page()

        try:
            for item in device.find(resourceId='com.instagram.android:id/follow_list_container',
                                    className='android.widget.LinearLayout'):
                user_info_view = item.child(index=1)
                user_name_view = user_info_view.child(index=0).child()
                if not user_name_view.exists(quick=True):
                    print(COLOR_OKGREEN + "Next item not found: probably reached end of the screen." + COLOR_ENDC)
                    break

                username = user_name_view.get_text()
                screen_iterated_followers.append(username)
                scroll_end_detector.notify_username_iterated(username)

                if storage.is_user_in_blacklist(username):
                    print("@" + username + " is in blacklist. Skip.")
                elif is_myself and storage.check_user_was_interacted(username):
                    print("@" + username + ": already interacted. Skip.")
                    screen_skipped_followers_count += 1
                elif is_myself and storage.check_user_was_interacted_recently(username):
                    print("@" + username + ": already interacted in the last week. Skip.")
                    screen_skipped_followers_count += 1
                else:
                    print("@" + username + ": interact")
                    user_name_view.click()

                    can_follow = not is_myself \
                        and not is_follow_limit_reached() \
                        and storage.get_following_status(username) == FollowingStatus.NONE

                    interaction_succeed, followed = interaction(device, username=username, can_follow=can_follow)
                    storage.add_interacted_user(username, followed=followed)
                    can_continue = on_interaction(succeed=interaction_succeed,
                                                  followed=followed)

                    if not can_continue:
                        return

                    print("Back to followers list")
                    device.back()
        except IndexError:
            print(COLOR_FAIL + "Cannot get next item: probably reached end of the screen." + COLOR_ENDC)

        if is_myself and scrolled_to_top():
            print(COLOR_OKGREEN + "Scrolled to top, finish." + COLOR_ENDC)
            return
        elif len(screen_iterated_followers) > 0:
            load_more_button = device.find(resourceId='com.instagram.android:id/row_load_more_button')
            load_more_button_exists = load_more_button.exists(quick=True)

            if scroll_end_detector.is_the_end():
                return

            need_swipe = screen_skipped_followers_count == len(screen_iterated_followers)
            list_view = device.find(resourceId='android:id/list',
                                    className='android.widget.ListView')
            if not list_view.exists():
                print(COLOR_FAIL + "Cannot find the list of followers. Trying to press back again." + COLOR_ENDC)
                device.back()
                list_view = device.find(resourceId='android:id/list',
                                        className='android.widget.ListView')

            if is_myself:
                print(COLOR_OKGREEN + "Need to scroll now" + COLOR_ENDC)
                list_view.scroll(DeviceFacade.Direction.TOP)
            else:
                pressed_retry = False
                if load_more_button_exists:
                    retry_button = load_more_button.child(className='android.widget.ImageView')
                    if retry_button.exists():
                        print("Press \"Load\" button")
                        retry_button.click()
                        random_sleep()
                        pressed_retry = True

                if need_swipe and not pressed_retry:
                    print(COLOR_OKGREEN + "All followers skipped, let's do a swipe" + COLOR_ENDC)
                    list_view.swipe(DeviceFacade.Direction.BOTTOM)
                else:
                    print(COLOR_OKGREEN + "Need to scroll now" + COLOR_ENDC)
                    list_view.scroll(DeviceFacade.Direction.BOTTOM)
        else:
            print(COLOR_OKGREEN + "No followers were iterated, finish." + COLOR_ENDC)
            return