from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.common.exceptions import StaleElementReferenceException, TimeoutException
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from pikaptcha.jibber import *
from pikaptcha.ptcexceptions import *
from pikaptcha.url import *
user_agent = ("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) " + "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.57 Safari/537.36")
# endpoints taken from PTCAccount
SUCCESS_URLS = (
"https://club.pokemon.com/us/pokemon-trainer-club/parents/email", # This initially seemed to be the proper success redirect
"https://club.pokemon.com/us/pokemon-trainer-club/sign-up/", # but experimentally it now seems to return to the sign-up, but still registers
)
# As both seem to work, we"ll check against both success destinations until I have I better idea for how to check success
DUPE_EMAIL_URL = "https://club.pokemon.com/us/pokemon-trainer-club/forgot-password?msg=users.email.exists"
BAD_DATA_URL = "https://club.pokemon.com/us/pokemon-trainer-club/parents/sign-up"
def _validate_birthday(birthday):
# raises PTCInvalidBirthdayException if invalid
# split by -
# has to be at least 2002 and after 1910
# char length 10
try:
assert len(birthday) == 10
# Ensure birthday is delimited by -
# Ensure birthday is zero-padded
year, month, day = birthday.split("-")
assert year is not None and month is not None and day is not None
assert len(year) == 4 and year.isdigit()
assert len(month) == 2 and month.isdigit()
assert len(day) == 2 and day.isdigit()
# Check year is between 1910 and 2002, and also that it"s a valid date
assert datetime.datetime(year=1910, month=1, day=1) <= datetime.datetime(year=int(year), month=int(month), day=int(day)) <= datetime.datetime(year=2002, month=12, day=31)
def _validate_password(password):
# Check that password length is between 6 and 15 characters long
if len(password) < 6 or len(password) > 15:
raise PTCInvalidPasswordException("Password must be between 6 and 15 characters.")
return True
def create_account(username, password, email, birthday, captchakey2, captchatimeout):
if password is not None:
_validate_password(password)
print("Attempting to create user {user}:{pw}. Opening browser...".format(user=username, pw=password))
if captchakey2 != None:
dcap = dict(DesiredCapabilities.PHANTOMJS)
dcap["phantomjs.page.settings.userAgent"] = user_agent
driver = webdriver.PhantomJS(desired_capabilities=dcap)
else:
driver = webdriver.Chrome()
driver.set_window_size(600, 600)
# Input age: 1992-01-08
print("Step 1: Verifying age using birthday: {}".format(birthday))
driver.get("{}/sign-up/".format(BASE_URL))
assert driver.current_url == "{}/sign-up/".format(BASE_URL)
elem = driver.find_element_by_name("dob")
# Workaround for different region not having the same input type
driver.execute_script("var input = document.createElement("input"); input.type="text"; input.setAttribute("name", "dob"); arguments[0].parentNode.replaceChild(input, arguments[0])", elem)
def _validate_response(driver):
url = driver.current_url
if url in SUCCESS_URLS:
return True
elif url == DUPE_EMAIL_URL:
raise PTCInvalidEmailException("Email already in use.")
elif url == BAD_DATA_URL:
if "Enter a valid email address." in driver.page_source:
raise PTCInvalidEmailException("Invalid email.")
else:
raise PTCInvalidNameException("Username already in use.")
else:
raise PTCException("Generic failure. User was not created.")
def random_account(username=None, password=None, email=None, birthday=None, plusmail=None, recaptcha=None, captchatimeout=1000):
try_username = _random_string() if username is None else str(username)
password = _random_string() if password is None else str(password)
try_email = _random_email() if email is None else str(email)
captchakey2 = None if recaptcha is None else str(recaptcha)
if plusmail is not None:
pm = plusmail.split("@")
try_email = pm[0] + "+" + try_username + "@" + pm[1]
try_birthday = _random_birthday() if birthday is None else str(birthday)
if birthday is not None:
_validate_birthday(try_birthday)
account_created = False
while not account_created:
try:
account_created = create_account(try_username, password, try_email, try_birthday, captchakey2, captchatimeout)
except PTCInvalidNameException:
if username is None:
try_username = _random_string()
else:
raise
except PTCInvalidEmailException:
if email is None:
try_email = _random_email()
else:
raise