forked from TeamUltroid/Ultroid
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdater.py
More file actions
178 lines (168 loc) · 6.28 KB
/
updater.py
File metadata and controls
178 lines (168 loc) · 6.28 KB
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# Ultroid - UserBot
# Copyright (C) 2020 TeamUltroid
#
# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
# PLease read the GNU Affero General Public License in
# <https://www.github.com/TeamUltroid/Ultroid/blob/main/LICENSE/>.
import asyncio
import sys
from os import environ, execle, path, remove
from git import Repo
from git.exc import GitCommandError, InvalidGitRepositoryError, NoSuchPathError
UPSTREAM_REPO_URL = "https://github.com/TeamUltroid/Ultroid"
requirements_path = path.join(
path.dirname(path.dirname(path.dirname(__file__))), "requirements.txt"
)
async def gen_chlog(repo, diff):
ch_log = ""
d_form = "On %d/%m/%y at %H:%M:%S"
for c in repo.iter_commits(diff):
ch_log += f"**#{c.count()}** : {c.committed_datetime.strftime(d_form)} : [{c.summary}]({UPSTREAM_REPO_URL.rstrip('/')}/commit/{c}) by `{c.author}`\n"
return ch_log
async def updateme_requirements():
reqs = str(requirements_path)
try:
process = await asyncio.create_subprocess_shell(
" ".join([sys.executable, "-m", "pip", "install", "-r", reqs]),
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
await process.communicate()
return process.returncode
except Exception as e:
return repr(e)
@ultroid_cmd(
pattern="update ?(.*)",
)
async def upstream(ups):
pagal = await eor(ups, "`Checking for updates, please wait....`")
conf = ups.pattern_match.group(1)
off_repo = UPSTREAM_REPO_URL
try:
txt = "`Oops.. Updater cannot continue due to "
txt += "some problems occured`\n\n**LOGTRACE:**\n"
repo = Repo()
except NoSuchPathError as error:
await eod(pagal, f"{txt}\n`directory {error} is not found`", time=10)
repo.__del__()
return
except GitCommandError as error:
await eod(pagal, f"{txt}\n`Early failure! {error}`", time=10)
repo.__del__()
return
except InvalidGitRepositoryError as error:
if conf != "now":
await eod(
pagal,
f"**Unfortunately, the directory {error} does not seem to be a git repository.Or Maybe it just needs a sync verification with {GIT_REPO_NAME} But we can fix that by force updating the userbot using** `.update now.`",
time=30,
)
return
repo = Repo.init()
origin = repo.create_remote("upstream", off_repo)
origin.fetch()
repo.create_head("main", origin.refs.main)
repo.heads.main.set_tracking_branch(origin.refs.main)
repo.heads.main.checkout(True)
ac_br = repo.active_branch.name
if ac_br != "main":
await eod(
pagal,
f"**[UPDATER]:**` You are on ({ac_br})\n Please change to main branch.`",
)
repo.__del__()
return
try:
repo.create_remote("upstream", off_repo)
except BaseException:
pass
ups_rem = repo.remote("upstream")
ups_rem.fetch(ac_br)
changelog = await gen_chlog(repo, f"HEAD..upstream/{ac_br}")
if "now" not in conf:
if changelog:
changelog_str = f"**New UPDATE available for [[{ac_br}]]({UPSTREAM_REPO_URL}/tree/{ac_br}):\n\nCHANGELOG**\n\n{changelog}"
if len(changelog_str) > 4096:
await eor(pagal, "`Changelog is too big, view the file to see it.`")
file = open("output.txt", "w+")
file.write(changelog_str)
file.close()
await ups.client.send_file(
ups.chat_id,
"output.txt",
caption=f"Do `{hndlr}update now` to update.",
reply_to=ups.id,
)
remove("output.txt")
else:
return await eod(
pagal, f"{changelog_str}\n\nDo `{hndlr}update now` to update."
)
else:
await eod(
pagal,
f"\n`Your BOT is` **up-to-date** `with` **[[{ac_br}]]({UPSTREAM_REPO_URL}/tree/{ac_br})**\n",
time=10,
)
repo.__del__()
return
if Var.HEROKU_API is not None:
import heroku3
heroku = heroku3.from_key(Var.HEROKU_API)
heroku_app = None
heroku_applications = heroku.apps()
if not Var.HEROKU_APP_NAME:
await eod(
pagal,
"`Please set up the HEROKU_APP_NAME variable to be able to update userbot.`",
time=10,
)
repo.__del__()
return
for app in heroku_applications:
if app.name == Var.HEROKU_APP_NAME:
heroku_app = app
break
if heroku_app is None:
await eod(
pagal,
f"{txt}\n`Invalid Heroku credentials for updating userbot dyno.`",
time=10,
)
repo.__del__()
return
await eor(
pagal, "`Userbot dyno build in progress, please wait for it to complete.`"
)
ups_rem.fetch(ac_br)
repo.git.reset("--hard", "FETCH_HEAD")
heroku_git_url = heroku_app.git_url.replace(
"https://", "https://api:" + Var.HEROKU_API + "@"
)
if "heroku" in repo.remotes:
remote = repo.remote("heroku")
remote.set_url(heroku_git_url)
else:
remote = repo.create_remote("heroku", heroku_git_url)
try:
remote.push(refspec=f"HEAD:refs/heads/{ac_br}", force=True)
except GitCommandError as error:
await eod(pagal, f"{txt}\n`Here is the error log:\n{error}`", time=10)
repo.__del__()
return
await eod(pagal, "`Successfully Updated!\nRestarting, please wait...`", time=60)
else:
# Classic Updater, pretty straightforward.
try:
ups_rem.pull(ac_br)
except GitCommandError:
repo.git.reset("--hard", "FETCH_HEAD")
await updateme_requirements()
await eod(
pagal,
"`Successfully Updated!\nBot is restarting... Wait for a second!`",
)
# Spin a new instance of bot
args = [sys.executable, "./resources/startup/deploy.sh"]
execle(sys.executable, *args, environ)
return