def extract_hashtag_profiles_and_interact(device, hashtag, instructions,
                                          iteration_callback,
                                          iteration_callback_pre_conditions,
                                          on_action):
    print("Interacting with #{0}-{1}".format(hashtag, instructions.value))

    if not search_for(device, hashtag=hashtag, on_action=on_action):
        return

    # Switch to Recent tab
    if instructions == HashtagInteractionType.RECENT_LIKERS:
        print("Switching to Recent tab")
        tab_layout = device.find(
            resourceId='com.instagram.android:id/tab_layout',
            className='android.widget.LinearLayout')
        if tab_layout.exists():
            tab_layout.child(index=1).click()
        else:
            print("Can't Find recent tab. Interacting with Popular.")

        sleeper.random_sleep()

    # Open first post
    print("Opening the first post")
    # Index 1 is reserved for hot Reels by this tag
    first_post_index = 2 if instructions == HashtagInteractionType.TOP_LIKERS else 1
    first_post_view = device.find(
        resourceId='com.instagram.android:id/image_button',
        className='android.widget.ImageView',
        index=first_post_index)
    first_post_view.click()
    sleeper.random_sleep()

    posts_list_view = device.find(
        resourceId='android:id/list',
        className='androidx.recyclerview.widget.RecyclerView')
    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username,
                                                 liker_username_view)

    while True:
        if not open_likers(device):
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
            continue

        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        sleeper.random_sleep()

        iterate_over_likers(device, iteration_callback, pre_conditions)

        if posts_end_detector.is_the_end():
            break
        else:
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
Exemplo n.º 2
0
def extract_hashtag_profiles_and_interact(device,
                                          hashtag,
                                          instructions,
                                          iteration_callback,
                                          iteration_callback_pre_conditions,
                                          on_action):
    print("Interacting with #{0}-{1}".format(hashtag, instructions.value))

    if not search_for(device, hashtag=hashtag, on_action=on_action):
        return

    # Switch to Recent tab
    if instructions == HashtagInteractionType.RECENT_LIKERS:
        print("Switching to Recent tab")
        tab_layout = device.find(resourceId=f'{device.app_id}:id/tab_layout',
                                 className='android.widget.LinearLayout')
        if tab_layout.exists():
            tab_layout.child(index=1).click()
        else:
            print("Can't Find recent tab. Interacting with Popular.")

    # Sleep longer because posts loading takes time
    sleeper.random_sleep(multiplier=2.0)

    # Open post
    posts_view_list = PostsGridView(device).open_random_post()
    if posts_view_list is None:
        return

    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username, liker_username_view)

    while True:
        if not open_likers(device):
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_view_list.scroll_down()
            continue

        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        sleeper.random_sleep()

        should_continue_using_source = iterate_over_likers(device, iteration_callback, pre_conditions)

        if not should_continue_using_source:
            break

        if posts_end_detector.is_the_end():
            break
        else:
            posts_view_list.scroll_down()
Exemplo n.º 3
0
def extract_hashtag_likers_and_interact(device, hashtag, iteration_callback,
                                        iteration_callback_pre_conditions,
                                        on_action):
    print("Interacting with #{0} recent-likers".format(hashtag))

    if not search_for(device, hashtag=hashtag, on_action=on_action):
        return

    # Switch to Recent tab
    print("Switching to Recent tab")
    tab_layout = device.find(resourceId='com.instagram.android:id/tab_layout',
                             className='android.widget.LinearLayout')
    tab_layout.child(index=1).click()
    random_sleep()

    # Open first post
    print("Opening the first post")
    first_post_view = device.find(
        resourceId='com.instagram.android:id/image_button',
        className='android.widget.ImageView',
        index=1)
    first_post_view.click()
    random_sleep()

    posts_list_view = device.find(
        resourceId='android:id/list',
        className='androidx.recyclerview.widget.RecyclerView')
    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username,
                                                 liker_username_view)

    while True:
        if not open_likers(device):
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
            continue

        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        random_sleep()

        iterate_over_likers(device, iteration_callback, pre_conditions)

        if posts_end_detector.is_the_end():
            break
        else:
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
Exemplo n.º 4
0
def extract_place_likers_and_interact(device, place, instructions,
                                      navigate_to_feed, iteration_callback,
                                      iteration_callback_pre_conditions,
                                      on_action):
    print("Interacting with place-{0}-{1}".format(place, instructions.value))

    # Open post
    posts_view_list = navigate_to_feed()
    if posts_view_list is None:
        return

    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username,
                                                 liker_username_view)

    no_likes_count = 0

    while True:
        if not open_likers(device):
            no_likes_count += 1
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_view_list.scroll_down()
            if no_likes_count == 10:
                print(
                    COLOR_FAIL +
                    "Seen this message too many times. Lets restart the job." +
                    COLOR_ENDC)
                raise RestartJobRequiredException

            continue

        no_likes_count = 0
        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        sleeper.random_sleep()

        should_continue_using_source = iterate_over_likers(
            device, iteration_callback, pre_conditions)

        if not should_continue_using_source:
            break

        if posts_end_detector.is_the_end():
            break
        else:
            posts_view_list.scroll_down()
