From 66d0617299f9ac98dafc67995a5eccb141ab4969 Mon Sep 17 00:00:00 2001 From: EmaMaker Date: Fri, 27 Aug 2021 22:25:57 +0200 Subject: [PATCH] [SQUASHED] Use of Global Vars, fix bash scripts to properly use Xephyr --- .gitignore | 5 +- misc/qwiklabs_accounts.txt | 19 +-- src/colab/__pycache__/colab.cpython-39.pyc | Bin 4317 -> 5217 bytes src/colab/colab.py | 98 +++++++------ src/colab_automator.sh | 8 +- src/main.py | 13 +- src/ngrok/__pycache__/ngrok.cpython-39.pyc | Bin 1925 -> 1815 bytes src/ngrok/ngrok.py | 16 --- .../__pycache__/account_list.cpython-39.pyc | Bin 1990 -> 2465 bytes src/qwiklabs/account_list.py | 23 +-- src/qwiklabs/create_account.py | 19 ++- src/qwiklabs/delete_account.py | 5 +- src/qwiklabs/get_account.py | 132 ++++++++++++++---- src/qwiklabs/get_account.sh | 16 ++- .../browser_manager.cpython-39.pyc | Bin 2697 -> 2741 bytes src/utils/browser_manager.py | 8 +- src/utils/change_mac.sh | 0 src/utils/global_vars.py | 4 + src/utils/gui.py | 44 ------ src/utils/proxy.py | 51 +++++++ 20 files changed, 285 insertions(+), 176 deletions(-) mode change 100644 => 100755 src/colab_automator.sh mode change 100644 => 100755 src/utils/change_mac.sh create mode 100644 src/utils/global_vars.py delete mode 100644 src/utils/gui.py create mode 100644 src/utils/proxy.py diff --git a/.gitignore b/.gitignore index 92f5ffe..e9f213e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ -__pycache__/ +**/__pycache__/ chrome-profile/ misc/ -chromedriver \ No newline at end of file +chromedriver +bash-test.sh \ No newline at end of file diff --git a/misc/qwiklabs_accounts.txt b/misc/qwiklabs_accounts.txt index 97f8427..a35c4f5 100644 --- a/misc/qwiklabs_accounts.txt +++ b/misc/qwiklabs_accounts.txt @@ -1,5 +1,3 @@ -# '!' before an email address means it still needs to be activated. Password is 'hellogoodbye' when not specified - 06prgzamm96@esiix.com jhv8mtemi@esiix.com 6bgfngq6@yoggm.com @@ -7,13 +5,10 @@ fohxil@xojxe.com b4d0o0y5pg@esiix.com i3z8qtab@xojxe.com l5wbup@1secmail.com - -! ryysw0@1secmail.net -! m5l7868ar@wwjmp.com -! m5i8g3@1secmail.com -! ue8oqa0lf0j@1secmail.net -! 17k2l9@1secmail.com -! 08hyvaejbr@xojxe.com -! c5xm6j@1secmail.net -! mud0ud@esiix.com -! t788egrvdp@wwjmp.com \ No newline at end of file +ryysw0@1secmail.net +m5l7868ar@wwjmp.com +ue8oqa0lf0j@1secmail.net +17k2l9@1secmail.com +c5xm6j@1secmail.net +mud0ud@esiix.com +t788egrvdp@wwjmp.com \ No newline at end of file diff --git a/src/colab/__pycache__/colab.cpython-39.pyc b/src/colab/__pycache__/colab.cpython-39.pyc index 86a506ad0fcd71aa92dc35dc5cf2e95136fc97be..46aa1bb6134bbc916e816aff44feeb94e40aeca5 100644 GIT binary patch literal 5217 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 delta 2113 zcmaJ?J!~UI6rR~#uV;V!@5BjrN^-f26X))t933L$fN&RtAc{z&11pkoJexZ^$vQW? z5sBqsi3=S?qLpZ9>@tGxXy_=YXptyZqM)HcP|zV7-Ww;e6ItwPzL|aR&6}C;y?yiB z%&)iND|{xC|M?4=h0)rqYita77ebgkpesY@_vhk`ua2B zlz9aw_CG3oya~sZ!r5Z=O++z}YyV3n>_dDj4K~ueI4=Dm|&o zSxRs(GCrBTw39Q?SY!ZRf#zudB&bJTZT$d)#nV*ZO7eubHYNCeOk8Ci zzPY(3zfr=iH8M|-|AM{p@+?Qaf7oIR z`M@B^n7<9tZ<03Y5HIfoDKCH&*gnwGfwe)SVUO!dDP%!SmxKT{DDjP&$(4(foJ%aO zN{QW$aqYTw3m8RKP$^wW$8qHOi1tZoI{}&`PH)1PN2R07Ss0tk4Rm=Ptm|&Br)%{l zTD%*Bp0cOAIMpDX#m%cn_}|UgZM#E`6kykCr<$ZyOUrX9NHv@nluc!XaQg;QoZcoU zipclLW82yZ6$gz~JZ(Dzgj+n`Q9$++xJ+CPn0u$sDk-i00;^P?)ds{9atk7=5kGsP z98OSj1OaJeefZGA(MrkYr|C-ye*Vms_y$P_X@4J5Rh4m5L4gR!T zIu>l(t5X=;s=B-co7;6<-wTaL2Nh?}uh!i#Xv<{$tcc51&!3ZPU2G~CPHt`70ly-TFoiG;P%uP~5m`l% zy20F_qE};kwR0X6`@!$Y#dW-(WT8mIz=yht`PIQoLd6v7mTs-P;xM|yf-i$52Gk^h zCas{JTAl4y@2=%6&KYEm?0p{motjLp6jTvKGY0UuUqv-$u diff --git a/src/colab/colab.py b/src/colab/colab.py index 6fef432..a55bd0d 100644 --- a/src/colab/colab.py +++ b/src/colab/colab.py @@ -2,7 +2,9 @@ from utils import browser_manager from selenium import webdriver from selenium.webdriver.common.by import By import time -from threading import Thread +from threading import Thread, Event + +from utils.global_vars import PROXY class ColabGist(Thread): @@ -13,21 +15,27 @@ class ColabGist(Thread): For future-proofness each Gist is started in its own thread, this makes possible to run multiple gists in different threads at the same time ''' - def __init__(self, url, account, minutes=40, backend='N', proxy=False): + def __init__(self, url, account, minutes=5, backend='N'): self.url = url self.account = account self.minutes = minutes self.backend = backend - self.proxy = proxy + + self.refresh_event = Event() + self.stop_event = Event() + print("[ColabGist {}] New Colab Gist Thread created!".format(self.url)) def run(self): self.run_colab() def run_colab(self): + print("[ColabGist {}] Starting the gist".format(self.url)) self.start_browser() self.start_session() def sign_in(self): + print("[ColabGist {}] Signing in...".format(self.url)) + try: self.driver.get("https://accounts.google.com/o/oauth2/v2/auth/oauthchooseaccount?redirect_uri=https%3A%2F%2Fdevelopers.google.com%2Foauthplayground&prompt=consent&response_type=code&client_id=407408718192.apps.googleusercontent.com&scope=email&access_type=offline&flowName=GeneralOAuthFlow") #need a fallback for when browser_manager.inputText(self.driver, By.CSS_SELECTOR, "#identifierId", self.account[0] + "\n") @@ -48,13 +56,51 @@ class ColabGist(Thread): # Run the desired Colab notebook. Logging into Google account by profile is mandatory def start_session(self): if not self.sign_in(): - print("Got the old login screen, trying again") + print("[ColabGist {}] Got the old login screen, trying again".format(self.url)) self.driver.quit() self.run_colab() return self.driver.get(self.url) + self.start_gist() + # Leave the colab be for the specified time + starting = time.time() + print("[ColabGist {}] Executing the gist for the next {} minutes. Using Backend {}".format(self.url, self.minutes, self.backend) ) + while (int(time.time() - starting))/60 < self.minutes: + + if self.stop_event.is_set(): + self.actual_quit() + if self.refresh_event.is_set(): + self.start_gist() + + if(int(time.time() - starting > 15)): + try: + if self.driver.find_elements(By.XPATH, "//*[contains(text(),'No backend')]"): + print("[ColabGist {}] This account {} has been blocked :/ try again with another one".format(self.url, self.account)) + self.driver.quit() + elif self.driver.find_elements(By.XPATH, "//*[contains(text(),'Cannot connect')]"): + print("[ColabGist {}] No backend was available, maybe the service is overflooded or this account/computer is about to be blocked :(".format(self.url)) + self.driver.quit() + return + except Exception as e: + print(e) + + '''char = input() + if char == "t": + break + elif char == "g": + elapsed = time()-starting + elapsed_min = int(elapsed / 60) + elapsed_sec = int(elapsed % 60) + print("Elapsed time: {}m{}s".format(elapsed_min, elapsed_sec)) + else: + print("Unrecognized option")''' + + print("[ColabGist {}] Time's up! Closing the browser".format(self.url)) + self.actual_quit() + + def start_gist(self): browser_manager.clickButton(self.driver, By.CSS_SELECTOR, "#runtime-menu-button") browser_manager.clickButton(self.driver, By.XPATH, '//*[@id=":24"]') @@ -80,39 +126,6 @@ class ColabGist(Thread): browser_manager.clickButton(self.driver, By.CSS_SELECTOR, "#ok") time.sleep(1.5) - # need a fallback for then it can't connect to the backend - - # Leave the colab be for the specified time - starting = time.time() - print("Executing the gist for the next {} minutes. Using Backend {}".format(self.minutes, self.backend) ) - while (time.time() - starting)/60 < self.minutes: - if(time.time() - starting > 15): - try: - if self.driver.find_elements(By.XPATH, "//*[contains(text(),'No backend')]"): - print("This account has been blocked :/ try again with another one") - self.driver.quit() - elif self.driver.find_elements(By.XPATH, "//*[contains(text(),'Cannot connect')]"): - print("No backend was available, maybe the service is overflooded or this account/computer is about to be blocked :(") - self.driver.quit() - return - except Exception as e: - print(e) - - '''char = input() - if char == "t": - break - elif char == "g": - elapsed = time()-starting - elapsed_min = int(elapsed / 60) - elapsed_sec = int(elapsed % 60) - print("Elapsed time: {}m{}s".format(elapsed_min, elapsed_sec)) - else: - print("Unrecognized option")''' - - print("Time's up! Closing the browser") - - self.terminate_session() - self.stop_browser() def terminate_session(): # Terminate the session @@ -125,8 +138,15 @@ class ColabGist(Thread): time.sleep(60) def start_browser(self): - self.driver=browser_manager.start_browser(self.proxy) + self.driver=browser_manager.start_browser() def stop_browser(self): # Close browser - self.driver.quit() \ No newline at end of file + self.driver.quit() + + def actual_quit(self): + self.terminate_session() + self.stop_browser() + + def quit(self): + self.stop_event.set() \ No newline at end of file diff --git a/src/colab_automator.sh b/src/colab_automator.sh old mode 100644 new mode 100755 index 3a0c41e..400f212 --- a/src/colab_automator.sh +++ b/src/colab_automator.sh @@ -9,8 +9,12 @@ pip install -r requirements.txt #Start xephyr window Xephyr -br -ac -noreset -screen 1280x720 :1 & +sleep 5 +DISPLAY=:1 Xephyr -br -ac -noreset -screen 800x600 :2 & +sleep 5 # Start a copyq server, that will be used to copy the email and password of the obtained account from the clipboard of Xephyr -# DISPLAY=:1 copyq & +DISPLAY=:2 copyq & +sleep 2 #Now start the actual bot, we're in a safe environment -DISPLAY=:1 python get_account_from_qwiklabs.py \ No newline at end of file +DISPLAY=:1 python src/main.py \ No newline at end of file diff --git a/src/main.py b/src/main.py index f11fb59..730b007 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,11 @@ -from qwiklabs import account_list +import subprocess +from utils import global_vars, proxy -ql_list = account_list.QL_AccountList('/home/emamaker/Documents/Projects/GColabAutomator/GColabAutomator-v2/src/qwiklabs_available_accounts.txt') -print(ql_list.request_new_account()) +print("[MAIN] Entering main script!") +p = proxy.Proxy() while True: - ql_list.update_account_list() - print(ql_list.suspended_list) \ No newline at end of file + p.request_new_proxy() + print(global_vars.PROXY) + + time.sleep(30) \ No newline at end of file diff --git a/src/ngrok/__pycache__/ngrok.cpython-39.pyc b/src/ngrok/__pycache__/ngrok.cpython-39.pyc index 45c03ad1350c8728162b1cca939207ff499a13d9..252caeee59e4722c0831ab5cd53e620794193299 100644 GIT binary patch delta 141 zcmZqWpU%gZ$ji&c00hrwY9v;%P2~F`!vy3x1934(yoRxcA)XZ)f4SGCh~o$X9n_|fw))#NTe{PFr_dzGo>?@FvK&~FxD`{ zGo>&DGib8-X);wwrDrDQrDx{k=w^mC2S-dGleWM~sYWo0qXt0C}7|GXMYp diff --git a/src/ngrok/ngrok.py b/src/ngrok/ngrok.py index ee80f16..f0e26aa 100644 --- a/src/ngrok/ngrok.py +++ b/src/ngrok/ngrok.py @@ -8,25 +8,9 @@ from selenium.webdriver.common.by import By import time from colab import colab -# def start_proxy_get_ip(): -# c = colab.ColabGist('https://colab.research.google.com/gist/EmaMaker/4e1478c9913a2df58fc1b8ff422fa161/proxy.ipynb', , minutes=3) -# c.run() - -# time.sleep(120) - -# n = Ngrok() -# n.start_browser() -# n.access_ngrok() - -# return n.get_proxy_ip() - class Ngrok: def __init__(self, account): - Ngrok.ACCOUNTS = [ - ('giangillo.rossi1@gmail.com', 'emamaker02') - ('giangillo.rossi2@gmail.com', 'emamaker02') - ] self.account = account def start_browser(self): diff --git a/src/qwiklabs/__pycache__/account_list.cpython-39.pyc b/src/qwiklabs/__pycache__/account_list.cpython-39.pyc index 45f04cee57c40ed1c604174d6a3290db5f7fb040..a57e13df3d1f89e9d0495cd8bb5db5494aa2b4e7 100644 GIT binary patch literal 2465 zcmaJ?QE%He5GE;ER&2*H+G0(+tyMdqsD~}?_E@w-f}|)4q+W-n2RFi4s$Wlzw z$?D2`N#D0$FxZcI+rQXvm|pkPzp$s>QMT(iX(jM@q{!p(?)y%`@^Xp5^Yrh#!9Sq= zi-Y;cg26g8bsGdHoJORT_q0VH6VABxj&SRQwHT+*N!@-A>qxVWa{gg3Scj&zKnT*J zoZt@5-jSBYEp9_^^8$CEFYqFFp?CNaFF{}AWnO{a<;%PZ{Sse+lWJM@r)__u-A?+k z-VT*+;~CQjbsO3yG_?+bQ%!t04 zo{yJw;&TxREizk&UD2vVfzp1^)?pI+W~MwhlNAnS80*a0OJq0Db(YymM0*k=c1mO! zy8nX4e$o{U(G9x6fsl=@q}}g|SgXb}nRG-Ol*gM%6ujE#>jaD>a&i3a(f17{+l}6F zcmV5EWBv+jhi@|1_ro~UzVE_;ss@5khdK-zyd`LZt7k*JHr>(23{0N_C}_eY`%h3b zq_RUfJz>B9Hl(k~5K=y3W3okFUK&~{8(FC}vd3f$$?aWFnJ$bRfJQN8CzM;OWX!IS zp`DVEo7!V4*CucP9pM1;Wt<1i-X#p+VZ(c3QGiKrZFg=Q*S;g_k9&lg_h*n3C}mU{ z481o%dUy^<8(usIrTsv8uY`y_DSCaO44~TkNuprt?XX_S>;%AIvX?CZ;&>FsLS;^H zh#1Knsk96ap$}r7bX!I2G5uB~;;a@bz=>gze-uO^ml#U91R`6Rz-+ppUXWNWTJB_n zYE`Ei;1JKWvCE2+S%aipRM6h#$pw74-PGn~_@FL?u?B|5mhko^m` zpJP3O!2sbdC>nS_qAAs^V~ruXlxQ20T^N%Sr~w@(r4RCyu;$>=`7BJR3^Y9sqX=@~ z&3NYlbv(TaN^kKpeizl2ZV-%WJNL2-e568G1k zO})AKac>Ns&y)(}+w8w^0|q%lG@DYp1BC%c6RH9(?tcmwGir7Nc_6q!g(<`#R$k!C zj7)j5&8-mab(%xqZ1%Iy(aw|_K42^_>&DtQc1RG7(jWP zVFU`~ogvcY*~dOT1ZW7dZ5GF3KUaZWj!Rl`&ioY3_1p362qHg z9&uxMAkEe7{OTqaNP&#G;%keG>`Q|dW k?5?=BYr$)qZ*?n=!jzesgWRhhFjywdE_JQ{0lmpi@Bjb+ delta 824 zcmZuv&ubGw6rMLb*=%C7O-)N%)M}|v)=&`yMG1mfdozfk2M@A_?kZ{1B+kqtLO`%* zQJISeg#^9i;=TWXc+&e^J@vovz1dbHy2F0VkMDi+z4vBZ`#Kx8E0r?CZ{yo~`+@&1 z{BfJ(>JI+uEJ6aB#V~{+i+P73dQS;O!dfii%_EA93X)>%Ol!M!|88^Be1^+&5w}96 z-6yhuM-wJXW|0rVA}&;bz`*Ce`N*$T-{L}}<}M^~z~2naPrfOJY*aEgyn6lB6$WlR zM0A&mrUfYhqmBrovK9S7+LHzI-P>BQvno@#Oyc&=PCx5uG#8kwV&i5B$z{11!fbA40=9nm{x1tk>yj zD|BZ+l|BkgxTG}YBEjER%LUv!gTJDxG4rW#Z%r=aEaEQIioNuOl2rZaNHgaz!-}c< z$)#iR3Nfgn|8Qw<9%0oS`i(6QXRe`?8aihq(0mMeJ@cErT!#qGas;{kDd*;O@k03` z5{_*j7T-T|MttX5o}*Yw%RL4uXhwRG$fcZ7Du;z+IxpI(WrL)x(~~~L-Hy`h=1cJS z QL_AccountList.ACTION_WAIT_TIME: - # TODO: add the requesting of a proxy when doing these actions + # if time.time() - self.last_action_time > QL_AccountList.ACTION_WAIT_TIME: + # # TODO: add the requesting of a proxy when doing these actions - if last_action == 0: - # removed an account from the "to delete" lsit - delete_account.QL_DeleteAccount(False, to_delete[random.randint(0, len(to_delete)-1)]) - else: - # otherwise create a new account - create_account.QL_CreateAccount(False) + # if last_action == 0: + # # removed an account from the "to delete" lsit + # delete_account.QL_DeleteAccount(False, to_delete[random.randint(0, len(to_delete)-1)]) + # else: + # # otherwise create a new account + # create_account.QL_CreateAccount(False) diff --git a/src/qwiklabs/create_account.py b/src/qwiklabs/create_account.py index a28b9b3..a1d1b9e 100644 --- a/src/qwiklabs/create_account.py +++ b/src/qwiklabs/create_account.py @@ -13,16 +13,15 @@ import pydub import speech_recognition as sr from bs4 import BeautifulSoup +from utils.global_vars import PROXY class QL_CreateAccount: - def __init__(self, proxy=False): - self.proxy = proxy def create_account(self): self.info = RandomNameGenerator(self.proxy).get_person_info() - self.driver = browser_manager.start_browser(self.proxy) - self.temp_mail = TempMail(self.proxy) + self.driver = browser_manager.start_browser() + self.temp_mail = TempMail() self.temp_mail_address = self.temp_mail.get_new_temp_mail() @@ -141,15 +140,14 @@ class QL_CreateAccount: class RandomNameGenerator(): - def __init__(self, proxy=False): - self.proxy = proxy + def __init__(self): self.proxyDict = { - "socks" : proxy, + "socks" : PROXY, "socksVersion" : 5 } def get_person_info(self): - if self.proxy: + if PROXY: r = requests.get('https://randomuser.me/api', proxies=self.proxyDict) else: r = requests.get('https://randomuser.me/api') @@ -162,10 +160,9 @@ class RandomNameGenerator(): # get a temp mail from https://www.1secmail.com/api/ and handle it using requests class TempMail: - def __init__(self, proxy=False): - self.proxy = proxy + def __init__(self): self.proxyDict = { - "socks" : proxy, + "socks" : PROXY, "socksVersion" : 5 } diff --git a/src/qwiklabs/delete_account.py b/src/qwiklabs/delete_account.py index ed12baa..b7c8cef 100644 --- a/src/qwiklabs/delete_account.py +++ b/src/qwiklabs/delete_account.py @@ -5,12 +5,11 @@ from selenium.webdriver.common.alert import Alert from selenium.webdriver.common.alert import Command class QL_DeleteAccount: - def __init__(self, proxy, account): - self.proxy = proxy + def __init__(self, account): self.account = account def delete_account(self): - self.driver = browser_manager.start_browser(self.proxy) + self.driver = browser_manager.start_browser() self.sign_in() self.delete() diff --git a/src/qwiklabs/get_account.py b/src/qwiklabs/get_account.py index e3f4145..1e6fe47 100644 --- a/src/qwiklabs/get_account.py +++ b/src/qwiklabs/get_account.py @@ -1,19 +1,61 @@ -import gui -import pyautogui -import time -import subprocess -def get_account(account_list): +class Gui: + def __init__(self, width, height): + Gui.chrome_gui = Chrome(width, height) + Gui.qwiklabs_gui = Qwiklabs(width, height) + +class Chrome(Gui): + SEARCH_BAR_PERCENTAGE = (0.5, 0.1) + + def __init__(self, width, height): + Chrome.SEARCH_BAR=width*Chrome.SEARCH_BAR_PERCENTAGE[0], height*Chrome.SEARCH_BAR_PERCENTAGE[1] + + def click_searchbar(self): + pyautogui.moveTo(Chrome.SEARCH_BAR[0], Chrome.SEARCH_BAR[1]) + pyautogui.click() + pyautogui.keyDown('ctrl') + pyautogui.press('a') + pyautogui.keyUp('ctrl') + + +class Qwiklabs(Gui): + JOIN_BTN_PERCENTAGE = (0.775, 0.183) + SIGN_IN_BTN_PERCENTAGE = (0.2125, 0.73) + EMAIL_TEXTBOX_PERCENTAGE = (0.5, 0.73) + COURSE_BTN_PERCENTAGE = (0.29, 0.45) + STARTLAB_BTN_PERCENTAGE = (0.125, 0.31) + CAPTCHA_BTN_PERCENTAGE = (0.075, 0.425) + EMAIL_COPY_BTN_PERCENTAGE = (0.3125, 0.7) + PASSWORD_COPY_BTN_PERCENTAGE = (0.3125, 0.82) + + def __init__(self, width, height): + Qwiklabs.JOIN_BTN=width*Qwiklabs.JOIN_BTN_PERCENTAGE[0], height*Qwiklabs.JOIN_BTN_PERCENTAGE[1] + Qwiklabs.SIGN_IN_BTN=width*Qwiklabs.SIGN_IN_BTN_PERCENTAGE[0], height*Qwiklabs.SIGN_IN_BTN_PERCENTAGE[1] + Qwiklabs.EMAIL_TEXTBOX=width*Qwiklabs.EMAIL_TEXTBOX_PERCENTAGE[0], height*Qwiklabs.EMAIL_TEXTBOX_PERCENTAGE[1] + Qwiklabs.COURSE_BTN=width*Qwiklabs.COURSE_BTN_PERCENTAGE[0], height*Qwiklabs.COURSE_BTN_PERCENTAGE[1] + Qwiklabs.STARTLAB_BTN=width*Qwiklabs.STARTLAB_BTN_PERCENTAGE[0], height*Qwiklabs.STARTLAB_BTN_PERCENTAGE[1] + Qwiklabs.CAPTCHA_BTN=width*Qwiklabs.CAPTCHA_BTN_PERCENTAGE[0], height*Qwiklabs.CAPTCHA_BTN_PERCENTAGE[1] + Qwiklabs.EMAIL_COPY_BTN=width*Qwiklabs.EMAIL_COPY_BTN_PERCENTAGE[0], height*Qwiklabs.EMAIL_COPY_BTN_PERCENTAGE[1] + Qwiklabs.PASSWORD_COPY_BTN=width*Qwiklabs.PASSWORD_COPY_BTN_PERCENTAGE[0], height*Qwiklabs.PASSWORD_COPY_BTN_PERCENTAGE[1] + +if __name__ == "__main__": + import time + import subprocess + import os + import pyautogui + import sys + import requests + pyautogui.FAILSAFE = False - + screenWidth, screenHeight = pyautogui.size() - ui = gui.Gui(screenWidth, screenHeight) + ui = Gui(screenWidth, screenHeight) - print("Screen is {} {}".format(screenWidth, screenHeight)) + # print("[QL_GetGAccount] Screen is {} {}".format(screenWidth, screenHeight)) - print("Accessing course on qwiklabs") + # print("[QL_GetGAccount] Accessing course on qwiklabs") # Head over to the course on qwiklabs.com - gui.Gui.chrome_gui.click_searchbar() + Gui.chrome_gui.click_searchbar() pyautogui.write("qwiklabs.com") pyautogui.press('/') pyautogui.write("focuses") @@ -27,7 +69,7 @@ def get_account(account_list): time.sleep(15) - print("Signing in") + # print("[QL_GetGAccount] Signing in") pyautogui.moveTo(0,0) # Click join button @@ -38,7 +80,7 @@ def get_account(account_list): # Move to the end of the page pyautogui.press('pgdn') - print("Moving from sign up to sign in") + # print("Moving from sign up to sign in") # switch to sign in button pyautogui.moveTo(ui.qwiklabs_gui.SIGN_IN_BTN[0], ui.qwiklabs_gui.SIGN_IN_BTN[1], 3, pyautogui.easeOutQuad) pyautogui.click(button='left') @@ -49,15 +91,20 @@ def get_account(account_list): pyautogui.click(button='left') time.sleep(2) - print("Inserting credentials") + # print("[QL_GetGAccount] Inserting credentials") # account; "mopopa1077@5sword.com", "hellogoodbye" # account = ("hemerey688@kibwot.com", "hellogoodbye") - account_email = account_list.request_new_account() + account_email = sys.argv[1] account = (account_email, "hellogoodbye") username = account[0] password = account[1] - first_part = username.split('@')[0] - second_part = username.split('@')[1] + + try: + first_part = username.split('@')[0] + second_part = username.split('@')[1] + except: + print(False) + exit() pyautogui.press('@') pyautogui.press('left') @@ -73,7 +120,7 @@ def get_account(account_list): # Start course time.sleep(5) - print("Starting the course") + # print("[QL_GetGAccount] Starting the course") pyautogui.moveTo(ui.qwiklabs_gui.STARTLAB_BTN[0], ui.qwiklabs_gui.STARTLAB_BTN[1], 3, pyautogui.easeOutQuad) pyautogui.click() @@ -87,21 +134,58 @@ def get_account(account_list): bashCommand = "copyq clipboard" # Copy username to clipboard time.sleep(20) - print("Copying email") + # print("Copying email") pyautogui.moveTo(ui.qwiklabs_gui.EMAIL_COPY_BTN[0], ui.qwiklabs_gui.EMAIL_COPY_BTN[1], 3, pyautogui.easeOutQuad) pyautogui.click() g_email = subprocess.check_output(['bash','-c', bashCommand]).decode('utf-8') # Copy password to clipboard time.sleep(5) - print("Copying password") + # print("Copying password") pyautogui.moveTo(ui.qwiklabs_gui.PASSWORD_COPY_BTN[0], ui.qwiklabs_gui.PASSWORD_COPY_BTN[1], 3, pyautogui.easeOutQuad) pyautogui.click() g_password = subprocess.check_output(['bash','-c', bashCommand]).decode('utf-8') + time.sleep(5) - # a possible way of finding out we haven't got the password, therefore the account was probably blocked - if not '@' in g_email: - account_list.mark_account_for_deletition(account_email) - return False + # a possible way of finding out we haven't got the password, therefore the account was probably blocked or there was a connection issue + if '@' in g_email: + print(g_email, g_password) + else: + # account_list.mark_account_for_deletition(account_email) + print(False) - return (g_email, g_password) \ No newline at end of file + + +def get_google_account(): + from utils import global_vars + import subprocess + + print("[QL_GetAccount] Getting new google account..." ) + account = global_vars.ql_list.request_new_account() + + res = subprocess.check_output(['bash','-c', "src/qwiklabs/get_account.sh {} {} ".format(str(global_vars.PROXY), account)]).decode('utf-8') + + if res is False: + res = bool(res) + # Maybe if we failed there was a connection issue, so ping qwiklabs.com to check + # If ping is successful the account is out of quota + + if global_vars.PROXY is False: + r = requests.get("https://qwiklabs.com", proxies=proxyDict) + else : + proxyDict = { + "socksVersion" : 5, + "socks" : global_vars.PROXY + } + + r = requests.get("https://qwiklabs.com", proxies=proxyDict) + + # ping was unsuccessful, delete the account + if r.stats_code == 200: + print("[QL_GetAccount] Something went wrong, trying again") + else: + ql_list.mark_account_for_deletition(account) + + + print("[QL_GetGAccount] {}".format(res)) + return res \ No newline at end of file diff --git a/src/qwiklabs/get_account.sh b/src/qwiklabs/get_account.sh index 9bf946d..53ccc3b 100755 --- a/src/qwiklabs/get_account.sh +++ b/src/qwiklabs/get_account.sh @@ -1,18 +1,22 @@ #!/bin/bash -#Start xephyr window -DISPLAY=:2 Xephyr -br -ac -noreset -screen 800x600 :2 & -# Start a copyq server, that will be used to copy the email and password of the obtained account from the clipboard of Xephyr -DISPLAY=:1 copyq & +d=":2" # Clear chrome profile rm -rf ./chrome-profile +DISPLAY=:2 kill -9 $(pidof /usr/bin/google-chrome-stable) > /dev/null 2> /dev/null #Start chrome -DISPLAY=:1 /usr/bin/google-chrome-stable --user-data-dir='./chrome-profile' --no-first-run & +if [ $1 == "False" ]; then + DISPLAY=$d /usr/bin/google-chrome-stable --user-data-dir='./chrome-profile' --no-first-run > /dev/null 2> /dev/null & + # echo "Starting chrome without proxy" +else + DISPLAY=$d /usr/bin/google-chrome-stable --user-data-dir='./chrome-profile' --no-first-run --proxy-server=socks5://$1 > /dev/null 2> /dev/null & + # echo "Starting chrome with proxy" +fi #Wait enough to let chrome start up sleep 5 #Now start the actual bot, we're in a safe environment -DISPLAY=:1 python get_account_from_qwiklabs.py \ No newline at end of file +DISPLAY=$d python src/qwiklabs/get_account.py $2 \ No newline at end of file diff --git a/src/utils/__pycache__/browser_manager.cpython-39.pyc b/src/utils/__pycache__/browser_manager.cpython-39.pyc index 257c40cc3f821acc37676ace748ac57a1479e940..5f77960703c693107d42fc96103bdda6f398690c 100644 GIT binary patch delta 1177 zcmZ`&Pj4Gl5Z_sQ*K23(Hc4$Kv7NSr(l|(=MF?>~J%H5S+6r3HE(f#qJSE$#cink! zlN1H{k{&o95iM{od;o-m_yF|I7uXK~;!7ZAHl~Uqv4`KA_nUe1f4^@3)^3K)X2asI z_G&Zy^Q1X|;^gh)&n>LSok=(7f`#k2fc`NAD|i`Oc!8x=yn>6k#L^lr zeD?7wuHY(b2DpYjX4dfy?Bjr$%Lt!Z!;O=FUbKc#IQKuf_vrE84u{VFu-EdR;Ctxg zAK3fL%S>rcasnIr-~z4WzuSB0Gc&AFjSp%Hv;;0N6wWw~#(PE8L=#mwI#y~*7e(87 z4PCKYDD6JVj7gJKCUjXkhgr8<5@?WrTX`}2|3E=qs{}`T>ba(#xb8Cy>$E8Hl7J-7 zd8k7}mqhfU#3D4Nu;1fS&~G_&Pb0bni`UqXC3E{ovp=fCbi38m9FSo{+;u1=S{v3D}{>`?JFu@ z1`B#O#Pnc9X=={8Vbh|m4yPd(KR1~d@*b;nmB9iZ=sKUb#~|1FSIO_Y-8*n(A!M8x zg0V-HBY0Uw`$quFI9SPm-Y=P|ak^H?T2I|0K<69y$~Lu^9=gIF+4;}zomri1_8l}o z-lcS+?oCaUCYm;xE4*D5Vyv_-{19;z(oQDLCYf^Ko<2A;w+d~EqMA;P4*YTHZ{Ce_ zd(+e=Br|$K=|NR1x|M%f>%n&ZL+!I0Z?TK>t@58`(Wx~XKVXA-hdiL0`M|pY@8oyA z)tNjE{DUwuGC|qh^Nt);arpd^c#xtkpm!OEHZAZ$(&ztV+2lwW_Xgxf8XJY9vesY!@|Iv${zS6Ng-bl%bW(Vvo@GiKT`XoMiuLwRoIVNT(SAs}Y$dHo zfPuhCGJ;|ogO##XCOf_Xc%U{s@aFSvct6Nf#-ps#f^e*~#!)(hyVZp delta 1086 zcmaJ=J#W)c6!mo+$93bGg9zq*Phj z0VIaX3ky;i7%E2K7a-P-4EZIDylW~59kAr{j?caCyzBek`&xcoc6`UNHTAqdT=vgT zoLM+Oxp}lci#84)fj5bB=-`NA6`aRW98+ux$FX#zc~zXivKpsx0V_DAA~meyv{Ghp z5oAR&dwO(xTs-VLRm_U{EhrYcrtQ5CE1vOBS!C@Ft z;N_dGpt;>QWY8A(`-zlMSV>QEC8(tzbH}~^SP#V_#KyKb zh^fkE(+b=n8fDIv(zpV(ve=hYQq;48Pzu`hTQtFuf@q1h2xT9F%he18VJDGK#l9}* z(@#bf7SiuVubx@6t2aVP7zW{HBW_aAku;~oL6bDh*T+_r7@G<-u)qddO3(7oRu{-Msdd`C_irQkmBZDZ6>AKST)|T+GCF0mC`iKpmHWTiuXa3F|*c*dx@PvGaqWuHU zh&ocuX=aWW&A4_F_SI)3=2hxanEp#p+e%G}tLNF76}&XJ^Tem2%NF z3uq->wN{~?`c}2aQ@!GzA4uLnKA4w{@+eyV!E<)V8Vz(yaaSk4aRdW=ih1t0KJz!Y zw&p@6x^rG72~kMVlmZ+4v!8!jCD_bv2p?O|BtOKc?O7yt5)sRoDr{6^SYTLU;B6E#nu3rR=8w diff --git a/src/utils/browser_manager.py b/src/utils/browser_manager.py index 83a579f..32f028e 100644 --- a/src/utils/browser_manager.py +++ b/src/utils/browser_manager.py @@ -14,6 +14,8 @@ import time import random import requests +from utils.global_vars import PROXY + def waitForElement(browser, by, selector, timeout=5, after_delay=0): try: return WebDriverWait(browser, timeout).until(EC.element_to_be_clickable((by, selector))) @@ -57,7 +59,7 @@ def expand_shadow_element(driver, element): # shadowRoot = driver.execute_script('return arguments[0].shadowRoot.children', element) # return shadowRoot -def start_browser(headless=False, proxy=False): +def start_browser(headless=False): # # change mac # # run_as_sudo('macchanger -r wlp3s0') @@ -70,8 +72,8 @@ def start_browser(headless=False, proxy=False): opts.add_argument('--enable-javascript') #enabling javascript is needed in order to not get recognized as a bot # opts.add_argument("user-agent={}".format(user_agent)) - if proxy is not False: - opts.add_argument(f'--proxy-server=socks5://'+proxy) + if PROXY is not False: + opts.add_argument(f'--proxy-server=socks5://'+PROXY) #Fire up chromedriver chromedriver = webdriver.Chrome(options=opts) diff --git a/src/utils/change_mac.sh b/src/utils/change_mac.sh old mode 100644 new mode 100755 diff --git a/src/utils/global_vars.py b/src/utils/global_vars.py new file mode 100644 index 0000000..9818afd --- /dev/null +++ b/src/utils/global_vars.py @@ -0,0 +1,4 @@ +from qwiklabs import account_list + +PROXY = False +ql_list = account_list.QL_AccountList('/home/emamaker/Documents/Projects/GColabAutomator/GColabAutomator-v2/src/qwiklabs_available_accounts.txt') \ No newline at end of file diff --git a/src/utils/gui.py b/src/utils/gui.py deleted file mode 100644 index 65614ed..0000000 --- a/src/utils/gui.py +++ /dev/null @@ -1,44 +0,0 @@ -''' -This classes holds the coordinates for all the elements that need to be clicked on the screen. -All the coordinates are kept as percentages of the screen resolution and are recalculated at runtime -''' -import pyautogui - -class Gui: - def __init__(self, width, height): - Gui.chrome_gui = Chrome(width, height) - Gui.qwiklabs_gui = Qwiklabs(width, height) - -class Chrome(Gui): - SEARCH_BAR_PERCENTAGE = (0.5, 0.1) - - def __init__(self, width, height): - Chrome.SEARCH_BAR=width*Chrome.SEARCH_BAR_PERCENTAGE[0], height*Chrome.SEARCH_BAR_PERCENTAGE[1] - - def click_searchbar(self): - pyautogui.moveTo(Chrome.SEARCH_BAR[0], Chrome.SEARCH_BAR[1]) - pyautogui.click() - pyautogui.keyDown('ctrl') - pyautogui.press('a') - pyautogui.keyUp('ctrl') - - -class Qwiklabs(Gui): - JOIN_BTN_PERCENTAGE = (0.775, 0.183) - SIGN_IN_BTN_PERCENTAGE = (0.2125, 0.73) - EMAIL_TEXTBOX_PERCENTAGE = (0.5, 0.73) - COURSE_BTN_PERCENTAGE = (0.29, 0.45) - STARTLAB_BTN_PERCENTAGE = (0.125, 0.31) - CAPTCHA_BTN_PERCENTAGE = (0.075, 0.425) - EMAIL_COPY_BTN_PERCENTAGE = (0.3125, 0.7) - PASSWORD_COPY_BTN_PERCENTAGE = (0.3125, 0.82) - - def __init__(self, width, height): - Qwiklabs.JOIN_BTN=width*Qwiklabs.JOIN_BTN_PERCENTAGE[0], height*Qwiklabs.JOIN_BTN_PERCENTAGE[1] - Qwiklabs.SIGN_IN_BTN=width*Qwiklabs.SIGN_IN_BTN_PERCENTAGE[0], height*Qwiklabs.SIGN_IN_BTN_PERCENTAGE[1] - Qwiklabs.EMAIL_TEXTBOX=width*Qwiklabs.EMAIL_TEXTBOX_PERCENTAGE[0], height*Qwiklabs.EMAIL_TEXTBOX_PERCENTAGE[1] - Qwiklabs.COURSE_BTN=width*Qwiklabs.COURSE_BTN_PERCENTAGE[0], height*Qwiklabs.COURSE_BTN_PERCENTAGE[1] - Qwiklabs.STARTLAB_BTN=width*Qwiklabs.STARTLAB_BTN_PERCENTAGE[0], height*Qwiklabs.STARTLAB_BTN_PERCENTAGE[1] - Qwiklabs.CAPTCHA_BTN=width*Qwiklabs.CAPTCHA_BTN_PERCENTAGE[0], height*Qwiklabs.CAPTCHA_BTN_PERCENTAGE[1] - Qwiklabs.EMAIL_COPY_BTN=width*Qwiklabs.EMAIL_COPY_BTN_PERCENTAGE[0], height*Qwiklabs.EMAIL_COPY_BTN_PERCENTAGE[1] - Qwiklabs.PASSWORD_COPY_BTN=width*Qwiklabs.PASSWORD_COPY_BTN_PERCENTAGE[0], height*Qwiklabs.PASSWORD_COPY_BTN_PERCENTAGE[1] diff --git a/src/utils/proxy.py b/src/utils/proxy.py new file mode 100644 index 0000000..e193dc1 --- /dev/null +++ b/src/utils/proxy.py @@ -0,0 +1,51 @@ +from ngrok import ngrok +from colab import colab +from colab.gists import Gists +from utils import global_vars +from qwiklabs import get_account + +import time + +class Proxy(): + def __init__(self): + Proxy.PROXY_COMBOS = [ + ( ('giangillo.rossi1@gmail.com', 'emamaker02'), Gists.PROXY1), + ( ('giangillo.rossi2@gmail.com', 'emamaker02'), Gists.PROXY2) + ] + Proxy.TIME_ELAPSED = 2400 #time that has to pass before changing account combo, in seconds + + self.account_combo_index = 0 + self.account_combo = Proxy.PROXY_COMBOS[self.account_combo_index] + self.last_time = time.time() + + self.start_new_proxy_session() + + def request_new_proxy(self): + print("[PROXY] A new proxy has been requested") + # then it's time to close the current gist+ngrok account and open another one + if time.time() - self.last_time > Proxy.TIME_ELAPSED: + print("[PROXY] Time for current account {} has expired".format(self.account_combo[0])) + self.ngrok.close_browser() + self.colab.quit() + + # it's not needed to manually close the colab session, just leave it decay on it's own + # but it's needed to close ngrok + self.account_combo_index = (self.account_combo_index+1) % len(Proxy.PROXY_COMBOS) + self.account_combo = Proxy.PROXY_COMBOS[self.account_combo_index] + print("[PROXY] Switching to new account {}".format(self.account_combo[1])) + + self.start_new_proxy_session() + else: + print("[PROXY] Refreshing existing proxy to get new ip") + #just refresh + self.colab.refresh_event.set() + + global_vars.PROXY = self.ngrok.get_proxy_ip() + print("[PROXY] Done! New proxy is: {} ".format(global_vars.PROXY)) + + def start_new_proxy_session(self): + self.colab = colab.ColabGist(self.account_combo[1], get_account.get_google_account()) + self.colab.run() #this launches a new thread + time.sleep(90) + + \ No newline at end of file