예제 #1
0
    def sort_followings_by_date(self, device):
        logger.info("Sort followings by date: from oldest to newest.")
        UniversalActions(device)._swipe_points(direction=Direction.DOWN, )

        sort_button = device.find(
            resourceId=self.ResourceID.SORTING_ENTRY_ROW_ICON,
            className=ClassName.IMAGE_VIEW,
        )
        if not sort_button.exists():
            logger.error(
                "Cannot find button to sort followings. Continue without sorting."
            )
            return
        sort_button.click()
        random_sleep()

        sort_options_recycler_view = device.find(
            resourceId=self.ResourceID.
            FOLLOW_LIST_SORTING_OPTIONS_RECYCLER_VIEW)
        if not sort_options_recycler_view.exists():
            logger.error(
                "Cannot find options to sort followings. Continue without sorting."
            )
            return

        sort_options_recycler_view.child(index=2).click()
예제 #2
0
파일: views.py 프로젝트: ufo2011/bot
 def getProfileBiography(self):
     biography = self.device.find(
         resourceIdMatches=case_insensitive_re(
             ResourceID.PROFILE_HEADER_BIO_TEXT),
         className=ClassName.TEXT_VIEW,
     )
     if biography.exists():
         biography_text = biography.get_text()
         # If the biography is very long, blabla text and end with "...more" click the bottom of the text and get the new text
         is_long_bio = re.compile(
             r"{0}$".format("… more"),
             flags=re.IGNORECASE).search(biography_text)
         if is_long_bio is not None:
             logger.debug('Found "… more" in bio - trying to expand')
             username = self.getUsername()
             for _ in range(2):
                 # Clicking the biography is dangerous. Clicking "bottomright" is safest so we can try to avoid hashtags and tags
                 biography.click(biography.Location.BOTTOMRIGHT)
                 random_sleep()
                 if username == self.getUsername():
                     return biography.get_text()
                 logger.debug(
                     "We're not in the same page - did we click a hashtag or a tag? Go back."
                 )
                 self.device.back()
             logger.info(
                 "Failed to expand biography - checking short view.")
             return biography.get_text()
         return biography_text
     return ""
예제 #3
0
파일: views.py 프로젝트: timurguseynov/bot
    def likePost(self, click_btn_like=False):
        MEDIA_GROUP_RE = case_insensitive_re([
            "com.instagram.android:id/media_group",
            "com.instagram.android:id/carousel_media_group",
        ])
        post_media_view = self.device.find(
            resourceIdMatches=MEDIA_GROUP_RE,
            className="android.widget.FrameLayout")

        if click_btn_like:
            like_btn_view = self._getPostLikeButton()
            if not like_btn_view:
                return False
            like_btn_view.click()
        else:

            if post_media_view.exists():
                post_media_view.double_click()
            else:
                logger.error("Could not find post area to double click")
                return False

        random_sleep()

        return self._isPostLiked()
예제 #4
0
    def navigateToHashtag(self, hashtag):
        logger.info(f"Navigate to hashtag {hashtag}")
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()

        random_sleep()
        hashtag_tab = self._getTabTextView(SearchTabs.TAGS)
        if not hashtag_tab.exists():
            logger.debug(
                "Cannot find tab: Tags. Going to attempt to search for placeholder in all tabs"
            )
            hashtag_tab = self._searchTabWithTextPlaceholder(SearchTabs.TAGS)
            if hashtag_tab is None:
                logger.error("Cannot find tab: Tags.")
                save_crash(self.device)
                return None
        hashtag_tab.click()

        search_edit_text.set_text(hashtag)
        hashtag_view = self._getHashtagRow(hashtag[1:])

        if not hashtag_view.exists():
            logger.error(f"Cannot find hashtag {hashtag}, abort.")
            save_crash(self.device)
            return None

        hashtag_view.click()

        return HashTagView(self.device)
