Skip to content

Commit

Permalink
Merge pull request #81 from alexal1/DNUSH-master
Browse files Browse the repository at this point in the history
Minor improvements for #74
  • Loading branch information
alexal1 authored Aug 8, 2020
2 parents 51e4ad9 + 03a5798 commit 979f89e
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 35 deletions.
55 changes: 45 additions & 10 deletions insomniac.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from src.action_get_my_profile_info import get_my_profile_info
from src.action_handle_blogger import handle_blogger
from src.action_unfollow import unfollow
from src.action_unfollow import unfollow, UnfollowRestriction
from src.counters_parser import LanguageChangedException
from src.filter import Filter
from src.navigation import navigate, Tabs
Expand Down Expand Up @@ -48,10 +48,12 @@ def main():
is_interact_enabled = len(args.interact) > 0
is_unfollow_enabled = int(args.unfollow) > 0
is_unfollow_non_followers_enabled = int(args.unfollow_non_followers) > 0
total_enabled = int(is_interact_enabled) + int(is_unfollow_enabled) + int(is_unfollow_non_followers_enabled)
is_unfollow_any_enabled = int(args.unfollow_any) > 0
total_enabled = int(is_interact_enabled) + int(is_unfollow_enabled) + int(is_unfollow_non_followers_enabled) \
+ int(is_unfollow_any_enabled)
if total_enabled == 0:
print_timeless(COLOR_FAIL + "You have to specify one of the actions: --interact, --unfollow, "
"--unfollow-non-followers" + COLOR_ENDC)
"--unfollow-non-followers, --unfollow-any" + COLOR_ENDC)
return
elif total_enabled > 1:
print_timeless(COLOR_FAIL + "Running Insomniac with two or more actions is not supported yet." + COLOR_ENDC)
Expand All @@ -66,6 +68,9 @@ def main():
elif is_unfollow_non_followers_enabled:
print("Action: unfollow " + str(args.unfollow_non_followers) + " non followers")
mode = Mode.UNFOLLOW_NON_FOLLOWERS
elif is_unfollow_any_enabled:
print("Action: unfollow any " + str(args.unfollow_any))
mode = Mode.UNFOLLOW_ANY

profile_filter = Filter()
on_interaction = partial(_on_interaction,
Expand All @@ -79,7 +84,9 @@ def main():

print_timeless(COLOR_WARNING + "\n-------- START: " + str(session_state.startTime) + " --------" + COLOR_ENDC)
open_instagram(device_id)
session_state.my_username, session_state.my_followers_count = get_my_profile_info(device)
session_state.my_username,\
session_state.my_followers_count,\
session_state.my_following_count = get_my_profile_info(device)
storage = Storage(session_state.my_username)

# IMPORTANT: in each job we assume being on the top of the Profile tab already
Expand All @@ -93,9 +100,23 @@ def main():
profile_filter,
on_interaction)
elif mode == Mode.UNFOLLOW:
_job_unfollow(device, int(args.unfollow), storage, only_non_followers=False)
_job_unfollow(device,
int(args.unfollow),
storage,
int(args.min_following),
UnfollowRestriction.FOLLOWED_BY_SCRIPT)
elif mode == Mode.UNFOLLOW_NON_FOLLOWERS:
_job_unfollow(device, int(args.unfollow_non_followers), storage, only_non_followers=True)
_job_unfollow(device,
int(args.unfollow_non_followers),
storage,
int(args.min_following),
UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS)
elif mode == Mode.UNFOLLOW_ANY:
_job_unfollow(device,
int(args.unfollow_any),
storage,
int(args.min_following),
UnfollowRestriction.ANY)

close_instagram(device_id)
print_copyright(session_state.my_username)
Expand Down Expand Up @@ -171,7 +192,7 @@ def job():
break


def _job_unfollow(device, count, storage, only_non_followers):
def _job_unfollow(device, count, storage, min_following, unfollow_restriction):
class State:
def __init__(self):
pass
Expand All @@ -181,6 +202,11 @@ def __init__(self):

state = State()
session_state = sessions[-1]
new_count = min(count, session_state.my_following_count - min_following)
if new_count <= 0:
print("You want to unfollow " + str(count) + ", you have " + str(session_state.my_following_count) +
" followings, min following is " + str(min_following) + ". Finish.")
return

def on_unfollow():
state.unfollowed_count += 1
Expand All @@ -189,15 +215,15 @@ def on_unfollow():
@_run_safely(device=device)
def job():
unfollow(device,
count - state.unfollowed_count,
new_count - state.unfollowed_count,
on_unfollow,
storage,
only_non_followers,
unfollow_restriction,
session_state.my_username)
print("Unfollowed " + str(state.unfollowed_count) + ", finish.")
state.is_job_completed = True

while not state.is_job_completed and state.unfollowed_count < count:
while not state.is_job_completed and state.unfollowed_count < new_count:
job()


Expand Down Expand Up @@ -245,6 +271,14 @@ def _parse_arguments():
'by this script will be unfollowed. The order is from oldest to newest followings',
metavar='100',
default='0')
parser.add_argument('--unfollow-any',
help='unfollow at most given number of users. The order is from oldest to newest followings',
metavar='100',
default='0')
parser.add_argument('--min-following',
help='minimum amount of followings, after reaching this amount unfollow stops',
metavar='100',
default=0)
parser.add_argument('--device',
help='device identifier. Should be used only when multiple devices are connected at once',
metavar='2443de990e017ece')
Expand Down Expand Up @@ -332,6 +366,7 @@ class Mode(Enum):
INTERACT = 0
UNFOLLOW = 1
UNFOLLOW_NON_FOLLOWERS = 2
UNFOLLOW_ANY = 3


