InstaAddict 1.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- GramAddict/__init__.py +10 -0
- GramAddict/__main__.py +161 -0
- GramAddict/core/__init__.py +0 -0
- GramAddict/core/bot_flow.py +425 -0
- GramAddict/core/config.py +219 -0
- GramAddict/core/decorators.py +144 -0
- GramAddict/core/device_facade.py +743 -0
- GramAddict/core/download_from_github.py +263 -0
- GramAddict/core/filter.py +759 -0
- GramAddict/core/handle_sources.py +890 -0
- GramAddict/core/interaction.py +1034 -0
- GramAddict/core/log.py +152 -0
- GramAddict/core/navigation.py +120 -0
- GramAddict/core/persistent_list.py +56 -0
- GramAddict/core/plugin_loader.py +46 -0
- GramAddict/core/report.py +206 -0
- GramAddict/core/resources.py +245 -0
- GramAddict/core/scroll_end_detector.py +77 -0
- GramAddict/core/session_state.py +323 -0
- GramAddict/core/storage.py +254 -0
- GramAddict/core/utils.py +804 -0
- GramAddict/core/views.py +2207 -0
- GramAddict/plugins/__init__.py +0 -0
- GramAddict/plugins/action_unfollow_followers.py +570 -0
- GramAddict/plugins/cloned_app.py +25 -0
- GramAddict/plugins/core_arguments.py +411 -0
- GramAddict/plugins/data_analytics.py +40 -0
- GramAddict/plugins/interact_blogger.py +258 -0
- GramAddict/plugins/interact_blogger_followers.py +196 -0
- GramAddict/plugins/interact_blogger_post_likers.py +184 -0
- GramAddict/plugins/interact_feed.py +147 -0
- GramAddict/plugins/interact_hashtag_likers.py +199 -0
- GramAddict/plugins/interact_hashtag_posts.py +192 -0
- GramAddict/plugins/interact_place_likers.py +194 -0
- GramAddict/plugins/interact_place_posts.py +185 -0
- GramAddict/plugins/like_from_urls.py +137 -0
- GramAddict/plugins/plugin.example +38 -0
- GramAddict/plugins/remove_followers.py +122 -0
- GramAddict/plugins/telegram.py +249 -0
- GramAddict/version.py +2 -0
- instaaddict-1.0.1.dist-info/METADATA +335 -0
- instaaddict-1.0.1.dist-info/RECORD +45 -0
- instaaddict-1.0.1.dist-info/WHEEL +4 -0
- instaaddict-1.0.1.dist-info/entry_points.txt +3 -0
- instaaddict-1.0.1.dist-info/licenses/LICENSE +23 -0
GramAddict/__init__.py
ADDED
GramAddict/__main__.py
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from os import getcwd, path
|
|
3
|
+
|
|
4
|
+
from GramAddict import __version__
|
|
5
|
+
from GramAddict.core.bot_flow import start_bot
|
|
6
|
+
from GramAddict.core.download_from_github import download_from_github
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def cmd_init(args):
|
|
10
|
+
if args.account_name is not None:
|
|
11
|
+
print(f"Script launched in {getcwd()}, files will be available there.")
|
|
12
|
+
for username in args.account_name:
|
|
13
|
+
if not path.exists("./run.py"):
|
|
14
|
+
print("Creating run.py ...")
|
|
15
|
+
download_from_github(
|
|
16
|
+
"https://github.com/joeahkim/InstaAddict/blob/master/run.py"
|
|
17
|
+
)
|
|
18
|
+
if not path.exists(f"./accounts/{username}"):
|
|
19
|
+
print(
|
|
20
|
+
f"Creating 'accounts/{username}' folder with a config starting point inside. You have to edit these files according with https://docs.gramaddict.org/#/configuration"
|
|
21
|
+
)
|
|
22
|
+
download_from_github(
|
|
23
|
+
"https://github.com/joeahkim/InstaAddict/tree/master/config-examples",
|
|
24
|
+
output_dir=f"accounts/{username}",
|
|
25
|
+
flatten=True,
|
|
26
|
+
)
|
|
27
|
+
else:
|
|
28
|
+
print(f"'accounts/{username}' folder already exists, skip.")
|
|
29
|
+
continue
|
|
30
|
+
with open(f"./accounts/{username}/config.yml", "r+", encoding="utf-8") as f:
|
|
31
|
+
config = f.read()
|
|
32
|
+
f.seek(0)
|
|
33
|
+
config_fixed = config.replace("myusername", username)
|
|
34
|
+
f.write(config_fixed)
|
|
35
|
+
else:
|
|
36
|
+
print("You have to provide at last one account name..")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def cmd_run(args):
|
|
40
|
+
start_bot()
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def cmd_dump(args):
|
|
44
|
+
import os
|
|
45
|
+
import shutil
|
|
46
|
+
import time
|
|
47
|
+
|
|
48
|
+
import uiautomator2 as u2
|
|
49
|
+
from colorama import Fore, Style
|
|
50
|
+
|
|
51
|
+
if not args.no_kill:
|
|
52
|
+
os.popen("adb shell pkill atx-agent").close()
|
|
53
|
+
try:
|
|
54
|
+
d = u2.connect(args.device)
|
|
55
|
+
except RuntimeError as err:
|
|
56
|
+
raise SystemExit(err)
|
|
57
|
+
|
|
58
|
+
def dump_hierarchy(device, path):
|
|
59
|
+
xml_dump = device.dump_hierarchy()
|
|
60
|
+
with open(path, "w", encoding="utf-8") as outfile:
|
|
61
|
+
outfile.write(xml_dump)
|
|
62
|
+
|
|
63
|
+
def make_archive(name):
|
|
64
|
+
os.chdir("dump")
|
|
65
|
+
shutil.make_archive(base_name=f"screen_{name}", format="zip", root_dir="cur")
|
|
66
|
+
shutil.rmtree("cur")
|
|
67
|
+
|
|
68
|
+
os.makedirs("dump/cur", exist_ok=True)
|
|
69
|
+
d.screenshot("dump/cur/screenshot.png")
|
|
70
|
+
dump_hierarchy(d, "dump/cur/hierarchy.xml")
|
|
71
|
+
archive_name = int(time.time())
|
|
72
|
+
make_archive(archive_name)
|
|
73
|
+
print(
|
|
74
|
+
Fore.GREEN
|
|
75
|
+
+ Style.BRIGHT
|
|
76
|
+
+ "\nCurrent screen dump generated successfully! Please, send me this file:"
|
|
77
|
+
)
|
|
78
|
+
print(Fore.BLUE + Style.BRIGHT + f"{os.getcwd()}\\screen_{archive_name}.zip")
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
_commands = [
|
|
82
|
+
dict(
|
|
83
|
+
action=cmd_init,
|
|
84
|
+
command="init",
|
|
85
|
+
help="creates your account folder under accounts with files for configuration",
|
|
86
|
+
flags=[
|
|
87
|
+
dict(
|
|
88
|
+
args=["account_name"],
|
|
89
|
+
nargs="+",
|
|
90
|
+
help="instagram account name to initialize",
|
|
91
|
+
),
|
|
92
|
+
],
|
|
93
|
+
),
|
|
94
|
+
dict(
|
|
95
|
+
action=cmd_run,
|
|
96
|
+
command="run",
|
|
97
|
+
help="start the bot!",
|
|
98
|
+
flags=[
|
|
99
|
+
dict(args=["--config"], nargs="?", help="provide the config.yml path"),
|
|
100
|
+
],
|
|
101
|
+
),
|
|
102
|
+
dict(
|
|
103
|
+
action=cmd_dump,
|
|
104
|
+
command="dump",
|
|
105
|
+
help="dump current screen",
|
|
106
|
+
flags=[
|
|
107
|
+
dict(
|
|
108
|
+
args=["--device"],
|
|
109
|
+
nargs=None,
|
|
110
|
+
default=None,
|
|
111
|
+
help="provide the device name if more then one connected",
|
|
112
|
+
),
|
|
113
|
+
dict(
|
|
114
|
+
args=["--no-kill"],
|
|
115
|
+
action="store_true",
|
|
116
|
+
help="don't kill the uia2 demon",
|
|
117
|
+
),
|
|
118
|
+
],
|
|
119
|
+
),
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def main() -> None:
|
|
124
|
+
parser = argparse.ArgumentParser(
|
|
125
|
+
prog="GramAddict",
|
|
126
|
+
description="free human-like Instagram bot",
|
|
127
|
+
)
|
|
128
|
+
parser.add_argument(
|
|
129
|
+
"-v", "--version", action="version", version=f"{parser.prog} {__version__}"
|
|
130
|
+
)
|
|
131
|
+
subparser = parser.add_subparsers(dest="subparser")
|
|
132
|
+
actions = {}
|
|
133
|
+
for c in _commands:
|
|
134
|
+
cmd_name = c["command"]
|
|
135
|
+
actions[cmd_name] = c["action"]
|
|
136
|
+
sp = subparser.add_parser(
|
|
137
|
+
cmd_name,
|
|
138
|
+
help=c.get("help"),
|
|
139
|
+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
|
140
|
+
)
|
|
141
|
+
for f in c.get("flags", []):
|
|
142
|
+
args = f.get("args")
|
|
143
|
+
if not args:
|
|
144
|
+
args = ["-" * min(2, len(n)) + n for n in f["name"]]
|
|
145
|
+
kwargs = f.copy()
|
|
146
|
+
kwargs.pop("name", None)
|
|
147
|
+
kwargs.pop("args", None)
|
|
148
|
+
kwargs.pop("run", None)
|
|
149
|
+
sp.add_argument(*args, **kwargs)
|
|
150
|
+
|
|
151
|
+
args = parser.parse_args()
|
|
152
|
+
|
|
153
|
+
if args.subparser:
|
|
154
|
+
actions[args.subparser](args)
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
parser.print_help()
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
if __name__ == "__main__":
|
|
161
|
+
main()
|
|
File without changes
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import random
|
|
3
|
+
from datetime import datetime, timedelta
|
|
4
|
+
from time import sleep
|
|
5
|
+
|
|
6
|
+
from colorama import Fore, Style
|
|
7
|
+
|
|
8
|
+
from GramAddict import __tested_ig_version__
|
|
9
|
+
from GramAddict.core.config import Config
|
|
10
|
+
from GramAddict.core.device_facade import create_device, get_device_info
|
|
11
|
+
from GramAddict.core.filter import Filter
|
|
12
|
+
from GramAddict.core.filter import load_config as load_filter
|
|
13
|
+
from GramAddict.core.interaction import load_config as load_interaction
|
|
14
|
+
from GramAddict.core.log import (
|
|
15
|
+
configure_logger,
|
|
16
|
+
is_log_file_updated,
|
|
17
|
+
update_log_file_name,
|
|
18
|
+
)
|
|
19
|
+
from GramAddict.core.navigation import check_if_english
|
|
20
|
+
from GramAddict.core.persistent_list import PersistentList
|
|
21
|
+
from GramAddict.core.report import print_full_report
|
|
22
|
+
from GramAddict.core.session_state import SessionState, SessionStateEncoder
|
|
23
|
+
from GramAddict.core.storage import Storage
|
|
24
|
+
from GramAddict.core.utils import (
|
|
25
|
+
ask_for_a_donation,
|
|
26
|
+
can_repeat,
|
|
27
|
+
check_adb_connection,
|
|
28
|
+
check_if_updated,
|
|
29
|
+
check_screen_timeout,
|
|
30
|
+
close_instagram,
|
|
31
|
+
config_examples,
|
|
32
|
+
countdown,
|
|
33
|
+
get_instagram_version,
|
|
34
|
+
get_value,
|
|
35
|
+
head_up_notifications,
|
|
36
|
+
kill_atx_agent,
|
|
37
|
+
)
|
|
38
|
+
from GramAddict.core.utils import load_config as load_utils
|
|
39
|
+
from GramAddict.core.utils import (
|
|
40
|
+
move_usernames_to_accounts,
|
|
41
|
+
open_instagram,
|
|
42
|
+
pre_post_script,
|
|
43
|
+
print_telegram_reports,
|
|
44
|
+
restart_atx_agent,
|
|
45
|
+
save_crash,
|
|
46
|
+
set_time_delta,
|
|
47
|
+
show_ending_conditions,
|
|
48
|
+
stop_bot,
|
|
49
|
+
wait_for_next_session,
|
|
50
|
+
)
|
|
51
|
+
from GramAddict.core.views import AccountView, ProfileView, TabBarView, UniversalActions
|
|
52
|
+
from GramAddict.core.views import load_config as load_views
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def start_bot(**kwargs):
|
|
56
|
+
# Logging initialization
|
|
57
|
+
logger = logging.getLogger(__name__)
|
|
58
|
+
|
|
59
|
+
# Pre-Load Config
|
|
60
|
+
configs = Config(first_run=True, **kwargs)
|
|
61
|
+
configure_logger(configs.debug, configs.username)
|
|
62
|
+
if not kwargs:
|
|
63
|
+
if "--config" not in configs.args:
|
|
64
|
+
logger.info(
|
|
65
|
+
"It's strongly recommend to use a config.yml file. Follow these links for more details: https://docs.gramaddict.org/#/configuration and https://github.com/joeahkim/Insta-Addict/tree/develop/config-examples",
|
|
66
|
+
extra={"color": f"{Fore.GREEN}{Style.BRIGHT}"},
|
|
67
|
+
)
|
|
68
|
+
sleep(3)
|
|
69
|
+
|
|
70
|
+
# Config-example hint
|
|
71
|
+
config_examples()
|
|
72
|
+
|
|
73
|
+
# Check for updates
|
|
74
|
+
check_if_updated()
|
|
75
|
+
|
|
76
|
+
# Move username folders to a main directory -> accounts
|
|
77
|
+
if "--move-folders-in-accounts" in configs.args:
|
|
78
|
+
move_usernames_to_accounts()
|
|
79
|
+
|
|
80
|
+
# Global Variables
|
|
81
|
+
sessions = PersistentList("sessions", SessionStateEncoder)
|
|
82
|
+
|
|
83
|
+
# Load Config
|
|
84
|
+
configs.load_plugins()
|
|
85
|
+
configs.parse_args()
|
|
86
|
+
# Some plugins need config values without being passed
|
|
87
|
+
# through. Because we do a weird config/argparse hybrid,
|
|
88
|
+
# we need to load the configs in a weird way
|
|
89
|
+
load_filter(configs)
|
|
90
|
+
load_interaction(configs)
|
|
91
|
+
load_utils(configs)
|
|
92
|
+
load_views(configs)
|
|
93
|
+
|
|
94
|
+
if not configs.args or not check_adb_connection():
|
|
95
|
+
return
|
|
96
|
+
|
|
97
|
+
if len(configs.enabled) < 1:
|
|
98
|
+
logger.error(
|
|
99
|
+
"You have to specify one of these actions: " + ", ".join(configs.actions)
|
|
100
|
+
)
|
|
101
|
+
return
|
|
102
|
+
device = create_device(configs.device_id, configs.app_id)
|
|
103
|
+
session_state = None
|
|
104
|
+
if str(configs.args.total_sessions) != "-1":
|
|
105
|
+
total_sessions = get_value(configs.args.total_sessions, None, -1)
|
|
106
|
+
else:
|
|
107
|
+
total_sessions = -1
|
|
108
|
+
|
|
109
|
+
# init
|
|
110
|
+
analytics_at_end = False
|
|
111
|
+
telegram_reports_at_end = False
|
|
112
|
+
followers_now = None
|
|
113
|
+
following_now = None
|
|
114
|
+
|
|
115
|
+
while True:
|
|
116
|
+
set_time_delta(configs.args)
|
|
117
|
+
inside_working_hours, time_left = SessionState.inside_working_hours(
|
|
118
|
+
configs.args.working_hours, configs.args.time_delta_session
|
|
119
|
+
)
|
|
120
|
+
if not inside_working_hours:
|
|
121
|
+
wait_for_next_session(time_left, session_state, sessions, device)
|
|
122
|
+
pre_post_script(path=configs.args.pre_script)
|
|
123
|
+
if configs.args.restart_atx_agent:
|
|
124
|
+
restart_atx_agent(device)
|
|
125
|
+
get_device_info(device)
|
|
126
|
+
session_state = SessionState(configs)
|
|
127
|
+
session_state.set_limits_session()
|
|
128
|
+
sessions.append(session_state)
|
|
129
|
+
check_screen_timeout()
|
|
130
|
+
device.wake_up()
|
|
131
|
+
head_up_notifications(enabled=False)
|
|
132
|
+
logger.info(
|
|
133
|
+
"-------- START: "
|
|
134
|
+
+ str(session_state.startTime.strftime("%H:%M:%S - %Y/%m/%d"))
|
|
135
|
+
+ " --------",
|
|
136
|
+
extra={"color": f"{Style.BRIGHT}{Fore.YELLOW}"},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
if not device.get_info()["screenOn"]:
|
|
140
|
+
device.press_power()
|
|
141
|
+
if device.is_screen_locked():
|
|
142
|
+
device.unlock()
|
|
143
|
+
if device.is_screen_locked():
|
|
144
|
+
logger.error(
|
|
145
|
+
"Can't unlock your screen. There may be a passcode on it. If you would like your screen to be turned on and unlocked automatically, please remove the passcode."
|
|
146
|
+
)
|
|
147
|
+
stop_bot(device, sessions, session_state, was_sleeping=False)
|
|
148
|
+
|
|
149
|
+
logger.info("Device screen ON and unlocked.")
|
|
150
|
+
if open_instagram(device):
|
|
151
|
+
try:
|
|
152
|
+
running_ig_version = get_instagram_version()
|
|
153
|
+
logger.info(f"Instagram version: {running_ig_version}")
|
|
154
|
+
if tuple(running_ig_version.split(".")) > tuple(
|
|
155
|
+
__tested_ig_version__.split(".")
|
|
156
|
+
):
|
|
157
|
+
logger.warning(
|
|
158
|
+
f"You have a newer version of IG then the one tested! (Tested version: {__tested_ig_version__}).",
|
|
159
|
+
extra={"color": f"{Style.BRIGHT}"},
|
|
160
|
+
)
|
|
161
|
+
logger.warning(
|
|
162
|
+
"Using an untested version of IG would cause unexpected behavior because some elements in the user interface may have been changed. Any crashes that occur with an untested version are not taken into account."
|
|
163
|
+
)
|
|
164
|
+
if not configs.args.allow_untested_ig_version:
|
|
165
|
+
logger.warning(
|
|
166
|
+
"If you press ENTER, you are aware of this and will not ask for support in case of a crash."
|
|
167
|
+
)
|
|
168
|
+
logger.warning(
|
|
169
|
+
"If you want to avoid pressing ENTER next run, add allow-untested-ig-version: true in your config.yml file. (read the docs for more info)"
|
|
170
|
+
)
|
|
171
|
+
input()
|
|
172
|
+
|
|
173
|
+
except Exception as e:
|
|
174
|
+
logger.error(f"Error retrieving the IG version. Exception: {e}")
|
|
175
|
+
|
|
176
|
+
UniversalActions.close_keyboard(device)
|
|
177
|
+
else:
|
|
178
|
+
break
|
|
179
|
+
profile_view = ProfileView(device)
|
|
180
|
+
account_view = AccountView(device)
|
|
181
|
+
tab_bar_view = TabBarView(device)
|
|
182
|
+
try:
|
|
183
|
+
account_view.navigate_to_main_account()
|
|
184
|
+
check_if_english(device)
|
|
185
|
+
if configs.args.username is not None:
|
|
186
|
+
success = account_view.changeToUsername(configs.args.username)
|
|
187
|
+
if not success:
|
|
188
|
+
logger.error(
|
|
189
|
+
f"Not able to change to {configs.args.username}, abort!"
|
|
190
|
+
)
|
|
191
|
+
save_crash(device)
|
|
192
|
+
device.back()
|
|
193
|
+
break
|
|
194
|
+
account_view.refresh_account()
|
|
195
|
+
(
|
|
196
|
+
session_state.my_username,
|
|
197
|
+
session_state.my_posts_count,
|
|
198
|
+
session_state.my_followers_count,
|
|
199
|
+
session_state.my_following_count,
|
|
200
|
+
) = profile_view.getProfileInfo()
|
|
201
|
+
except Exception as e:
|
|
202
|
+
logger.error(f"Exception: {e}")
|
|
203
|
+
save_crash(device)
|
|
204
|
+
break
|
|
205
|
+
|
|
206
|
+
if (
|
|
207
|
+
session_state.my_username is None
|
|
208
|
+
or session_state.my_posts_count is None
|
|
209
|
+
or session_state.my_followers_count is None
|
|
210
|
+
or session_state.my_following_count is None
|
|
211
|
+
):
|
|
212
|
+
logger.critical(
|
|
213
|
+
"Could not get one of the following from your profile: username, # of posts, # of followers, # of followings. This is typically due to a soft-ban. Review the crash screenshot to see if this is the case."
|
|
214
|
+
)
|
|
215
|
+
logger.critical(
|
|
216
|
+
f"Username: {session_state.my_username}, Posts: {session_state.my_posts_count}, Followers: {session_state.my_followers_count}, Following: {session_state.my_following_count}"
|
|
217
|
+
)
|
|
218
|
+
save_crash(device)
|
|
219
|
+
stop_bot(device, sessions, session_state)
|
|
220
|
+
|
|
221
|
+
if not is_log_file_updated():
|
|
222
|
+
try:
|
|
223
|
+
update_log_file_name(session_state.my_username)
|
|
224
|
+
except Exception as e:
|
|
225
|
+
logger.error(
|
|
226
|
+
f"Failed to update log file name. Will continue anyway. {e}"
|
|
227
|
+
)
|
|
228
|
+
report_string = f"Hello, @{session_state.my_username}! You have {session_state.my_followers_count} followers and {session_state.my_following_count} followings so far."
|
|
229
|
+
logger.info(report_string, extra={"color": f"{Style.BRIGHT}{Fore.GREEN}"})
|
|
230
|
+
if configs.args.repeat:
|
|
231
|
+
logger.info(
|
|
232
|
+
f"You have {total_sessions + 1 - len(sessions) if total_sessions > 0 else 'infinite'} session(s) left. You can stop the bot by pressing CTRL+C in console.",
|
|
233
|
+
extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
|
|
234
|
+
)
|
|
235
|
+
sleep(3)
|
|
236
|
+
if configs.args.shuffle_jobs:
|
|
237
|
+
jobs_list = random.sample(configs.enabled, len(configs.enabled))
|
|
238
|
+
else:
|
|
239
|
+
jobs_list = configs.enabled
|
|
240
|
+
|
|
241
|
+
if "analytics" in jobs_list:
|
|
242
|
+
jobs_list.remove("analytics")
|
|
243
|
+
if configs.args.analytics:
|
|
244
|
+
analytics_at_end = True
|
|
245
|
+
if "telegram-reports" in jobs_list:
|
|
246
|
+
jobs_list.remove("telegram-reports")
|
|
247
|
+
if configs.args.telegram_reports:
|
|
248
|
+
telegram_reports_at_end = True
|
|
249
|
+
print_limits = True
|
|
250
|
+
unfollow_jobs = [x for x in jobs_list if "unfollow" in x]
|
|
251
|
+
logger.info(
|
|
252
|
+
f"There is/are {len(jobs_list)-len(unfollow_jobs)} active-job(s) and {len(unfollow_jobs)} unfollow-job(s) scheduled for this session."
|
|
253
|
+
)
|
|
254
|
+
storage = Storage(session_state.my_username)
|
|
255
|
+
filters = Filter(storage)
|
|
256
|
+
show_ending_conditions()
|
|
257
|
+
if not configs.args.debug:
|
|
258
|
+
countdown(10, "Bot will start in: ")
|
|
259
|
+
for plugin in jobs_list:
|
|
260
|
+
inside_working_hours, time_left = SessionState.inside_working_hours(
|
|
261
|
+
configs.args.working_hours, configs.args.time_delta_session
|
|
262
|
+
)
|
|
263
|
+
if not inside_working_hours:
|
|
264
|
+
logger.info(
|
|
265
|
+
"Outside of working hours. Ending session.",
|
|
266
|
+
extra={"color": f"{Fore.CYAN}"},
|
|
267
|
+
)
|
|
268
|
+
break
|
|
269
|
+
(
|
|
270
|
+
active_limits_reached,
|
|
271
|
+
unfollow_limit_reached,
|
|
272
|
+
actions_limit_reached,
|
|
273
|
+
) = session_state.check_limit(
|
|
274
|
+
limit_type=session_state.Limit.ALL, output=print_limits
|
|
275
|
+
)
|
|
276
|
+
if actions_limit_reached:
|
|
277
|
+
logger.info(
|
|
278
|
+
"At last one of these limits has been reached: interactions/successful or scraped. Ending session.",
|
|
279
|
+
extra={"color": f"{Fore.CYAN}"},
|
|
280
|
+
)
|
|
281
|
+
break
|
|
282
|
+
if profile_view.getUsername() != session_state.my_username:
|
|
283
|
+
logger.debug("Not in your main profile.")
|
|
284
|
+
tab_bar_view.navigateToProfile()
|
|
285
|
+
if plugin in unfollow_jobs:
|
|
286
|
+
if configs.args.scrape_to_file is not None:
|
|
287
|
+
logger.warning(
|
|
288
|
+
"Scraping in unfollow-jobs doesn't make any sense. SKIP. "
|
|
289
|
+
)
|
|
290
|
+
continue
|
|
291
|
+
if unfollow_limit_reached:
|
|
292
|
+
logger.warning(
|
|
293
|
+
f"Can't perform {plugin} job because the unfollow limit has been reached. SKIP."
|
|
294
|
+
)
|
|
295
|
+
print_limits = None
|
|
296
|
+
continue
|
|
297
|
+
logger.info(
|
|
298
|
+
f"Current unfollow-job: {plugin}",
|
|
299
|
+
extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
|
|
300
|
+
)
|
|
301
|
+
configs.actions[plugin].run(
|
|
302
|
+
device, configs, storage, sessions, filters, plugin
|
|
303
|
+
)
|
|
304
|
+
unfollow_jobs.remove(plugin)
|
|
305
|
+
print_limits = True
|
|
306
|
+
else:
|
|
307
|
+
if active_limits_reached:
|
|
308
|
+
logger.warning(
|
|
309
|
+
f"Can't perform {plugin} job because a limit for active-jobs has been reached."
|
|
310
|
+
)
|
|
311
|
+
print_limits = None
|
|
312
|
+
if unfollow_jobs:
|
|
313
|
+
continue
|
|
314
|
+
else:
|
|
315
|
+
logger.info(
|
|
316
|
+
"No other jobs can be done cause of limit reached. Ending session.",
|
|
317
|
+
extra={"color": f"{Fore.CYAN}"},
|
|
318
|
+
)
|
|
319
|
+
break
|
|
320
|
+
|
|
321
|
+
logger.info(
|
|
322
|
+
f"Current active-job: {plugin}",
|
|
323
|
+
extra={"color": f"{Style.BRIGHT}{Fore.BLUE}"},
|
|
324
|
+
)
|
|
325
|
+
if configs.args.scrape_to_file is not None:
|
|
326
|
+
logger.warning(
|
|
327
|
+
"You're in scraping mode! That means you're only collection data without interacting!"
|
|
328
|
+
)
|
|
329
|
+
configs.actions[plugin].run(
|
|
330
|
+
device, configs, storage, sessions, filters, plugin
|
|
331
|
+
)
|
|
332
|
+
print_limits = True
|
|
333
|
+
|
|
334
|
+
# save the session in sessions.json
|
|
335
|
+
session_state.finishTime = datetime.now()
|
|
336
|
+
sessions.persist(directory=session_state.my_username)
|
|
337
|
+
|
|
338
|
+
# print reports
|
|
339
|
+
if telegram_reports_at_end:
|
|
340
|
+
logger.info("Going back to your profile..")
|
|
341
|
+
profile_view.click_on_avatar()
|
|
342
|
+
if profile_view.getFollowingCount() is None:
|
|
343
|
+
profile_view.click_on_avatar()
|
|
344
|
+
account_view.refresh_account()
|
|
345
|
+
(
|
|
346
|
+
_,
|
|
347
|
+
_,
|
|
348
|
+
followers_now,
|
|
349
|
+
following_now,
|
|
350
|
+
) = profile_view.getProfileInfo()
|
|
351
|
+
|
|
352
|
+
if analytics_at_end:
|
|
353
|
+
configs.actions["analytics"].run(
|
|
354
|
+
device, configs, storage, sessions, "analytics"
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
# turn off bot
|
|
358
|
+
close_instagram(device)
|
|
359
|
+
if configs.args.screen_sleep:
|
|
360
|
+
device.screen_off()
|
|
361
|
+
logger.info("Screen turned off for sleeping time.")
|
|
362
|
+
|
|
363
|
+
if configs.args.kill_atx_agent:
|
|
364
|
+
kill_atx_agent(device)
|
|
365
|
+
head_up_notifications(enabled=True)
|
|
366
|
+
logger.info(
|
|
367
|
+
"-------- FINISH: "
|
|
368
|
+
+ str(session_state.finishTime.strftime("%H:%M:%S - %Y/%m/%d"))
|
|
369
|
+
+ " --------",
|
|
370
|
+
extra={"color": f"{Style.BRIGHT}{Fore.YELLOW}"},
|
|
371
|
+
)
|
|
372
|
+
pre_post_script(pre=False, path=configs.args.post_script)
|
|
373
|
+
|
|
374
|
+
if configs.args.repeat and can_repeat(len(sessions), total_sessions):
|
|
375
|
+
print_full_report(sessions, configs.args.scrape_to_file)
|
|
376
|
+
inside_working_hours, time_left = SessionState.inside_working_hours(
|
|
377
|
+
configs.args.working_hours, configs.args.time_delta_session
|
|
378
|
+
)
|
|
379
|
+
if inside_working_hours:
|
|
380
|
+
time_left = (
|
|
381
|
+
get_value(configs.args.repeat, "Sleep for {} minutes.", 180) * 60
|
|
382
|
+
)
|
|
383
|
+
print_telegram_reports(
|
|
384
|
+
configs,
|
|
385
|
+
telegram_reports_at_end,
|
|
386
|
+
followers_now,
|
|
387
|
+
following_now,
|
|
388
|
+
time_left,
|
|
389
|
+
)
|
|
390
|
+
logger.info(
|
|
391
|
+
f'Next session will start at: {(datetime.now() + timedelta(seconds=time_left)).strftime("%H:%M:%S (%Y/%m/%d)")}.'
|
|
392
|
+
)
|
|
393
|
+
try:
|
|
394
|
+
sleep(time_left)
|
|
395
|
+
except KeyboardInterrupt:
|
|
396
|
+
stop_bot(
|
|
397
|
+
device,
|
|
398
|
+
sessions,
|
|
399
|
+
session_state,
|
|
400
|
+
was_sleeping=True,
|
|
401
|
+
)
|
|
402
|
+
else:
|
|
403
|
+
print_telegram_reports(
|
|
404
|
+
configs,
|
|
405
|
+
telegram_reports_at_end,
|
|
406
|
+
followers_now,
|
|
407
|
+
following_now,
|
|
408
|
+
time_left.total_seconds(),
|
|
409
|
+
)
|
|
410
|
+
wait_for_next_session(
|
|
411
|
+
time_left,
|
|
412
|
+
session_state,
|
|
413
|
+
sessions,
|
|
414
|
+
device,
|
|
415
|
+
)
|
|
416
|
+
else:
|
|
417
|
+
break
|
|
418
|
+
print_telegram_reports(
|
|
419
|
+
configs,
|
|
420
|
+
telegram_reports_at_end,
|
|
421
|
+
followers_now,
|
|
422
|
+
following_now,
|
|
423
|
+
)
|
|
424
|
+
print_full_report(sessions, configs.args.scrape_to_file)
|
|
425
|
+
ask_for_a_donation()
|