예제 #5
0
파일: views.py 프로젝트: rxu202/bot
 def changeToUsername(self, username):
     action_bar = self.device.find(
         resourceId=ResourceID.ACTION_BAR_LARGE_TITLE)
     current_profile_name = action_bar.get_text().upper()
     if current_profile_name == username.upper():
         logger.info(
             f"You are already logged as {username}!",
             extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
         )
         return True
     if action_bar.exists():
         action_bar.click()
         random_sleep()
         found_obj = self.device.find(
             resourceId=ResourceID.ROW_USER_TEXTVIEW,
             textMatches=case_insensitive_re(username),
         )
         if found_obj.exists():
             logger.info(
                 f"Switching to {configs.args.username}...",
                 extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
             )
             found_obj.click()
             random_sleep()
             action_bar = self.device.find(
                 resourceId=ResourceID.ACTION_BAR_LARGE_TITLE)
             current_profile_name = action_bar.get_text().upper()
             if current_profile_name == username.upper():
                 return True
     return False
예제 #6
0
 def process_file(self, current_file, on_like, storage):
     # TODO: We need to add interactions properly, honor session/source limits, honor filter,
     # etc. Not going to try to do this now, but adding a note to do it later
     if path.isfile(current_file):
         with open(current_file, "r") as f:
             for line in f:
                 url = line.strip()
                 if validate_url(url) and "instagram.com/p/" in url:
                     if open_instagram_with_url(url) is True:
                         opened_post_view = OpenedPostView(self.device)
                         username = opened_post_view._getUserName
                         like_succeed = do_like(opened_post_view,
                                                self.device, on_like)
                         logger.info("Like for: {}, status: {}".format(
                             url, like_succeed))
                         if like_succeed:
                             logger.info("Back to profile")
                             storage.add_interacted_user(username)
                             self.device.back()
                             random_sleep()
                 else:
                     logger.info("Line in file is blank, skip.")
             remaining = f.readlines()
         if self.args.delete_interacted_users:
             with open(current_file, "w") as f:
                 f.writelines(remaining)
     else:
         logger.warning(f"File {current_file} not found.")
         return
예제 #7
0
파일: views.py 프로젝트: ufo2011/bot
 def changeToUsername(self, username):
     action_bar = self.device.find(
         resourceId=ResourceID.ACTION_BAR_LARGE_TITLE)
     current_profile_name = action_bar.get_text().upper()
     # in private accounts there is little lock which is codec as two spaces (should be \u1F512)
     if current_profile_name == username.upper(
     ) or current_profile_name == ("  " + username.upper()):
         logger.info(
             f"You are already logged as {username}!",
             extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
         )
         return True
     if action_bar.exists():
         action_bar.click()
         random_sleep()
         found_obj = self.device.find(
             resourceId=ResourceID.ROW_USER_TEXTVIEW,
             textMatches=case_insensitive_re(username),
         )
         if found_obj.exists():
             logger.info(
                 f"Switching to {username}...",
                 extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
             )
             found_obj.click()
             random_sleep()
             action_bar = self.device.find(
                 resourceId=ResourceID.ACTION_BAR_LARGE_TITLE)
             current_profile_name = action_bar.get_text().upper()
             if current_profile_name == username.upper():
                 return True
     return False
예제 #8
0
 def wrapper(*args, **kwargs):
     session_state = sessions[-1]
     try:
         func(*args, **kwargs)
     except KeyboardInterrupt:
         close_instagram(device_id)
         logger.info(
             f"-------- FINISH: {datetime.now().time()} --------",
             extra={"color": f"{Style.BRIGHT}{Fore.YELLOW}"},
         )
         print_full_report(sessions)
         sessions.persist(directory=session_state.my_username)
         sys.exit(0)
     except (DeviceFacade.JsonRpcError, IndexError, HTTPException,
             timeout):
         logger.error(traceback.format_exc())
         save_crash(device)
         logger.info("No idea what it was. Let's try again.")
         # Hack for the case when IGTV was accidentally opened
         close_instagram(device_id)
         random_sleep()
         open_instagram(device_id)
         TabBarView(device).navigateToProfile()
     except LanguageNotEnglishException:
         logger.info(
             "Language was changed. We'll have to start from the beginning."
         )
         TabBarView(device).navigateToProfile()
     except Exception as e:
         save_crash(device)
         close_instagram(device_id)
         print_full_report(sessions)
         sessions.persist(directory=session_state.my_username)
         raise e