Exemplo n.º 5
0
def extract_hashtag_profiles_and_interact(device, hashtag, instructions,
                                          iteration_callback,
                                          iteration_callback_pre_conditions,
                                          on_action):
    print("Interacting with #{0}-{1}".format(hashtag, instructions.value))

    if not search_for(device, hashtag=hashtag, on_action=on_action):
        return

    # Switch to Recent tab
    if instructions == HashtagInteractionType.RECENT_LIKERS:
        print("Switching to Recent tab")
        tab_layout = device.find(resourceId=f'{device.app_id}:id/tab_layout',
                                 className='android.widget.LinearLayout')
        if tab_layout.exists():
            tab_layout.child(index=1).click()
        else:
            print("Can't Find recent tab. Interacting with Popular.")

        sleeper.random_sleep()

    # Open post
    # Scroll down several times to pick random post
    scroll_times = randint(0, 5)
    posts_grid = device.find(
        resourceId=f'{device.app_id}:id/recycler_view',
        className='androidx.recyclerview.widget.RecyclerView')
    print(f"Scroll down {scroll_times} times.")
    for _ in range(0, scroll_times):
        posts_grid.scroll(DeviceFacade.Direction.BOTTOM)
        sleeper.random_sleep()

    # Scan for available posts' coordinates
    available_posts_coords = []
    print("Choosing a random post from those on the screen")
    for post_view in posts_grid.child(
            resourceId=f'{device.app_id}:id/image_button',
            className='android.widget.ImageView'):
        bounds = post_view.get_bounds()
        left = bounds["left"]
        top = bounds["top"]
        right = bounds["right"]
        bottom = bounds["bottom"]
        coords = (left + (right - left) / 2, top + (bottom - top) / 2)
        available_posts_coords.append(coords)
    if len(available_posts_coords) == 0:
        print(COLOR_FAIL + f"No posts for #{hashtag}. Abort." + COLOR_ENDC)
        return

    # Pick random post from available ones
    coords = random.choice(available_posts_coords)
    print(f"Open the post at {coords}")
    device.screen_click_by_coordinates(coords[0], coords[1])
    sleeper.random_sleep()
    posts_list_view = device.find(
        resourceId='android:id/list',
        className='androidx.recyclerview.widget.RecyclerView')
    if not posts_list_view.exists():
        print("Couldn't open a post, will try again.")
        device.screen_click_by_coordinates(coords[0], coords[1])
        sleeper.random_sleep()

    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username,
                                                 liker_username_view)

    while True:
        if not open_likers(device):
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
            continue

        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        sleeper.random_sleep()

        should_continue_using_source = iterate_over_likers(
            device, iteration_callback, pre_conditions)

        if not should_continue_using_source:
            break

        if posts_end_detector.is_the_end():
            break
        else:
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
Exemplo n.º 6
0
def extract_place_profiles_and_interact(device, place, instructions,
                                        iteration_callback,
                                        iteration_callback_pre_conditions,
                                        on_action):
    print("Interacting with place-{0}-{1}".format(place, instructions.value))

    if not search_for(device, place=place, on_action=on_action):
        return

    # Switch to Recent tab
    if instructions == PlaceInteractionType.RECENT_LIKERS:
        print("Switching to Recent tab")
        tab_layout = device.find(resourceId=f'{device.app_id}:id/tab_layout',
                                 className='android.widget.LinearLayout')
        if tab_layout.exists():
            tab_layout.child(index=1).click()
        else:
            print("Can't Find recent tab. Interacting with Popular.")

        sleeper.random_sleep()

    # Open post
    first_post_index = 2
    post_num = randint(first_post_index, 20)
    print(f"Opening post #{post_num}")
    post_view = device.find(resourceId=f'{device.app_id}:id/image_button',
                            className='android.widget.ImageView',
                            index=post_num)

    for _ in range(0, 10):
        if post_view.exists(quick=True):
            break

        print(f"Cannot find post #{post_num}. Swiping down a bit.")
        device.swipe(DeviceFacade.Direction.TOP)

    if not post_view.exists(quick=True):
        print(f"Cannot find post #{post_num} after 10 swipes. Aborting.")

    post_view.click()
    sleeper.random_sleep()

    posts_list_view = device.find(
        resourceId='android:id/list',
        className='androidx.recyclerview.widget.RecyclerView')
    posts_end_detector = ScrollEndDetector(repeats_to_end=2)

    def pre_conditions(liker_username, liker_username_view):
        posts_end_detector.notify_username_iterated(liker_username)
        return iteration_callback_pre_conditions(liker_username,
                                                 liker_username_view)

    while True:
        if not open_likers(device):
            print(COLOR_OKGREEN + "No likes, let's scroll down." + COLOR_ENDC)
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)
            continue

        print("List of likers is opened.")
        posts_end_detector.notify_new_page()
        sleeper.random_sleep()

        should_continue_using_source = iterate_over_likers(
            device, iteration_callback, pre_conditions)

        if not should_continue_using_source:
            break

        if posts_end_detector.is_the_end():
            break
        else:
            posts_list_view.scroll(DeviceFacade.Direction.BOTTOM)