if __name__ == "__main__":
Expand Down
32 changes: 29 additions & 3 deletions src/action_get_my_profile_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,26 @@ def get_my_profile_info(device):
navigate(device, Tabs.PROFILE)
followers = _get_followers_count(device)

try:
following = _get_following_count(device)
except LanguageChangedException:
# Try again on the correct language
navigate(device, Tabs.PROFILE)
following = _get_following_count(device)

report_string = ""
if username:
report_string += "Hello, @" + username + "!"
if followers:
report_string += " You have " + str(followers) + " followers so far."
if followers is not None:
report_string += " You have " + str(followers) + " followers"
if following is not None:
report_string += " and " + str(following) + " followings"
report_string += " so far."

if not report_string == "":
print(report_string)

return username, followers
return username, followers, following


def _get_followers_count(device):
Expand All @@ -49,3 +59,19 @@ def _get_followers_count(device):
print(COLOR_FAIL + "Cannot find your followers count view" + COLOR_ENDC)

return followers


def _get_following_count(device):
following = None
following_text_view = device(resourceId='com.instagram.android:id/row_profile_header_textview_following_count',
className='android.widget.TextView')
if following_text_view.exists:
following_text = following_text_view.text
if following_text:
following = parse(device, following_text)
else:
print(COLOR_FAIL + "Cannot get your following count text" + COLOR_ENDC)
else:
print(COLOR_FAIL + "Cannot find your following count view" + COLOR_ENDC)

return following
59 changes: 37 additions & 22 deletions src/action_unfollow.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from enum import unique, Enum

from src.storage import FollowingStatus
from src.utils import *


def unfollow(device, count, on_unfollow, storage, only_non_followers, my_username):
def unfollow(device, count, on_unfollow, storage, unfollow_restriction, my_username):
_open_my_followings(device)
_sort_followings_by_date(device)
_iterate_over_followings(device, count, on_unfollow, storage, only_non_followers, my_username)
_iterate_over_followings(device, count, on_unfollow, storage, unfollow_restriction, my_username)


def _open_my_followings(device):
Expand All @@ -29,7 +31,7 @@ def _sort_followings_by_date(device):
sort_options_recycler_view.child(index=2).click.wait()


def _iterate_over_followings(device, count, on_unfollow, storage, only_non_followers, my_username):
def _iterate_over_followings(device, count, on_unfollow, storage, unfollow_restriction, my_username):
unfollowed_count = 0
while True:
print("Iterate over visible followings")
Expand All @@ -46,29 +48,35 @@ def _iterate_over_followings(device, count, on_unfollow, storage, only_non_follo
username = user_name_view.text
screen_iterated_followings += 1

following_status = storage.get_following_status(username)
if not following_status == FollowingStatus.FOLLOWED:
print("Skip @" + username + ". Following status: " + following_status.name + ".")
elif only_non_followers and _check_is_follower(device, username, my_username):
if unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT or \
unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS:
following_status = storage.get_following_status(username)
if not following_status == FollowingStatus.FOLLOWED:
print("Skip @" + username + ". Following status: " + following_status.name + ".")
continue

if unfollow_restriction == UnfollowRestriction.FOLLOWED_BY_SCRIPT_NON_FOLLOWERS and \
_check_is_follower(device, username, my_username):
print("Skip @" + username + ". This user is following you.")
else:
print("Unfollow @" + username)
continue

print("Unfollow @" + username)

unfollow_button = item.child(resourceId='com.instagram.android:id/button',
className='android.widget.TextView')
if not unfollow_button.exists:
print(COLOR_FAIL + "Cannot find unfollow button" + COLOR_ENDC)
break
unfollow_button.click.wait()
_close_dialog_if_shown(device)
storage.add_interacted_user(username, unfollowed=True)
on_unfollow()
unfollow_button = item.child(resourceId='com.instagram.android:id/button',
className='android.widget.TextView')
if not unfollow_button.exists:
print(COLOR_FAIL + "Cannot find unfollow button" + COLOR_ENDC)
break
unfollow_button.click.wait()
_close_dialog_if_shown(device)
storage.add_interacted_user(username, unfollowed=True)
on_unfollow()

random_sleep()
random_sleep()

unfollowed_count += 1
if unfollowed_count >= count:
return
unfollowed_count += 1
if unfollowed_count >= count:
return

if screen_iterated_followings > 0:
print(COLOR_OKGREEN + "Need to scroll now" + COLOR_ENDC)
Expand Down Expand Up @@ -114,3 +122,10 @@ def _check_is_follower(device, username, my_username):
device.press.back()
device.press.back()
return result


@unique
class UnfollowRestriction(Enum):
ANY = 0
FOLLOWED_BY_SCRIPT = 1
FOLLOWED_BY_SCRIPT_NON_FOLLOWERS = 2
2 changes: 2 additions & 0 deletions src/session_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class SessionState:
args = {}
my_username = None
my_followers_count = None
my_following_count = None
totalInteractions = {}
successfulInteractions = {}
totalFollowed = {}
Expand All @@ -21,6 +22,7 @@ def __init__(self):
self.args = {}
self.my_username = None
self.my_followers_count = None
self.my_following_count = None
self.totalInteractions = {}
self.successfulInteractions = {}
self.totalFollowed = {}
Expand Down

0 comments on commit 979f89e

Please sign in to comment.