예제 #9
0
파일: interaction.py 프로젝트: ufo2011/bot
def _follow(device, username, follow_percentage, args, session_state,
            swipe_amount):
    if not session_state.check_limit(
            args, limit_type=session_state.Limit.FOLLOWS, output=False):
        follow_chance = randint(1, 100)
        if follow_chance > follow_percentage:
            return False

        coordinator_layout = device.find(
            resourceId=ResourceID.COORDINATOR_ROOT_LAYOUT)
        if coordinator_layout.exists() and swipe_amount != 0:
            UniversalActions(device)._swipe_points(direction=Direction.UP,
                                                   delta_y=swipe_amount)

        random_sleep()

        follow_button = device.find(
            classNameMatches=ClassName.BUTTON,
            clickable=True,
            textMatches=FOLLOW_REGEX,
        )

        if not follow_button.exists():
            unfollow_button = device.find(
                classNameMatches=ClassName.BUTTON,
                clickable=True,
                textMatches=UNFOLLOW_REGEX,
            )
            followback_button = device.find(
                classNameMatches=ClassName.BUTTON,
                clickable=True,
                textMatches=FOLLOWBACK_REGEX,
            )
            if unfollow_button.exists():
                logger.info(f"You already follow @{username}.",
                            extra={"color": f"{Fore.GREEN}"})
                return False
            elif followback_button.exists():
                logger.info(
                    f"@{username} already follows you.",
                    extra={"color": f"{Fore.GREEN}"},
                )
                return False
            else:
                logger.error(
                    "Cannot find neither Follow button, Follow Back button, nor Unfollow button. Maybe not English language is set?"
                )
                save_crash(device)
                switch_to_english(device)
                raise LanguageNotEnglishException()

        follow_button.click()
        detect_block(device)
        logger.info(f"Followed @{username}", extra={"color": f"{Fore.GREEN}"})
        random_sleep()
        return True
    else:
        logger.info("Reached total follows limit, not following.")
        return False
예제 #10
0
 def unfollow(self, device, count, on_unfollow, storage,
              unfollow_restriction, my_username):
     self.open_my_followings(device)
     random_sleep()
     self.sort_followings_by_date(device)
     random_sleep()
     self.iterate_over_followings(device, count, on_unfollow, storage,
                                  unfollow_restriction, my_username)
예제 #11
0
파일: views.py 프로젝트: ufo2011/bot
 def open_likers_container(self):
     likes_view = self.device.find(
         resourceId=ResourceID.ROW_FEED_TEXTVIEW_LIKES,
         className=ClassName.TEXT_VIEW,
     )
     logger.info("Opening post likers.")
     random_sleep()
     likes_view.click(likes_view.Location.RIGHT)
