22#
33# Licensed under the Raphielscape Public License, Version 1.c (the "License");
44# you may not use this file except in compliance with the License.
5+ # credits to @AvinashReddy3108
56#
67"""
78This module updates the userbot based on Upstream revision
89"""
910
10- from os import remove , execl
11+ from os import remove , execle , path , makedirs , getenv , environ
12+ from shutil import rmtree
13+ import asyncio
1114import sys
1215
1316from git import Repo
1417from git .exc import GitCommandError , InvalidGitRepositoryError , NoSuchPathError
1518
16- from userbot import CMD_HELP , bot , HEROKU_MEMEZ , HEROKU_APIKEY , HEROKU_APPNAME
19+ from userbot import CMD_HELP , bot , HEROKU_APIKEY , HEROKU_APPNAME , UPSTREAM_REPO_URL
1720from userbot .events import register
1821
22+ requirements_path = path .join (
23+ path .dirname (path .dirname (path .dirname (__file__ ))), 'requirements.txt' )
24+
1925
2026async def gen_chlog (repo , diff ):
2127 ch_log = ''
@@ -25,47 +31,62 @@ async def gen_chlog(repo, diff):
2531 return ch_log
2632
2733
28- async def is_off_br (br ):
29- off_br = ['sql-extended' ]
30- for k in off_br :
31- if k == br :
32- return 1
33- return
34+ async def update_requirements ():
35+ reqs = str (requirements_path )
36+ try :
37+ process = await asyncio .create_subprocess_shell (
38+ ' ' .join ([sys .executable , "-m" , "pip" , "install" , "-r" , reqs ]),
39+ stdout = asyncio .subprocess .PIPE ,
40+ stderr = asyncio .subprocess .PIPE )
41+ await process .communicate ()
42+ return process .returncode
43+ except Exception as e :
44+ return repr (e )
3445
3546
36- @register (outgoing = True , pattern = "^.update(?: |$)(.*)" )
47+ @register (outgoing = True , pattern = "^\ .update(?: |$)(.*)" )
3748async def upstream (ups ):
3849 "For .update command, check if the bot is up to date, update if specified"
3950 await ups .edit ("`Checking for updates, please wait....`" )
40- conf = ups .pattern_match .group (1 ).lower ()
41- off_repo = 'https://github.com/MoveAngel/One4uBot.git'
51+ conf = ups .pattern_match .group (1 )
52+ off_repo = UPSTREAM_REPO_URL
53+ force_update = False
4254
4355 try :
44- txt = "`Oops.. Updater cannot continue due to some problems occured`\n \n **LOGTRACE:**\n "
56+ txt = "`Oops.. Updater cannot continue due to "
57+ txt += "some problems occured`\n \n **LOGTRACE:**\n "
4558 repo = Repo ()
4659 except NoSuchPathError as error :
4760 await ups .edit (f'{ txt } \n `directory { error } is not found`' )
61+ repo .__del__ ()
4862 return
4963 except GitCommandError as error :
5064 await ups .edit (f'{ txt } \n `Early failure! { error } `' )
65+ repo .__del__ ()
5166 return
52- except InvalidGitRepositoryError :
67+ except InvalidGitRepositoryError as error :
68+ if conf != "now" :
69+ await ups .edit (
70+ f"`Unfortunately, the directory { error } does not seem to be a git repository.\
71+ \n But we can fix that by force updating the userbot using .update now.`"
72+ )
73+ return
5374 repo = Repo .init ()
54- await ups .edit (
55- "`Warning: Force-Syncing to the latest stable code from repo.`\
56- \n I may lose my downloaded files during this update."
57- )
5875 origin = repo .create_remote ('upstream' , off_repo )
5976 origin .fetch ()
60- repo .create_head ('sql-extended' , origin .refs .master )
61- repo .heads .master .checkout (True )
77+ force_update = True
78+ repo .create_head ('sql-extended' , origin .refs .sql - extended )
79+ repo .heads .sql - extended .set_tracking_branch (origin .refs .sql - extended )
80+ repo .heads .sql - extended .checkout (True )
6281
6382 ac_br = repo .active_branch .name
64- if not await is_off_br ( ac_br ) :
83+ if ac_br != 'sql-extended' :
6584 await ups .edit (
66- f'**[UPDATER]:**` Looks like you are using your own custom branch ({ ac_br } ). \
67- in that case, Updater is unable to identify which branch is to be merged. \
68- please checkout to any official branch`' )
85+ f'**[UPDATER]:**` Looks like you are using your own custom branch ({ ac_br } ). '
86+ 'in that case, Updater is unable to identify '
87+ 'which branch is to be merged. '
88+ 'please checkout to any official branch`' )
89+ repo .__del__ ()
6990 return
7091
7192 try :
@@ -75,16 +96,19 @@ async def upstream(ups):
7596
7697 ups_rem = repo .remote ('upstream' )
7798 ups_rem .fetch (ac_br )
99+
78100 changelog = await gen_chlog (repo , f'HEAD..upstream/{ ac_br } ' )
79101
80- if not changelog :
81- await ups .edit (f'\n `Your BOT is` **up-to-date** `with` **{ ac_br } **\n ' )
102+ if not changelog and not force_update :
103+ await ups .edit (
104+ f'\n `Your BOT is` **up-to-date** `with` **{ ac_br } **\n ' )
105+ repo .__del__ ()
82106 return
83107
84- if conf != "now" :
108+ if conf != "now" and not force_update :
85109 changelog_str = f'**New UPDATE available for [{ ac_br } ]:\n \n CHANGELOG:**\n `{ changelog } `'
86110 if len (changelog_str ) > 4096 :
87- await ups .edit ("`Changelog is too big, sending it as a file .`" )
111+ await ups .edit ("`Changelog is too big, view the file to see it .`" )
88112 file = open ("output.txt" , "w+" )
89113 file .write (changelog_str )
90114 file .close ()
@@ -96,20 +120,69 @@ async def upstream(ups):
96120 remove ("output.txt" )
97121 else :
98122 await ups .edit (changelog_str )
99- await ups .respond (
100- "`do \" .update now\" to update\n Don't if using Heroku`" )
123+ await ups .respond ('`do \" .update now\" to update`' )
101124 return
102125
103- await ups .edit ('`New update found, updating...`' )
104- ups_rem .fetch (ac_br )
105- await ups .edit ('`Successfully Updated!\n '
106- 'Bot is restarting... Wait for a second!`' )
107- await install_requirements ()
108- await bot .disconnect ()
109- # Spin a new instance of bot
110- execl (sys .executable , sys .executable , * sys .argv )
111- # Shut the existing one down
112- exit ()
126+ if force_update :
127+ await ups .edit (
128+ '`Force-Syncing to latest stable userbot code, please wait...`' )
129+ else :
130+ await ups .edit ('`Updating userbot, please wait....`' )
131+ # We're in a Heroku Dyno, handle it's memez.
132+ if HEROKU_APIKEY is not None :
133+ import heroku3
134+ heroku = heroku3 .from_key (HEROKU_APIKEY )
135+ heroku_app = None
136+ heroku_applications = heroku .apps ()
137+ if not HEROKU_APPNAME :
138+ await ups .edit (
139+ '`[HEROKU MEMEZ] Please set up the HEROKU_APPNAME variable to be able to update userbot.`'
140+ )
141+ repo .__del__ ()
142+ return
143+ for app in heroku_applications :
144+ if app .name == HEROKU_APPNAME :
145+ heroku_app = app
146+ break
147+ if heroku_app is None :
148+ await ups .edit (
149+ f'{ txt } \n `Invalid Heroku credentials for updating userbot dyno.`'
150+ )
151+ repo .__del__ ()
152+ return
153+ await ups .edit ('`[HEROKU MEMEZ]\
154+ \n Userbot dyno build in progress, please wait for it to complete.`'
155+ )
156+ ups_rem .fetch (ac_br )
157+ repo .git .reset ("--hard" , "FETCH_HEAD" )
158+ heroku_git_url = heroku_app .git_url .replace (
159+ "https://" , "https://api:" + HEROKU_APIKEY + "@" )
160+ if "heroku" in repo .remotes :
161+ remote = repo .remote ("heroku" )
162+ remote .set_url (heroku_git_url )
163+ else :
164+ remote = repo .create_remote ("heroku" , heroku_git_url )
165+ try :
166+ remote .push (refspec = "HEAD:refs/heads/sql-extended" , force = True )
167+ except GitCommandError as error :
168+ await ups .edit (f'{ txt } \n `Here is the error log:\n { error } `' )
169+ repo .__del__ ()
170+ return
171+ await ups .edit ('`Successfully Updated!\n '
172+ 'Restarting, please wait...`' )
173+ else :
174+ # Classic Updater, pretty straightforward.
175+ try :
176+ ups_rem .pull (ac_br )
177+ except GitCommandError :
178+ repo .git .reset ("--hard" , "FETCH_HEAD" )
179+ reqs_upgrade = await update_requirements ()
180+ await ups .edit ('`Successfully Updated!\n '
181+ 'Bot is restarting... Wait for a second!`' )
182+ # Spin a new instance of bot
183+ args = [sys .executable , "-m" , "userbot" ]
184+ execle (sys .executable , * args , environ )
185+ return
113186
114187
115188CMD_HELP .update ({
@@ -118,4 +191,4 @@ async def upstream(ups):
118191\n Usage: Checks if the main userbot repository has any updates and shows a changelog if so.\
119192\n \n .update now\
120193\n Usage: Updates your userbot, if there are any updates in the main userbot repository."
121- })
194+ })
0 commit comments