def unfollow(device, on_action, storage, unfollow_restriction, sort_order, session_state, is_limit_reached, action_status): if not open_user_followings(device=device, username=None, on_action=on_action): return sleeper.random_sleep() sort_followings_by_date(device, sort_order) sleeper.random_sleep() # noinspection PyUnusedLocal # following_name_view is a standard callback argument def iteration_callback_pre_conditions(following_name, following_name_view, follow_status_button_view): """ :return: True to start unfollowing for given user, False to skip """ if storage.is_user_in_whitelist(following_name): print(f"@{following_name} is in whitelist. Skip.") return False if unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT or \ unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS: following_status = storage.get_following_status(following_name) if not following_status == FollowingStatus.FOLLOWED: print("Skip @" + following_name + ". Following status: " + following_status.name + " (probably not followed by the bot...)") return False if follow_status_button_view is not None: following_status = storage.get_following_status(following_name) follow_status_from_row = follow_status_button_view.get_text() print("Follow-status-button text: " + follow_status_from_row + ".") if follow_status_from_row in FOLLOW_REGEX.split('|') or following_status == FollowingStatus.UNFOLLOWED: print("Skip @" + following_name + ". Following status: " + FollowingStatus.UNFOLLOWED.name + "(already been unfollowed by the bot...)") return False if unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS or \ unfollow_restriction == UnfollowRestriction.ANY_NON_FOLLOWERS: if storage.is_profile_follows_me_by_cache(following_name): print("Skip @" + following_name + ". Following status (according to cache): " + FollowingStatus.FOLLOWED.name) return False return True # noinspection PyUnusedLocal # following_name_view is a standard callback argument def iteration_callback(following_name, following_name_view, follow_status_button_view): """ :return: True to continue unfollowing after given user, False to stop """ print("Running Unfollow-action on @" + following_name) is_unfollow_limit_reached, unfollow_reached_source_limit, unfollow_reached_session_limit = \ is_limit_reached(UnfollowAction(user=following_name), session_state) if not process_limits(is_unfollow_limit_reached, unfollow_reached_session_limit, unfollow_reached_source_limit, action_status, "Unfollowing"): return False is_get_profile_limit_reached, get_profile_reached_source_limit, get_profile_reached_session_limit = \ is_limit_reached(GetProfileAction(user=following_name), session_state) if not process_limits(is_get_profile_limit_reached, get_profile_reached_session_limit, get_profile_reached_source_limit, action_status, "Get-Profile"): return False check_if_is_follower = unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS or \ unfollow_restriction == UnfollowRestriction.ANY_NON_FOLLOWERS unfollowed = do_unfollow(device, session_state.my_username, following_name, storage, check_if_is_follower, following_name_view, follow_status_button_view, on_action) if unfollowed: storage.add_interacted_user(following_name, unfollowed=True) on_action(UnfollowAction(user=following_name)) print(COLOR_OKGREEN + f"Unfollowed @{following_name}" + COLOR_ENDC) print_short_unfollow_report(session_state) return True iterate_over_my_followings(device, iteration_callback, iteration_callback_pre_conditions)
def unfollow(device, on_action, storage, unfollow_restriction, session_state, is_limit_reached, action_status): if not open_user_followings( device=device, username=None, on_action=on_action): return sleeper.random_sleep() sort_followings_by_date(device) sleeper.random_sleep() # noinspection PyUnusedLocal # following_name_view is a standard callback argument def iteration_callback_pre_conditions(following_name, following_name_view): """ :return: True to start unfollowing for given user, False to skip """ if storage.is_user_in_whitelist(following_name): print(f"@{following_name} is in whitelist. Skip.") return False if unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT or \ unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS: following_status = storage.get_following_status(following_name) if not following_status == FollowingStatus.FOLLOWED: print("Skip @" + following_name + ". Following status: " + following_status.name + ".") return False if unfollow_restriction == UnfollowRestriction.ANY: following_status = storage.get_following_status(following_name) if following_status == FollowingStatus.UNFOLLOWED: print("Skip @" + following_name + ". Following status: " + following_status.name + ".") return False return True # noinspection PyUnusedLocal # following_name_view is a standard callback argument def iteration_callback(following_name, following_name_view): """ :return: True to continue unfollowing after given user, False to stop """ print("Unfollow @" + following_name) is_unfollow_limit_reached, unfollow_reached_source_limit, unfollow_reached_session_limit = \ is_limit_reached(UnfollowAction(user=following_name), session_state) if not process_limits( is_unfollow_limit_reached, unfollow_reached_session_limit, unfollow_reached_source_limit, action_status, "Unfollowing"): return False is_get_profile_limit_reached, get_profile_reached_source_limit, get_profile_reached_session_limit = \ is_limit_reached(GetProfileAction(user=following_name), session_state) if not process_limits(is_get_profile_limit_reached, get_profile_reached_session_limit, get_profile_reached_source_limit, action_status, "Get-Profile"): return False check_if_is_follower = unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS unfollowed = do_unfollow(device, following_name, session_state.my_username, check_if_is_follower, on_action) if unfollowed: storage.add_interacted_user(following_name, unfollowed=True) on_action(UnfollowAction(user=following_name)) return True iterate_over_followings(device, iteration_callback, iteration_callback_pre_conditions)
def handle_blogger(device, username, instructions, session_state, likes_count, stories_count, follow_percentage, like_percentage, storage, on_action, is_limit_reached, is_passed_filters, action_status): is_myself = username == session_state.my_username interaction = partial(interact_with_user, device=device, user_source=username, my_username=session_state.my_username, on_action=on_action) if instructions == BloggerInteractionType.FOLLOWERS: if not open_user_followers(device=device, username=username, on_action=on_action): return elif instructions == BloggerInteractionType.FOLLOWING: if not open_user_followings(device=device, username=username, on_action=on_action): return if is_myself: scroll_to_bottom(device) def pre_conditions(follower_name, follower_name_view): if storage.is_user_in_blacklist(follower_name): print("@" + follower_name + " is in blacklist. Skip.") return False elif storage.check_user_was_filtered(follower_name): print("@" + follower_name + ": already filtered in past. Skip.") return False elif not is_myself and storage.check_user_was_interacted(follower_name): print("@" + follower_name + ": already interacted. Skip.") return False elif is_myself and storage.check_user_was_interacted_recently(follower_name): print("@" + follower_name + ": already interacted in the last week. Skip.") return False elif is_passed_filters is not None: if not is_passed_filters(device, follower_name, ['BEFORE_PROFILE_CLICK']): storage.add_filtered_user(follower_name) return False return True def interact_with_follower(follower_name, follower_name_view): is_interact_limit_reached, interact_reached_source_limit, interact_reached_session_limit = \ is_limit_reached(InteractAction(source=username, user=follower_name, succeed=True), session_state) if not process_limits(is_interact_limit_reached, interact_reached_session_limit, interact_reached_source_limit, action_status, "Interaction"): return False is_get_profile_limit_reached, get_profile_reached_source_limit, get_profile_reached_session_limit = \ is_limit_reached(GetProfileAction(user=follower_name), session_state) if not process_limits(is_get_profile_limit_reached, get_profile_reached_session_limit, get_profile_reached_source_limit, action_status, "Get-Profile"): return False print("@" + follower_name + ": interact") follower_name_view.click() on_action(GetProfileAction(user=follower_name)) if is_passed_filters is not None: if not is_passed_filters(device, follower_name): storage.add_filtered_user(follower_name) # Continue to next follower print("Back to profiles list") device.back() return True is_like_limit_reached, like_reached_source_limit, like_reached_session_limit = \ is_limit_reached(LikeAction(source=username, user=follower_name), session_state) is_follow_limit_reached, follow_reached_source_limit, follow_reached_session_limit = \ is_limit_reached(FollowAction(source=username, user=follower_name), session_state) is_watch_limit_reached, watch_reached_source_limit, watch_reached_session_limit = \ is_limit_reached(StoryWatchAction(user=follower_name), session_state) is_private = is_private_account(device) if is_private: print("@" + follower_name + ": Private account - images wont be liked.") do_have_stories = do_have_story(device) if not do_have_stories: print("@" + follower_name + ": seems there are no stories to be watched.") is_likes_enabled = likes_count != '0' is_stories_enabled = stories_count != '0' is_follow_enabled = follow_percentage != 0 likes_value = get_value(likes_count, "Likes count: {}", 2, max_count=12) stories_value = get_value(stories_count, "Stories to watch: {}", 1) can_like = not is_like_limit_reached and not is_private and likes_value > 0 can_follow = (not is_follow_limit_reached) and storage.get_following_status(username) == FollowingStatus.NONE and follow_percentage > 0 can_watch = (not is_watch_limit_reached) and do_have_stories and stories_value > 0 can_interact = can_like or can_follow or can_watch if not can_interact: print("@" + follower_name + ": Cant be interacted (due to limits / already followed). Skip.") storage.add_interacted_user(follower_name, followed=False) on_action(InteractAction(source=username, user=follower_name, succeed=False)) else: print_interaction_types(follower_name, can_like, can_follow, can_watch) interaction_strategy = InteractionStrategy(do_like=can_like, do_follow=can_follow, do_story_watch=can_watch, likes_count=likes_value, follow_percentage=follow_percentage, like_percentage=like_percentage, stories_count=stories_value) is_liked, is_followed, is_watch = interaction(username=follower_name, interaction_strategy=interaction_strategy) if is_liked or is_followed or is_watch: storage.add_interacted_user(follower_name, followed=is_followed) on_action(InteractAction(source=username, user=follower_name, succeed=True)) print_short_report(username, session_state) else: storage.add_interacted_user(follower_name, followed=False) on_action(InteractAction(source=username, user=follower_name, succeed=False)) can_continue = True if ((is_like_limit_reached and is_likes_enabled) or not is_likes_enabled) and \ ((is_follow_limit_reached and is_follow_enabled) or not is_follow_enabled) and \ ((is_watch_limit_reached and is_stories_enabled) or not is_stories_enabled): # If one of the limits reached for source-limit, move to next source if (like_reached_source_limit is not None and like_reached_session_limit is None) or \ (follow_reached_source_limit is not None and follow_reached_session_limit is None): can_continue = False action_status.set_limit(ActionState.SOURCE_LIMIT_REACHED) # If all of the limits reached for session-limit, finish the session if ((like_reached_session_limit is not None and is_likes_enabled) or not is_likes_enabled) and \ ((follow_reached_session_limit is not None and is_follow_enabled) or not is_follow_enabled): can_continue = False action_status.set_limit(ActionState.SESSION_LIMIT_REACHED) print("Back to profiles list") device.back() return can_continue iterate_over_followers(device, is_myself, interact_with_follower, pre_conditions)