예제 #12
0
def _follow(device, username, follow_percentage, args, session_state):
    if not session_state.check_limit(
            args, limit_type=session_state.Limit.FOLLOWS, output=False):
        follow_chance = randint(1, 100)
        if follow_chance > follow_percentage:
            return False

        logger.info("Following...")
        coordinator_layout = device.find(
            resourceId="com.instagram.android:id/coordinator_root_layout")
        if coordinator_layout.exists():
            coordinator_layout.scroll(DeviceFacade.Direction.TOP)

        random_sleep()

        follow_button = device.find(
            classNameMatches=BUTTON_REGEX,
            clickable=True,
            textMatches=FOLLOW_REGEX,
        )

        if not follow_button.exists():
            unfollow_button = device.find(
                classNameMatches=BUTTON_REGEX,
                clickable=True,
                textMatches=UNFOLLOW_REGEX,
            )
            followback_button = device.find(
                classNameMatches=BUTTON_REGEX,
                clickable=True,
                textMatches=FOLLOWBACK_REGEX,
            )
            if unfollow_button.exists():
                logger.info(f"You already follow @{username}.",
                            extra={"color": f"{Fore.GREEN}"})
                return False
            elif followback_button.exists():
                logger.info(
                    f"@{username} already follows you.",
                    extra={"color": f"{Fore.GREEN}"},
                )
                return False
            else:
                logger.error(
                    "Cannot find neither Follow button, Follow Back button, nor Unfollow button. Maybe not English language is set?"
                )
                save_crash(device)
                switch_to_english(device)
                raise LanguageNotEnglishException()

        follow_button.click()
        detect_block(device)
        logger.info(f"Followed @{username}", extra={"color": f"{Fore.GREEN}"})
        random_sleep()
        return True
    else:
        logger.info("Reached total follows limit, not following.")
        return False
예제 #13
0
def _follow(device, username, follow_percentage):
    follow_chance = randint(1, 100)
    if follow_chance > follow_percentage:
        return False

    logger.info("Following...")
    coordinator_layout = device.find(
        resourceId="com.instagram.android:id/coordinator_root_layout")
    if coordinator_layout.exists():
        coordinator_layout.scroll(DeviceFacade.Direction.TOP)

    random_sleep()

    profile_header_actions_layout = device.find(
        resourceId="com.instagram.android:id/profile_header_actions_top_row",
        className="android.widget.LinearLayout",
    )
    if not profile_header_actions_layout.exists():
        logger.error("Cannot find profile actions.")
        return False

    follow_button = profile_header_actions_layout.child(
        classNameMatches=TEXTVIEW_OR_BUTTON_REGEX,
        clickable=True,
        textMatches=FOLLOW_REGEX,
    )
    if not follow_button.exists():
        unfollow_button = profile_header_actions_layout.child(
            classNameMatches=TEXTVIEW_OR_BUTTON_REGEX,
            clickable=True,
            textMatches=UNFOLLOW_REGEX,
        )
        if unfollow_button.exists():
            logger.info(
                f"You already follow @{username}.",
                extra={"color": f"{Fore.GREEN}"},
            )
            return False
        else:
            logger.error(
                "Cannot find neither Follow button, nor Unfollow button. Maybe not English language is set?"
            )
            save_crash(device)
            switch_to_english(device)
            raise LanguageNotEnglishException()

    follow_button.click()
    detect_block(device)
    logger.info(
        f"Followed @{username}",
        extra={"color": f"{Fore.GREEN}"},
    )
    random_sleep()
    return True
 def open_likers(self, device):
     likes_view = device.find(
         resourceId="com.instagram.android:id/row_feed_textview_likes",
         className="android.widget.TextView",
     )
     if likes_view.exists():
         logger.info("Opening post likers")
         random_sleep()
         likes_view.click("right")
         return True
     else:
         return False
예제 #15
0
파일: views.py 프로젝트: rxu202/bot
    def navigateToUsername(self,
                           username,
                           interact_usernames=False,
                           swipe_to_accounts=True):
        logger.debug("Search for @" + username)
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()
        random_sleep(1, 2)
        if swipe_to_accounts:
            logger.debug("Close the keyboard")
            DeviceFacade.back(self.device)
            random_sleep(1, 2)
            DeviceFacade.swipe(self.device, DeviceFacade.Direction.LEFT, 0.8)
            random_sleep(1, 2)
        if interact_usernames:
            search_edit_text.set_text(username)
        else:
            searched_user_recent = self._getUsernameRow(username)
            if searched_user_recent.exists(True):
                searched_user_recent.click()
                return ProfileView(self.device, is_own_profile=False)
            search_edit_text.set_text(username)
        logger.debug("Close the keyboard")
        DeviceFacade.back(self.device)
        random_sleep(1, 2)
        username_view = self._getUsernameRow(username)
        if not username_view.exists(True):
            logger.error("Cannot find user @" + username + ".")
            return None
        username_view.click()

        return ProfileView(self.device, is_own_profile=False)
