Last active
February 3, 2022 03:05
-
-
Save JeffreyKozik/ebe4df2080cb8aeaff1d1ffd921a61e8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://stackoverflow.com/questions/65184355/error-403-access-denied-from-google-authentication-web-api-despite-google-acc | |
# Copyright 2018 Google LLC | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
# [START gmail_quickstart] | |
from __future__ import print_function | |
import os.path | |
from googleapiclient.discovery import build | |
from google_auth_oauthlib.flow import InstalledAppFlow | |
from google.auth.transport.requests import Request | |
from google.oauth2.credentials import Credentials | |
# If modifying these scopes, delete the file token.json. | |
SCOPES = ['https://www.googleapis.com/auth/gmail.send'] | |
def main(): | |
"""Shows basic usage of the Gmail API. | |
Lists the user's Gmail labels. | |
""" | |
creds = None | |
# The file token.json stores the user's access and refresh tokens, and is | |
# created automatically when the authorization flow completes for the first | |
# time. | |
if os.path.exists('token.json'): | |
creds = Credentials.from_authorized_user_file('token.json', SCOPES) | |
# If there are no (valid) credentials available, let the user log in. | |
if not creds or not creds.valid: | |
if creds and creds.expired and creds.refresh_token: | |
creds.refresh(Request()) | |
else: | |
flow = InstalledAppFlow.from_client_secrets_file( | |
'credentials.json', SCOPES) | |
creds = flow.run_local_server(port=0) | |
# Save the credentials for the next run | |
with open('token.json', 'w') as token: | |
token.write(creds.to_json()) | |
service = build('gmail', 'v1', credentials=creds) | |
# Call the Gmail API | |
results = service.users().labels().list(userId='me').execute() | |
labels = results.get('labels', []) | |
if not labels: | |
print('No labels found.') | |
else: | |
print('Labels:') | |
for label in labels: | |
print(label['name']) | |
if __name__ == '__main__': | |
main() | |
# [END gmail_quickstart] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Jeffrey Kozik | |
# MAC = "not m1" | |
MAC = "windows" | |
BROWSER = "chrome" | |
OVERALL_RECEIVER = "jeffreykozik8@gmail.com" | |
# https://www.geeksforgeeks.org/explicit-waits-in-selenium-python/ | |
waiting_time = 1000 #amount of max time to wait when loading pages | |
# #https://medium.com/@igorzabukovec/automate-web-crawling-with-selenium-python-part-1-85113660de96 | |
# https://medium.com/@igorzabukovec/crawl-websites-with-selenium-part-2-3e714120e93f | |
from selenium import webdriver | |
from selenium.webdriver.chrome.options import Options | |
from selenium.webdriver.common.by import By | |
from selenium.webdriver.support.ui import WebDriverWait | |
from selenium.webdriver.support import expected_conditions as EC | |
import time | |
from selenium.webdriver.support.ui import Select | |
from selenium.webdriver.common.keys import Keys | |
import chime | |
import time | |
def chime_n(n): | |
i = 0 | |
while i < n: | |
chime.success() | |
print("chime") | |
time.sleep(1) | |
i+=1 | |
chime_n(5) | |
import httplib2 | |
import os | |
import oauth2client | |
from oauth2client import client, tools, file | |
import base64 | |
from email.mime.multipart import MIMEMultipart | |
from email.mime.text import MIMEText | |
from apiclient import errors, discovery | |
import mimetypes | |
from email.mime.base import MIMEBase | |
from google_auth_oauthlib.flow import InstalledAppFlow | |
import pickle | |
SCOPES = 'https://www.googleapis.com/auth/gmail.send' | |
CLIENT_SECRET_FILE = 'client_secret.json' | |
APPLICATION_NAME = "Desktop client 1" | |
# https://developers.google.com/gmail/api/guides/sending | |
def create_message(sender, to, subject, message_text): | |
message = MIMEText(message_text) | |
message['to'] = to | |
message['from'] = sender | |
message['subject'] = subject | |
return {'raw': base64.urlsafe_b64encode(message.as_string().encode()).decode()} | |
def send_message(service, user_id, message): | |
# try: | |
message = (service.users().messages().send(userId=user_id, body=message).execute()) | |
# print('Message Id: %s' % message['id']) | |
return (message) | |
# except (Eerror): | |
# print("an error occurred: %s" % error) | |
creds = None | |
if os.path.exists('token.pickle'): | |
with open('token.pickle', 'rb') as token: | |
creds = pickle.load(token) | |
else: | |
print("The credentials to send an email are no longer valid.") | |
# if not creds or not creds.valid: | |
# flow = InstalledAppFlow.from_client_secrets_file('credentials.json', SCOPES) | |
# creds = flow.run_local_server(port=0) | |
# with open('token.pickle', 'wb') as token: | |
# pickle.dump(creds, token) | |
service = discovery.build('gmail', 'v1', credentials=creds) | |
def create_and_send_email(sender, receiver, subject, content, service): | |
email_message = create_message(sender, receiver, subject, content) | |
send_message(service, "jeffreykozik8@gmail.com", email_message) | |
create_and_send_email("jeffreykozik8@gmail.com", OVERALL_RECEIVER, "German Immigration Automation", "Selenium Script has Begun", service) | |
print("Sent email confirming start of script.") | |
if (BROWSER != "safari"): | |
# make incognito | |
chrome_options = Options() | |
chrome_options.add_argument("--incognito") | |
# path is executable selenium file | |
chrome_driver = "" | |
if (MAC == "not m1"): | |
chrome_driver = "chromedriver_mac64/chromedriver" | |
driver = webdriver.Chrome(options=chrome_options, executable_path=chrome_driver) | |
elif (MAC == "m1"): | |
chrome_driver = "chromedriver_mac64_m1/chromedriver" | |
driver = webdriver.Chrome(options=chrome_options, executable_path=chrome_driver) | |
else: | |
driver = webdriver.Chrome(options=chrome_options, executable_path="chromedriver.exe") | |
else: | |
# https://developer.apple.com/documentation/webkit/testing_with_webdriver_in_safari | |
driver = webdriver.Safari() | |
# homepage | |
url = "https://otv.verwalt-berlin.de/ams/TerminBuchen?lang=en" | |
# https://www.selenium.dev/selenium/docs/api/py/webdriver/selenium.webdriver.common.by.html | |
# open website, instead of waiting 3 seconds for it to load, wait up to waiting_time for it to load, but as soon as needed elements are loaded - continue | |
# https://stackoverflow.com/questions/27112731/selenium-common-exceptions-nosuchelementexception-message-unable-to-locate-ele | |
# wait for it to load | |
# https://pythonbasics.org/selenium-wait-for-page-to-load/ | |
driver.get(url) | |
book_appt = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.XPATH, "//*[contains(text(), 'Book Appointment')]"))) | |
book_appt.click() | |
# https://stackoverflow.com/questions/59130200/selenium-wait-until-element-is-present-visible-and-interactable | |
agree = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "xi-cb-1"))) | |
agree.click() | |
next = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "applicationForm:managedForm:proceed"))) | |
next.click() | |
def service_selection(): | |
# https://stackoverflow.com/questions/7867537/how-to-select-a-drop-down-menu-value-with-selenium-using-python | |
citizenship = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "xi-sel-400"))) | |
time.sleep(1) | |
citizenship_select = Select(citizenship) | |
time.sleep(1) | |
citizenship_select.select_by_value('368') | |
time.sleep(1) | |
num_people = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "xi-sel-422"))) | |
num_people_select = Select(num_people) | |
num_people_select.select_by_value('1') | |
in_berlin = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "xi-sel-427"))) | |
in_berlin_select = Select(in_berlin) | |
in_berlin_select.select_by_value('2') | |
residence_title = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.CLASS_NAME, "kachel-368-0-1"))) | |
residence_title.click() | |
economic_activity = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.CLASS_NAME, "accordion-368-0-1-1"))) | |
economic_activity.click() | |
blue_card = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "SERVICEWAHL_EN368-0-1-1-324659"))) | |
# https://stackoverflow.com/questions/18079765/how-to-find-parent-elements-by-python-webdriver | |
# blue_card_div = blue_card.find_elements_by_xpath('..') | |
blue_card.click() | |
# WebDriverWait(driver, waiting_time).until( | |
# EC.presence_of_element_located((By.XPATH, "//*[text()[contains(., 'EU Blue Card / Blaue Karte EU (sect. 18b para. 2)')]]"))) | |
# print("found paragraph") | |
# time.sleep(5) | |
service_selection_next = WebDriverWait(driver, waiting_time).until( | |
EC.element_to_be_clickable((By.ID, "applicationForm:managedForm:proceed"))) | |
# print("found next button") | |
# time.sleep(5) | |
service_selection_next.click() | |
print("Trying to Register for Appointment") | |
# service_selection_next_onclick = service_selection_next.get_attribute("onclick") | |
# driver.execute_script(service_selection_next_onclick) | |
# https://stackoverflow.com/questions/1629053/typing-the-enter-return-key-using-python-and-selenium | |
# service_selection_next.send_keys(Keys.RETURN) | |
# service_selection_next.send_keys(Keys.RETURN) | |
num_next_clicks = 0 | |
while True: | |
service_selection() | |
print("Waiting 15 seconds for page to load") | |
num_next_clicks+=1 | |
time.sleep(15) | |
print("Checking if there's any appointments") | |
try: | |
no_dates = driver.find_elements_by_xpath("//*[text()[contains(., 'There are currently no dates available for the selected service! Please try again later.')]]") | |
print("No appointments") | |
print("Have clicked next %d times" % num_next_clicks) | |
print("Going to try again...") | |
except: | |
print("SELECT APPOINTMENT!!!!") | |
create_and_send_email("jeffreykozik8@gmail.com", OVERALL_RECEIVER, "SELECT APPOINTMENT!!!", "Selenium Script has found appointment!!", service) | |
print("Sent email urging you to sign up for an appointment.") | |
chime_n(10) | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment