[SQUASHED] Use of Global Vars, fix bash scripts to properly use Xephyr

master
EmaMaker 2021-08-27 22:25:57 +02:00
parent 68b0560e7d
commit 66d0617299
20 changed files with 285 additions and 176 deletions

5
.gitignore vendored
View File

@ -1,4 +1,5 @@
__pycache__/ **/__pycache__/
chrome-profile/ chrome-profile/
misc/ misc/
chromedriver chromedriver
bash-test.sh

View File

@ -1,5 +1,3 @@
# '!' before an email address means it still needs to be activated. Password is 'hellogoodbye' when not specified
06prgzamm96@esiix.com 06prgzamm96@esiix.com
jhv8mtemi@esiix.com jhv8mtemi@esiix.com
6bgfngq6@yoggm.com 6bgfngq6@yoggm.com
@ -7,13 +5,10 @@ fohxil@xojxe.com
b4d0o0y5pg@esiix.com b4d0o0y5pg@esiix.com
i3z8qtab@xojxe.com i3z8qtab@xojxe.com
l5wbup@1secmail.com l5wbup@1secmail.com
ryysw0@1secmail.net
! ryysw0@1secmail.net m5l7868ar@wwjmp.com
! m5l7868ar@wwjmp.com ue8oqa0lf0j@1secmail.net
! m5i8g3@1secmail.com 17k2l9@1secmail.com
! ue8oqa0lf0j@1secmail.net c5xm6j@1secmail.net
! 17k2l9@1secmail.com mud0ud@esiix.com
! 08hyvaejbr@xojxe.com t788egrvdp@wwjmp.com
! c5xm6j@1secmail.net
! mud0ud@esiix.com
! t788egrvdp@wwjmp.com

View File

@ -2,7 +2,9 @@ from utils import browser_manager
from selenium import webdriver from selenium import webdriver
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
import time import time
from threading import Thread from threading import Thread, Event
from utils.global_vars import PROXY
class ColabGist(Thread): 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 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.url = url
self.account = account self.account = account
self.minutes = minutes self.minutes = minutes
self.backend = backend 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): def run(self):
self.run_colab() self.run_colab()
def run_colab(self): def run_colab(self):
print("[ColabGist {}] Starting the gist".format(self.url))
self.start_browser() self.start_browser()
self.start_session() self.start_session()
def sign_in(self): def sign_in(self):
print("[ColabGist {}] Signing in...".format(self.url))
try: 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 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") 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 # Run the desired Colab notebook. Logging into Google account by profile is mandatory
def start_session(self): def start_session(self):
if not self.sign_in(): 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.driver.quit()
self.run_colab() self.run_colab()
return return
self.driver.get(self.url) 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.CSS_SELECTOR, "#runtime-menu-button")
browser_manager.clickButton(self.driver, By.XPATH, '//*[@id=":24"]') 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") browser_manager.clickButton(self.driver, By.CSS_SELECTOR, "#ok")
time.sleep(1.5) 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(): def terminate_session():
# Terminate the session # Terminate the session
@ -125,8 +138,15 @@ class ColabGist(Thread):
time.sleep(60) time.sleep(60)
def start_browser(self): def start_browser(self):
self.driver=browser_manager.start_browser(self.proxy) self.driver=browser_manager.start_browser()
def stop_browser(self): def stop_browser(self):
# Close browser # Close browser
self.driver.quit() self.driver.quit()
def actual_quit(self):
self.terminate_session()
self.stop_browser()
def quit(self):
self.stop_event.set()

8
src/colab_automator.sh Normal file → Executable file
View File

@ -9,8 +9,12 @@ pip install -r requirements.txt
#Start xephyr window #Start xephyr window
Xephyr -br -ac -noreset -screen 1280x720 :1 & 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 # 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 #Now start the actual bot, we're in a safe environment
DISPLAY=:1 python get_account_from_qwiklabs.py DISPLAY=:1 python src/main.py

View File