예제 #16
0
        def job():
            for url in self.urls:
                url = url.strip().replace("\n", "")
                if validate_url(url) and "instagram.com/p/" in url:
                    if open_instagram_with_url(self.device_id, url) is True:
                        opened_post_view = OpenedPostView(device)
                        like_succeed = do_like(opened_post_view, device,
                                               on_like)
                        logger.info("Like for: {}, status: {}".format(
                            url, like_succeed))

                        if like_succeed:
                            logger.info("Back to profile")
                            device.back()
                            random_sleep()
    def open_user_followers(self, device, username):
        if username is None:
            logger.info("Open your followers")
            profile_view = TabBarView(device).navigateToProfile()
            profile_view.navigateToFollowers()
        else:
            search_view = TabBarView(device).navigateToSearch()
            profile_view = search_view.navigateToUsername(username)
            random_sleep()
            if not profile_view:
                return False

            logger.info(f"Open @{username} followers")
            profile_view.navigateToFollowers()

        return True
예제 #18
0
파일: views.py 프로젝트: timurguseynov/bot
 def open_likers(self):
     while True:
         likes_view = self.device.find(
             resourceId="com.instagram.android:id/row_feed_textview_likes",
             className="android.widget.TextView",
         )
         if likes_view.exists(True):
             if likes_view.get_text()[-6:].upper() == "OTHERS":
                 logger.info("Opening post likers")
                 random_sleep()
                 likes_view.click(likes_view.Location.RIGHT)
                 return True
             else:
                 logger.info("This post has only 1 liker, skip")
                 return False
         else:
             return False
    def check_is_follower(self, device, username, my_username):
        logger.info(f"Check if @{username} is following you.",
                    extra={"color": f"{Fore.GREEN}"})
        following_container = device.find(
            resourceIdMatches=FOLLOWING_BUTTON_ID_REGEX)
        following_container.click()

        random_sleep()

        my_username_view = device.find(
            resourceId="com.instagram.android:id/follow_list_username",
            className="android.widget.TextView",
            text=my_username,
        )
        result = my_username_view.exists()
        logger.info("Back to the profile.")
        device.back()
        return result
예제 #20
0
파일: views.py 프로젝트: timurguseynov/bot
    def navigateToHashtag(self, hashtag):
        logger.info(f"Navigate to hashtag {hashtag}")
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()

        random_sleep()
        hashtag_tab = self._getTabTextView(SearchTabs.TAGS)
        if not hashtag_tab.exists():
            logger.debug(
                "Cannot find tab: Tags. Going to attempt to search for placeholder in all tabs"
            )
            hashtag_tab = self._searchTabWithTextPlaceholder(SearchTabs.TAGS)
            if hashtag_tab is None:
                logger.error("Cannot find tab: Tags.")
                save_crash(self.device)
                return None

        hashtag_tab.click()
        random_sleep()
        DeviceFacade.back(self.device)
        random_sleep()
        # check if that hashtag already exists in the recent search list -> act as human
        hashtag_view_recent = self._getHashtagRow(hashtag[1:])

        if hashtag_view_recent.exists():
            hashtag_view_recent.click()
            random_sleep()
            return HashTagView(self.device)

        logger.info(f"{hashtag} is not in recent searching hystory..")
        search_edit_text.set_text(hashtag)
        hashtag_view = self._getHashtagRow(hashtag[1:])

        if not hashtag_view.exists():
            logger.error(f"Cannot find hashtag {hashtag}, abort.")
            save_crash(self.device)
            return None

        hashtag_view.click()
        random_sleep()

        return HashTagView(self.device)
