-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathclonerbot.py
162 lines (132 loc) · 4.58 KB
/
clonerbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import subprocess
import threading
import re
import os
from time import sleep, monotonic
from telegram import Update, ParseMode
from telegram.constants import MAX_MESSAGE_LENGTH
from telegram.error import TimedOut, BadRequest, RetryAfter
from telegram.ext import Updater, CommandHandler, CallbackContext, run_async
import config
TOKEN = config.BOT_TOKEN
updater = Updater(TOKEN, use_context=True)
dp = updater.dispatcher
threads = threading.BoundedSemaphore(1)
allowed_chats = config.ALLOWED_CHATS
queue = []
@run_async
def clone(update: Update, context: CallbackContext):
chat_id = str(update.effective_chat.id)
user_id = str(update.message.from_user.id)
bot = context.bot
if chat_id not in allowed_chats:
return
args = context.args
source = args[0]
dest = args[1]
try:
thread_amount = args[2]
except IndexError:
thread_amount = 25
try:
view = args[3]
except IndexError:
view = 0
try:
skip = args[4]
except IndexError:
skip = None
start_time = monotonic()
counter = 0
bot.sendMessage(update.effective_chat.id, f"Added {source} -> {dest} to queue")
queue.append({
"source" : source,
"dest" : dest,
"user" : user_id,
"threads" : thread_amount
})
threads.acquire()
sleep(3)
bot.sendMessage(update.effective_chat.id, "Started", timeout=5)
if 'DYNO' in os.environ:
if skip:
cmd = f"python3 folderclone.py -s {source} -d {dest} -t {thread_amount} --view {view} --skip {skip}"
else:
cmd = f"python3 folderclone.py -s {source} -d {dest} -t {thread_amount} --view {view}"
else:
if skip:
cmd = f"py folderclone.py -s {source} -d {dest} -t {thread_amount} --view {view} --skip {skip}"
else:
cmd = f"py folderclone.py -s {source} -d {dest} -t {thread_amount} --view {view}"
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, universal_newlines=True)
message = None
to_edit_bool = True
to_send = ""
for line in proc.stdout:
counter = int(monotonic() - start_time)
if len(to_send) >= MAX_MESSAGE_LENGTH:
to_edit_bool = False
to_send = ""
original = re.escape(line.rsplit("-", 1)[0])
try:
percent_update = line.rsplit("-", 1)[1].strip()
except IndexError:
percent_update = ""
regex = f"({original})-.*"
subst = f"\\1- {percent_update}"
new_to_send, success = re.subn(regex, subst, to_send, flags=re.MULTILINE)
if success:
to_send = new_to_send
else:
to_send += f"{line}"
to_send = to_send.replace("\n\n", "\n")
if "BoundedSemaphore" in to_send:
try:
to_send = to_send.split("threads\n")[1]
except IndexError:
to_send = ""
print(repr(line))
if counter == 0:
continue
try:
if message:
if not to_edit_bool:
to_edit_bool = True
message = bot.sendMessage(update.effective_chat.id, to_send)
else:
message = message.edit_text(to_send)
else:
message = bot.sendMessage(update.effective_chat.id, to_send)
except (TimedOut, RetryAfter, BadRequest):
print(to_send)
counter = 0
start_time = monotonic()
proc.stdout.flush()
bot.sendMessage(update.effective_chat.id, "Done")
sleep(10)
queue.pop(0)
threads.release()
@run_async
def status(update: Update, context: CallbackContext):
chat_id = str(update.effective_chat.id)
if chat_id not in allowed_chats:
return
message = ""
if not queue:
update.message.reply_text("No jobs currently running.")
return
for each_entry_num, each_entry in enumerate(queue):
source = each_entry['source']
dest = each_entry['dest']
user = each_entry['user']
thread_used = each_entry['threads']
if each_entry_num == 0:
message += f"Current Job - From `{source}` to `{dest}` started by `{user}`\nTotal thread used : `{thread_used}`\n\n"
else:
message += f"Queue {each_entry_num} - From `{source}` to `{dest}` started by `{user}`\nTotal thread to use : `{thread_used}`\n\n"
update.message.reply_text(message, parse_mode=ParseMode.MARKDOWN)
dp.add_handler(CommandHandler('folderclone', clone))
dp.add_handler(CommandHandler('status', status))
print("Bot Started.")
updater.start_polling()
updater.idle()