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
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
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 do_unfollow(self, device: DeviceFacade, username, my_username, check_if_is_follower): """ :return: whether unfollow was successful """ username_view = device.find( resourceId=self.ResourceID.FOLLOW_LIST_USERNAME, className=ClassName.TEXT_VIEW, text=username, ) if not username_view.exists(): logger.error("Cannot find @" + username + ", skip.") return False username_view.click() if check_if_is_follower and self.check_is_follower( device, username, my_username): logger.info(f"Skip @{username}. This user is following you.") logger.info("Back to the followings list.") device.back() return False unfollow_button = device.find( classNameMatches=ClassName.BUTTON, clickable=True, textMatches=FOLLOWING_REGEX, ) # I don't know/remember the origin of this, if someone does - let's document it attempts = 2 for _ in range(attempts): if unfollow_button.exists(): break scrollable = device.find(classNameMatches=ClassName.VIEW_PAGER) if scrollable.exists(): scrollable.scroll(DeviceFacade.Direction.TOP) unfollow_button = device.find( classNameMatches=ClassName.BUTTON, clickable=True, textMatches=FOLLOWING_REGEX, ) if not unfollow_button.exists(): logger.error( "Cannot find Following button. Maybe not English language is set?" ) save_crash(device) switch_to_english(device) raise LanguageNotEnglishException() random_sleep() logger.debug("Unfollow btn click") unfollow_button.click() logger.info(f"Unfollow @{username}.", extra={"color": f"{Fore.YELLOW}"}) # Weirdly enough, this is a fix for after you unfollow someone that follows # you back - the next person you unfollow the button is missing on first find # additional find - finds it. :shrug: confirm_unfollow_button = None attempts = 2 for _ in range(attempts): confirm_unfollow_button = device.find( resourceId=self.ResourceID.FOLLOW_SHEET_UNFOLLOW_ROW) if confirm_unfollow_button.exists(): break if not confirm_unfollow_button or not confirm_unfollow_button.exists(): logger.error("Cannot confirm unfollow.") save_crash(device) device.back() return False logger.debug("Confirm unfollow") confirm_unfollow_button.click() random_sleep(0, 1) # Check if private account confirmation private_unfollow_button = device.find( classNameMatches=ClassName.BUTTON_OR_TEXTVIEW_REGEX, textMatches=UNFOLLOW_REGEX, ) if private_unfollow_button.exists(): logger.debug("Confirm unfollow private account") private_unfollow_button.click() detect_block(device) logger.info("Back to the followings list.") device.back() return True
def do_unfollow(self, device, username, my_username, check_if_is_follower): """ :return: whether unfollow was successful """ username_view = device.find( resourceId="com.instagram.android:id/follow_list_username", className="android.widget.TextView", text=username, ) if not username_view.exists(): logger.error("Cannot find @" + username + ", skip.") return False username_view.click() if check_if_is_follower and self.check_is_follower( device, username, my_username): logger.info(f"Skip @{username}. This user is following you.") logger.info("Back to the followings list.") device.back() return False attempts = 0 while True: unfollow_button = device.find( classNameMatches=BUTTON_REGEX, clickable=True, textMatches=FOLLOWING_REGEX, ) if not unfollow_button.exists() and attempts <= 1: scrollable = device.find( classNameMatches="androidx.viewpager.widget.ViewPager") scrollable.scroll(DeviceFacade.Direction.TOP) attempts += 1 else: break if not unfollow_button.exists(): logger.error( "Cannot find Following button. Maybe not English language is set?" ) save_crash(device) switch_to_english(device) raise LanguageNotEnglishException() unfollow_button.click() confirm_unfollow_button = device.find( resourceId="com.instagram.android:id/follow_sheet_unfollow_row", className="android.widget.TextView", ) if not confirm_unfollow_button.exists(): logger.error("Cannot confirm unfollow.") save_crash(device) device.back() return False confirm_unfollow_button.click() random_sleep() # Check if private account confirmation private_unfollow_button = device.find( classNameMatches=BUTTON_OR_TEXTVIEW_REGEX, textMatches=UNFOLLOW_REGEX, ) if private_unfollow_button.exists(): private_unfollow_button.click() detect_block(device) logger.info("Back to the followings list.") device.back() return True