예제 #21
0
 def open_likers(self, device):
     attempts = 0
     while True:
         likes_view = device.find(
             resourceId="com.instagram.android:id/row_feed_textview_likes",
             className="android.widget.TextView",
         )
         if likes_view.exists():
             logger.info("Opening post likers")
             random_sleep()
             likes_view.click("right")
             return True
         else:
             if attempts < 1:
                 attempts += 1
                 logger.info("Can't find likers, trying small swipe")
                 device.swipe(DeviceFacade.Direction.TOP, scale=0.1)
                 continue
             else:
                 return False
예제 #22
0
    def check_is_follower(self, device, username, my_username):
        random_sleep()
        logger.info(f"Check if @{username} is following you.",
                    extra={"color": f"{Fore.GREEN}"})
        following_container = device.find(
            resourceIdMatches=self.ResourceID.
            ROW_PROFILE_HEADER_FOLLOWING_CONTAINER)
        following_container.click()

        random_sleep(4, 6)

        my_username_view = device.find(
            resourceId=self.ResourceID.FOLLOW_LIST_USERNAME,
            className=ClassName.TEXT_VIEW,
            text=my_username,
        )
        result = my_username_view.exists()
        logger.info("Back to the profile.")
        device.back()
        return result
예제 #23
0
파일: views.py 프로젝트: ufo2011/bot
    def likePost(self, click_btn_like=False):
        post_media_view = self.device.find(
            resourceIdMatches=case_insensitive_re(
                ResourceID.CAROUSEL_MEDIA_GROUP_AND_ZOOMABLE_VIEW_CONTAINER))

        if click_btn_like:
            like_btn_view = self._getPostLikeButton()
            if not like_btn_view:
                return False
            like_btn_view.click()
        else:
            if post_media_view.exists(True):
                post_media_view.double_click()
            else:
                logger.error("Could not find post area to double click")
                return False

        random_sleep()

        return self._isPostLiked()
예제 #24
0
파일: views.py 프로젝트: ufo2011/bot
 def _open_likers(self):
     while True:
         likes_view = self.device.find(
             resourceId=ResourceID.ROW_FEED_TEXTVIEW_LIKES,
             className=ClassName.TEXT_VIEW,
         )
         if likes_view.exists(True):
             likes_view_text = likes_view.get_text()
             if (likes_view_text[-6:].upper() == "OTHERS"
                     or likes_view_text.upper()[-5:] == "LIKES"):
                 logger.info("Opening post likers")
                 random_sleep()
                 PostsViewList(
                     self.device)._if_action_bar_is_over_obj_swipe(
                         likes_view)
                 likes_view.click(likes_view.Location.RIGHT)
                 return True
             else:
                 logger.info("This post has only 1 liker, skip")
                 return False
         else:
             return False
예제 #25
0
파일: views.py 프로젝트: thup/bot
    def _navigateTo(self, tab: TabBarTabs):
        tab_name = tab.name
        logger.debug(f"Navigate to {tab_name}")
        button = None
        if tab == TabBarTabs.HOME:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(TabBarText.HOME_CONTENT_DESC),
            )
        elif tab == TabBarTabs.SEARCH:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(TabBarText.SEARCH_CONTENT_DESC),
            )
            if not button.exists():
                # Some accounts display the search btn only in Home -> action bar
                logger.debug("Didn't find search in the tab bar...")
                home_view = self.navigateToHome()
                home_view.navigateToSearch()
                return
        elif tab == TabBarTabs.REELS:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(TabBarText.REELS_CONTENT_DESC),
            )
        elif tab == TabBarTabs.ORDERS:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(TabBarText.ORDERS_CONTENT_DESC),
            )
        elif tab == TabBarTabs.ACTIVITY:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(
                    TabBarText.ACTIVITY_CONTENT_DESC
                ),
            )
        elif tab == TabBarTabs.PROFILE:
            button = self.device.find(
                className=ClassName.BUTTON,
                descriptionMatches=case_insensitive_re(TabBarText.PROFILE_CONTENT_DESC),
            )

        if button.exists():
            # Two clicks to reset tab content
            random_sleep(1, 2)
            button.click()
            random_sleep(1, 2)
            if tab is not TabBarTabs.PROFILE:
                button.click()
                random_sleep(1, 2)

            return

        logger.error(
            f"Didn't find tab {tab_name} in the tab bar... Maybe English language is not set!?"
        )

        raise LanguageNotEnglishException()
