Created
June 9, 2021 12:48
-
-
Save david-caro/c6826aede8772f1f947a587b8dfda87a 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
#!/usr/bin/env python3 | |
import requests | |
import datetime | |
import click | |
import asyncio | |
import getpass | |
from pyppeteer import launch | |
from typing import List, Optional | |
BASE_URL = "https://globalunity.safeguardglobal.com" | |
LOGIN_URL = f"{BASE_URL}/login" | |
CLOCK_URL = "https://globalunity.safeguardglobal.com/myself/clocking" | |
def add_cookies(session: requests.Session, cookiejar): | |
for cookie in cookiejar: | |
params = { | |
"name": cookie["name"], | |
"value": cookie["value"], | |
"domain": cookie["domain"], | |
} | |
if "path" in cookie: | |
params["path"] = cookie["path"] | |
if "expires" in cookie: | |
params["expires"] = cookie["expires"] | |
if "secure" in cookie: | |
params["secure"] = cookie["secure"] | |
requests_cookie = requests.cookies.create_cookie(**params) | |
session.cookies.set_cookie(requests_cookie) | |
return session | |
async def main(dates: List[str], user: str, password: str): | |
browser = await launch() | |
page = await browser.newPage() | |
# Log in | |
await page.goto(LOGIN_URL) | |
await page.screenshot({"path": "example.jpeg"}) | |
await page.type('input[name="password"]', password) | |
await page.type('input[name="email"]', user) | |
await page.screenshot({"path": "example.jpeg"}) | |
await asyncio.gather(page.waitForNavigation(), page.click("button")) | |
await page.screenshot({"path": "example.jpeg"}) | |
for _ in range(2): | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
for date in dates: | |
await clockin_date(date_str=date, browser=browser, page=page) | |
await browser.close() | |
async def clockin_date(date_str: str, browser, page): | |
await page.goto(CLOCK_URL) | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
# Clock in | |
await page.click("span.forgot-clock-span") | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
await page.type("input.datepicker", "") | |
for _ in "YYYY-MM-DD": | |
await page.keyboard.press("Backspace") | |
await page.type("input.datepicker", date_str) | |
await page.select("#ddlHours", "09") | |
await page.select("#ddlMinutes", ":00") | |
matches = await page.querySelectorAll("input.form-control") | |
await matches[-1].click() | |
await asyncio.sleep(.5) | |
await page.keyboard.press("Backspace") | |
await matches[-1].type(".") | |
await page.screenshot({"path": "example.jpeg"}) | |
await page.keyboard.press("Tab") | |
await page.keyboard.press("Tab") | |
await page.keyboard.press("Enter") | |
# await page.click(".clockin-button", {"delay": .5}) | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
# Clock out | |
await page.click("span.forgot-clock-span") | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
await page.type("input.datepicker", "") | |
for _ in "YYYY-MM-DD": | |
await page.keyboard.press("Backspace") | |
await page.type("input.datepicker", date_str) | |
await page.select("#ddlHours", "18") | |
await page.select("#ddlMinutes", ":00") | |
matches = await page.querySelectorAll("input.form-control") | |
await matches[-1].click() | |
await asyncio.sleep(.5) | |
await page.keyboard.press("Backspace") | |
await matches[-1].type(".") | |
await page.keyboard.press("Tab") | |
await page.keyboard.press("Tab") | |
await page.keyboard.press("Tab") | |
await page.keyboard.press("Enter") | |
await asyncio.sleep(1) | |
await page.screenshot({"path": "example.jpeg"}) | |
def parse_date(maybe_date: str) -> str: | |
year, month, day = maybe_date.split("-") | |
date = datetime.datetime(year=int(year), month=int(month), day=int(day)) | |
return date | |
def get_dates_in_range_iter( | |
start_date: datetime.datetime, | |
end_date: Optional[datetime.datetime], | |
) -> List[datetime.datetime]: | |
if not end_date: | |
if start_date.weekday() < 5: | |
yield start_date | |
return | |
next_date = start_date | |
while next_date <= end_date: | |
# 5 Sat, 6 Sun | |
if next_date.weekday() < 5: | |
yield next_date | |
next_date = next_date + datetime.timedelta(days=1) | |
@click.command() | |
@click.argument("start-date") | |
@click.option("-e", "--end-date", default=None) | |
@click.option("-u", "--user", required=True) | |
def cli(start_date: str, end_date: Optional[str], user: str): | |
password = getpass.getpass("Enter your password: ") | |
dates = [ | |
date.strftime("%Y-%m-%d") | |
for date in get_dates_in_range_iter( | |
start_date=parse_date(start_date), | |
end_date=parse_date(end_date) if end_date else None, | |
) | |
] | |
print(f"Clocking in for the dates: {dates}") | |
asyncio.get_event_loop().run_until_complete( | |
main(dates=dates, user=user, password=password) | |
) | |
if __name__ == "__main__": | |
cli() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment