Skip to content

Instantly share code, notes, and snippets.

@david-caro
Created June 9, 2021 12:48
Show Gist options
  • Save david-caro/c6826aede8772f1f947a587b8dfda87a to your computer and use it in GitHub Desktop.
Save david-caro/c6826aede8772f1f947a587b8dfda87a to your computer and use it in GitHub Desktop.
#!/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