예제 #26
0
    def navigateToHashtag(self, hashtag):
        logger.debug(f"Navigate to hashtag #{hashtag}")
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()

        random_sleep()
        hashtag_tab = self._getTabTextView(SearchTabs.TAGS)
        if not hashtag_tab.exists():
            hashtag_tab = self._getTabTextView(SearchTabs.Tags)
        if not hashtag_tab.exists():
            logger.error("Cannot find tab: TAGS.")
            return None
        hashtag_tab.click()

        search_edit_text.set_text(hashtag)
        hashtag_view = self._getHashtagRow(hashtag)

        if not hashtag_view.exists():
            logger.error(f"Cannot find hashtag #{hashtag} , abort.")
            return None

        hashtag_view.click()

        return HashTagView(self.device)
    def close_confirm_dialog_if_shown(self, device):
        dialog_root_view = device.find(
            resourceId="com.instagram.android:id/dialog_root_view",
            className="android.widget.FrameLayout",
        )
        if not dialog_root_view.exists():
            return

        # Avatar existence is the way to distinguish confirm dialog from block dialog
        user_avatar_view = device.find(
            resourceId="com.instagram.android:id/circular_image",
            className="android.widget.ImageView",
        )
        if not user_avatar_view.exists():
            return

        logger.info("Dialog shown, confirm unfollowing.",
                    extra={"color": f"{Fore.GREEN}"})
        random_sleep()
        unfollow_button = dialog_root_view.child(
            resourceId="com.instagram.android:id/primary_button",
            className="android.widget.TextView",
        )
        unfollow_button.click()
예제 #28
0
파일: views.py 프로젝트: ufo2011/bot
    def navigateToUsername(self,
                           username,
                           interact_usernames=False,
                           swipe_to_accounts=True):
        logger.debug("Search for @" + username)
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()
        random_sleep(1, 2)
        tabbar_container = self.device.find(
            resourceId=ResourceID.FIXED_TABBAR_TABS_CONTAINER)
        if tabbar_container.exists(True):
            delta = tabbar_container.get_bounds()["bottom"]
        else:
            delta = 375
        if swipe_to_accounts:
            logger.debug("Swipe up to close the keyboard if present")
            UniversalActions(self.device)._swipe_points(
                direction=Direction.UP,
                start_point_y=randint(delta + 10, delta + 150),
                delta_y=randint(50, 100),
            )
            random_sleep(1, 2)
            DeviceFacade.swipe(self.device, DeviceFacade.Direction.LEFT, 0.8)
            random_sleep(1, 2)
        if interact_usernames:
            search_edit_text.set_text(username)
        else:
            searched_user_recent = self._getUsernameRow(username)
            if searched_user_recent.exists(True):
                searched_user_recent.click()
                return ProfileView(self.device, is_own_profile=False)
            search_edit_text.set_text(username)
        logger.debug("Swipe up to close the keyboard if present")
        UniversalActions(self.device)._swipe_points(
            direction=Direction.UP,
            start_point_y=randint(delta + 10, delta + 150),
            delta_y=randint(50, 100),
        )
        random_sleep(1, 2)
        username_view = self._getUsernameRow(username)
        if not username_view.exists(True):
            logger.error("Cannot find user @" + username + ".")
            return None
        username_view.click()

        return ProfileView(self.device, is_own_profile=False)