@ -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("[MAIN] Entering main script!")
print(ql_list.request_new_account())
p = proxy.Proxy()
while True: while True:
ql_list.update_account_list() p.request_new_proxy()
print(ql_list.suspended_list) print(global_vars.PROXY)
time.sleep(30)

View File

@ -8,25 +8,9 @@ from selenium.webdriver.common.by import By
import time import time
from colab import colab 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: class Ngrok:
def __init__(self, account): def __init__(self, account):
Ngrok.ACCOUNTS = [
('giangillo.rossi1@gmail.com', 'emamaker02')
('giangillo.rossi2@gmail.com', 'emamaker02')
]
self.account = account self.account = account
def start_browser(self): def start_browser(self):

View File

@ -1,7 +1,7 @@
# There is a more efficient way of doing this, but i don't want to think about it rn # There is a more efficient way of doing this, but i don't want to think about it rn
import time import time
import random import random
from qwiklabs import create_account, delete_account # from qwiklabs import create_account, delete_account
class QL_AccountList(): class QL_AccountList():
@ -14,6 +14,7 @@ class QL_AccountList():
self.to_delete = [] self.to_delete = []
self.last_action_time = time.time() self.last_action_time = time.time()
self.last_action = 0 #0 added, 1 removed self.last_action = 0 #0 added, 1 removed
print("[QL_AccountList] New account list created! Using list from file: {} " .format(account_list))
def request_new_account(self): def request_new_account(self):
with open(self.account_list, 'r') as accounts: with open(self.account_list, 'r') as accounts:
@ -25,10 +26,13 @@ class QL_AccountList():
while True: while True:
account = accounts_lines[random.randint(0, len(accounts_lines)-1)] account = accounts_lines[random.randint(0, len(accounts_lines)-1)]
if self.is_account_valid(account): if self.is_account_valid(account):
print("[QL_AccountList] A new account has been requested! choosen {}".format(account))
self.suspend_account(account) self.suspend_account(account)
return account return account
def suspend_account(self, account): def suspend_account(self, account):
print("[QL_AccountList] Account {} will be suspended for the next {} seconds".format(account, QL_AccountList.SUSPEND_TIME))
self.suspended_list[account] = int(time.time()) self.suspended_list[account] = int(time.time())
def is_account_suspended(self, account): def is_account_suspended(self, account):
@ -38,6 +42,7 @@ class QL_AccountList():
return (not self.is_account_suspended(account)) and (not account in self.to_delete) return (not self.is_account_suspended(account)) and (not account in self.to_delete)
def mark_account_for_deletition(self): def mark_account_for_deletition(self):
print("[QL_AccountList] Account {} has been marked for deletition".format(account))
self.to_delete.append(account) self.to_delete.append(account)
def update_account_list(self): def update_account_list(self):
@ -50,13 +55,13 @@ class QL_AccountList():
for d in to_delete: for d in to_delete:
del self.suspended_list[d] del self.suspended_list[d]
if time.time() - self.last_action_time > QL_AccountList.ACTION_WAIT_TIME: # if time.time() - self.last_action_time > QL_AccountList.ACTION_WAIT_TIME:
# TODO: add the requesting of a proxy when doing these actions # # TODO: add the requesting of a proxy when doing these actions
if last_action == 0: # if last_action == 0:
# removed an account from the "to delete" lsit # # removed an account from the "to delete" lsit
delete_account.QL_DeleteAccount(False, to_delete[random.randint(0, len(to_delete)-1)]) # delete_account.QL_DeleteAccount(False, to_delete[random.randint(0, len(to_delete)-1)])
else: # else:
# otherwise create a new account # # otherwise create a new account
create_account.QL_CreateAccount(False) # create_account.QL_CreateAccount(False)

View File