예제 #29
0
파일: views.py 프로젝트: ufo2011/bot
    def navigateToHashtag(self, hashtag):
        logger.info(f"Navigate to hashtag {hashtag}")
        search_edit_text = self._getSearchEditText()
        search_edit_text.click()
        random_sleep(1, 2)
        hashtag_tab = self._getTabTextView(SearchTabs.TAGS)
        if not hashtag_tab.exists():
            logger.debug(
                "Cannot find tab: Tags. Going to attempt to search for placeholder in all tabs"
            )
            hashtag_tab = self._searchTabWithTextPlaceholder(SearchTabs.TAGS)
            if hashtag_tab is None:
                logger.error("Cannot find tab: Tags.")
                save_crash(self.device)
                return None
        hashtag_tab.click()
        random_sleep(1, 2)
        tabbar_container = self.device.find(
            resourceId=ResourceID.FIXED_TABBAR_TABS_CONTAINER)
        if tabbar_container.exists(True):
            delta = tabbar_container.get_bounds()["bottom"]
        else:
            delta = 375
        logger.debug("Swipe up to close the keyboard if present")
        UniversalActions(self.device)._swipe_points(
            direction=Direction.UP,
            start_point_y=randint(delta + 10, delta + 150),
            delta_y=randint(50, 100),
        )
        random_sleep(1, 2)
        # check if that hashtag already exists in the recent search list -> act as human
        hashtag_view_recent = self._getHashtagRow(hashtag[1:])

        if hashtag_view_recent.exists():
            hashtag_view_recent.click()
            random_sleep(5, 10)
            return HashTagView(self.device)

        logger.info(f"{hashtag} is not in recent searching history..")
        search_edit_text.set_text(hashtag)
        hashtag_view = self._getHashtagRow(hashtag[1:])
        random_sleep(4, 8)

        if not hashtag_view.exists():
            logger.error(f"Cannot find hashtag {hashtag}, abort.")
            save_crash(self.device)
            return None

        hashtag_view.click()
        random_sleep()

        return HashTagView(self.device)
    def iterate_over_followers(
        self,
        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:
            logger.info("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):
                        logger.info(
                            "Next item not found: probably reached end of the screen.",
                            extra={"color": f"{Fore.GREEN}"},
                        )
                        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):
                        logger.info(f"@{username} is in blacklist. Skip.")
                    elif not is_myself and storage.check_user_was_interacted(username):
                        logger.info(f"@{username}: already interacted. Skip.")
                        screen_skipped_followers_count += 1
                    elif is_myself and storage.check_user_was_interacted_recently(
                        username
                    ):
                        logger.info(
                            f"@{username}: already interacted in the last week. Skip."
                        )
                        screen_skipped_followers_count += 1
                    else:
                        logger.info(f"@{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

                        logger.info("Back to followers list")
                        device.back()
                        random_sleep()
            except IndexError:
                logger.error(
                    "Cannot get next item: probably reached end of the screen."
                )

            if is_myself and scrolled_to_top():
                logger.info(
                    "Scrolled to top, finish.", extra={"color": f"{Fore.GREEN}"}
                )
                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():
                    logger.error(
                        "Cannot find the list of followers. Trying to press back again."
                    )
                    device.back()
                    list_view = device.find(
                        resourceId="android:id/list",
                        className="android.widget.ListView",
                    )

                if is_myself:
                    logger.info("Need to scroll now", extra={"color": f"{Fore.GREEN}"})
                    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():
                            logger.info('Press "Load" button')
                            retry_button.click()
                            random_sleep()
                            pressed_retry = True

                    if need_swipe and not pressed_retry:
                        logger.info(
                            "All followers skipped, let's do a swipe",
                            extra={"color": f"{Fore.GREEN}"},
                        )
                        list_view.swipe(DeviceFacade.Direction.BOTTOM)
                    else:
                        logger.info(
                            "Need to scroll now", extra={"color": f"{Fore.GREEN}"}
                        )
                        list_view.scroll(DeviceFacade.Direction.BOTTOM)
            else:
                logger.info(
                    "No followers were iterated, finish.",
                    extra={"color": f"{Fore.GREEN}"},
                )
                return