@ -13,16 +13,15 @@ import pydub
import speech_recognition as sr import speech_recognition as sr
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from utils.global_vars import PROXY
class QL_CreateAccount: class QL_CreateAccount:
def __init__(self, proxy=False):
self.proxy = proxy
def create_account(self): def create_account(self):
self.info = RandomNameGenerator(self.proxy).get_person_info() self.info = RandomNameGenerator(self.proxy).get_person_info()
self.driver = browser_manager.start_browser(self.proxy) self.driver = browser_manager.start_browser()
self.temp_mail = TempMail(self.proxy) self.temp_mail = TempMail()
self.temp_mail_address = self.temp_mail.get_new_temp_mail() self.temp_mail_address = self.temp_mail.get_new_temp_mail()
@ -141,15 +140,14 @@ class QL_CreateAccount:
class RandomNameGenerator(): class RandomNameGenerator():
def __init__(self, proxy=False): def __init__(self):
self.proxy = proxy
self.proxyDict = { self.proxyDict = {
"socks" : proxy, "socks" : PROXY,
"socksVersion" : 5 "socksVersion" : 5
} }
def get_person_info(self): def get_person_info(self):
if self.proxy: if PROXY:
r = requests.get('https://randomuser.me/api', proxies=self.proxyDict) r = requests.get('https://randomuser.me/api', proxies=self.proxyDict)
else: else:
r = requests.get('https://randomuser.me/api') 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 # get a temp mail from https://www.1secmail.com/api/ and handle it using requests
class TempMail: class TempMail:
def __init__(self, proxy=False): def __init__(self):
self.proxy = proxy
self.proxyDict = { self.proxyDict = {
"socks" : proxy, "socks" : PROXY,
"socksVersion" : 5 "socksVersion" : 5
} }

View File

@ -5,12 +5,11 @@ from selenium.webdriver.common.alert import Alert
from selenium.webdriver.common.alert import Command from selenium.webdriver.common.alert import Command
class QL_DeleteAccount: class QL_DeleteAccount:
def __init__(self, proxy, account): def __init__(self, account):
self.proxy = proxy
self.account = account self.account = account
def delete_account(self): def delete_account(self):
self.driver = browser_manager.start_browser(self.proxy) self.driver = browser_manager.start_browser()
self.sign_in() self.sign_in()
self.delete() self.delete()

View File

@ -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 pyautogui.FAILSAFE = False
screenWidth, screenHeight = pyautogui.size() 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 # Head over to the course on qwiklabs.com
gui.Gui.chrome_gui.click_searchbar() Gui.chrome_gui.click_searchbar()
pyautogui.write("qwiklabs.com") pyautogui.write("qwiklabs.com")
pyautogui.press('/') pyautogui.press('/')
pyautogui.write("focuses") pyautogui.write("focuses")
@ -27,7 +69,7 @@ def get_account(account_list):
time.sleep(15) time.sleep(15)
print("Signing in") # print("[QL_GetGAccount] Signing in")
pyautogui.moveTo(0,0) pyautogui.moveTo(0,0)
# Click join button # Click join button
@ -38,7 +80,7 @@ def get_account(account_list):
# Move to the end of the page # Move to the end of the page
pyautogui.press('pgdn') pyautogui.press('pgdn')
print("Moving from sign up to sign in") # print("Moving from sign up to sign in")
# switch to sign in button # 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.moveTo(ui.qwiklabs_gui.SIGN_IN_BTN[0], ui.qwiklabs_gui.SIGN_IN_BTN[1], 3, pyautogui.easeOutQuad)
pyautogui.click(button='left') pyautogui.click(button='left')
@ -49,15 +91,20 @@ def get_account(account_list):
pyautogui.click(button='left') pyautogui.click(button='left')
time.sleep(2) time.sleep(2)
print("Inserting credentials") # print("[QL_GetGAccount] Inserting credentials")
# account; "mopopa1077@5sword.com", "hellogoodbye" # account; "mopopa1077@5sword.com", "hellogoodbye"
# account = ("hemerey688@kibwot.com", "hellogoodbye") # account = ("hemerey688@kibwot.com", "hellogoodbye")
account_email = account_list.request_new_account() account_email = sys.argv[1]
account = (account_email, "hellogoodbye") account = (account_email, "hellogoodbye")
username = account[0] username = account[0]
password = account[1] 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('@')
pyautogui.press('left') pyautogui.press('left')
@ -73,7 +120,7 @@ def get_account(account_list):
# Start course # Start course
time.sleep(5) 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.moveTo(ui.qwiklabs_gui.STARTLAB_BTN[0], ui.qwiklabs_gui.STARTLAB_BTN[1], 3, pyautogui.easeOutQuad)
pyautogui.click() pyautogui.click()
@ -87,21 +134,58 @@ def get_account(account_list):
bashCommand = "copyq clipboard" bashCommand = "copyq clipboard"
# Copy username to clipboard # Copy username to clipboard
time.sleep(20) 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.moveTo(ui.qwiklabs_gui.EMAIL_COPY_BTN[0], ui.qwiklabs_gui.EMAIL_COPY_BTN[1], 3, pyautogui.easeOutQuad)
pyautogui.click() pyautogui.click()
g_email = subprocess.check_output(['bash','-c', bashCommand]).decode('utf-8') g_email = subprocess.check_output(['bash','-c', bashCommand]).decode('utf-8')
# Copy password to clipboard # Copy password to clipboard
time.sleep(5) 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.moveTo(ui.qwiklabs_gui.PASSWORD_COPY_BTN[0], ui.qwiklabs_gui.PASSWORD_COPY_BTN[1], 3, pyautogui.easeOutQuad)
pyautogui.click() pyautogui.click()
g_password = subprocess.check_output(['bash','-c', bashCommand]).decode('utf-8') 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 # 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 not '@' in g_email: if '@' in g_email:
account_list.mark_account_for_deletition(account_email) print(g_email, g_password)
return False else:
# account_list.mark_account_for_deletition(account_email)
print(False)
return (g_email, g_password)
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

View File

@ -1,18 +1,22 @@
#!/bin/bash #!/bin/bash
#Start xephyr window d=":2"
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 &
# Clear chrome profile # Clear chrome profile
rm -rf ./chrome-profile rm -rf ./chrome-profile
DISPLAY=:2 kill -9 $(pidof /usr/bin/google-chrome-stable) > /dev/null 2> /dev/null
#Start chrome #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 #Wait enough to let chrome start up
sleep 5 sleep 5
#Now start the actual bot, we're in a safe environment #Now start the actual bot, we're in a safe environment
DISPLAY=:1 python get_account_from_qwiklabs.py DISPLAY=$d python src/qwiklabs/get_account.py $2

View File

@ -14,6 +14,8 @@ import time
import random import random
import requests import requests
from utils.global_vars import PROXY
def waitForElement(browser, by, selector, timeout=5, after_delay=0): def waitForElement(browser, by, selector, timeout=5, after_delay=0):
try: try:
return WebDriverWait(browser, timeout).until(EC.element_to_be_clickable((by, selector))) 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) # shadowRoot = driver.execute_script('return arguments[0].shadowRoot.children', element)
# return shadowRoot # return shadowRoot
def start_browser(headless=False, proxy=False): def start_browser(headless=False):
# # change mac # # change mac
# # run_as_sudo('macchanger -r wlp3s0') # # 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('--enable-javascript') #enabling javascript is needed in order to not get recognized as a bot
# opts.add_argument("user-agent={}".format(user_agent)) # opts.add_argument("user-agent={}".format(user_agent))
if proxy is not False: if PROXY is not False:
opts.add_argument(f'--proxy-server=socks5://'+proxy) opts.add_argument(f'--proxy-server=socks5://'+PROXY)
#Fire up chromedriver #Fire up chromedriver
chromedriver = webdriver.Chrome(options=opts) chromedriver = webdriver.Chrome(options=opts)

0
src/utils/change_mac.sh Normal file → Executable file
View File

4
src/utils/global_vars.py Normal file
View File

@ -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')

View File

@ -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]

51
src/utils/proxy.py Normal file
View File

@ -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)