And God said, "Let there be light"
This commit is contained in:
commit
b0e0a7e78d
8 changed files with 305 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
*.json
|
||||
__pycache__
|
||||
time.txt
|
||||
*.log
|
||||
55
mail.py
Executable file
55
mail.py
Executable file
|
|
@ -0,0 +1,55 @@
|
|||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.base import MIMEBase
|
||||
from email.mime.image import MIMEImage
|
||||
from email import encoders
|
||||
import smtplib
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
def take_screenshot():
|
||||
filename = "./screenshot.png"
|
||||
subprocess.call(["scrot", filename])
|
||||
return filename
|
||||
|
||||
|
||||
def send_email(login_file):
|
||||
picture_name = take_screenshot()
|
||||
|
||||
json_data = open(login_file).read()
|
||||
data = json.loads(json_data)
|
||||
fromaddr = toaddr = data["email_address"]
|
||||
password = data["password"]
|
||||
|
||||
msg = MIMEMultipart()
|
||||
|
||||
msg['From'] = fromaddr
|
||||
msg['To'] = toaddr
|
||||
msg['Subject'] = "Clock Status"
|
||||
|
||||
body = "Hello, world!"
|
||||
|
||||
msg.attach(MIMEText(body, 'plain'))
|
||||
|
||||
filename = "time.txt"
|
||||
#attachment = open("./time.txt", "rb")
|
||||
picture = open(picture_name, "rb")
|
||||
|
||||
#part = MIMEBase('application', 'octet-stream')
|
||||
#part.set_payload((attachment).read())
|
||||
#encoders.encode_base64(part)
|
||||
#part.add_header('Content-Disposition', "attachment; filename= %s" % filename)
|
||||
#msg.attach(part)
|
||||
|
||||
image = MIMEImage(picture.read(), name=os.path.basename(picture_name))
|
||||
msg.attach(image)
|
||||
|
||||
server = smtplib.SMTP('smtp.gmail.com', 587)
|
||||
server.starttls()
|
||||
server.login(fromaddr, password)
|
||||
text = msg.as_string()
|
||||
server.sendmail(fromaddr, toaddr, text)
|
||||
server.quit()
|
||||
|
||||
os.remove(picture_name)
|
||||
194
pyclock.py
Normal file
194
pyclock.py
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
import argparse
|
||||
import json
|
||||
import getpass
|
||||
import time
|
||||
import datetime as dt
|
||||
import os
|
||||
from enum import IntEnum
|
||||
from mail import send_email
|
||||
from selen_help import *
|
||||
|
||||
class Clock(IntEnum):
|
||||
In = 1
|
||||
Out = 2
|
||||
Meal = 3
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
@staticmethod
|
||||
def from_string(s):
|
||||
try:
|
||||
return Clock[s]
|
||||
except KeyError:
|
||||
raise ValueError()
|
||||
|
||||
|
||||
def login(driver, username, password):
|
||||
wait_for_internet_connection()
|
||||
|
||||
driver.get("https://accessuh.uh.edu")
|
||||
find_element(driver, By.ID, "param1").send_keys(username)
|
||||
find_element(driver, By.ID, "param2").send_keys(password)
|
||||
find_element(driver, By.XPATH, "/html/body/main/div/section/div[2]/form/div/div[1]/i/input").click()
|
||||
|
||||
elem = find_element(driver, By.XPATH, "/html/body/main/div/div[2]/div/div[2]/div[2]/a")
|
||||
driver.execute_script("arguments[0].setAttribute('target', '_self')",
|
||||
elem)
|
||||
driver.execute_script("arguments[0].click()",
|
||||
elem)
|
||||
|
||||
find_element(driver, By.ID, "win0divPTNUI_LAND_REC_GROUPLET$0").click()
|
||||
find_element(driver, By.ID, "PT_SIDE$PIMG").click()
|
||||
|
||||
|
||||
def select_action(driver, val):
|
||||
select = Select(find_element(driver, By.ID, 'TL_RPTD_TIME_PUNCH_TYPE$0'))
|
||||
select.select_by_value(str(int(val)))
|
||||
|
||||
|
||||
def submit_form(driver):
|
||||
elem = find_element(driver, By.ID, "TL_WEB_CLOCK_WK_TL_SAVE_PB")
|
||||
driver.execute_script("arguments[0].setAttribute('onclick', \"submitAction_win0(document.win0, 'TL_WEB_CLOCK_WK_TL_SAVE_PB')\")", elem)
|
||||
time.sleep(2)
|
||||
elem.click()
|
||||
|
||||
|
||||
def clock(action, username, password, email_status):
|
||||
driver = webdriver.Firefox()
|
||||
login(driver, username, password)
|
||||
|
||||
select_action(driver, action)
|
||||
|
||||
submit_form(driver)
|
||||
timeClocked = dt.datetime.now()
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
if email_status:
|
||||
send_email("./email.json")
|
||||
|
||||
time.sleep(3)
|
||||
driver.quit()
|
||||
|
||||
return timeClocked
|
||||
|
||||
|
||||
def clockAt(action, username, password, end_time, quiet, email_status):
|
||||
accurate_wait_until(end_time - dt.timedelta(seconds=30), quiet)
|
||||
|
||||
driver = webdriver.Firefox()
|
||||
login(driver, username, password)
|
||||
select_action(driver, action)
|
||||
|
||||
accurate_wait_until(end_time, quiet)
|
||||
|
||||
submit_form(driver)
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
if email_status:
|
||||
send_email("./email.json")
|
||||
|
||||
time.sleep(3)
|
||||
driver.quit()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('-c', '--clock', type=Clock.from_string, choices=list(Clock))
|
||||
group.add_argument('-b', '--both', action="store_true")
|
||||
group.add_argument('-d', '--delayed', action="store_true")
|
||||
group.add_argument("-i", "--interrupted", action="store_true")
|
||||
group.add_argument("-n", "--navigate", action="store_true")
|
||||
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument("-u", "--username")
|
||||
group.add_argument("-f", "--file")
|
||||
|
||||
parser.add_argument("-p", "--password")
|
||||
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("-et", "--elapsed_time", type=float)
|
||||
group.add_argument("-t", "--time")
|
||||
|
||||
parser.add_argument("-s", "--start")
|
||||
|
||||
parser.add_argument("-m", "--minutes", action="store_true", help="Use minutes instead of hours")
|
||||
|
||||
parser.add_argument("-q", "--quiet", action="store_true")
|
||||
parser.add_argument("-e", "--email", action="store_true", help="Specify if you want to send an email with a screenshot")
|
||||
|
||||
(args, extra) = parser.parse_known_args()
|
||||
|
||||
if(args.file is not None):
|
||||
json_data = open(args.file).read()
|
||||
data = json.loads(json_data)
|
||||
username = data["username"]
|
||||
password = data["password"]
|
||||
else:
|
||||
username = args.username
|
||||
if args.password is None:
|
||||
password = getpass.getpass()
|
||||
else:
|
||||
password = args.password
|
||||
|
||||
if args.clock is not None:
|
||||
clock(args.clock, username, password)
|
||||
elif args.navigate:
|
||||
login(webdriver.Firefox(), username, password)
|
||||
else:
|
||||
if args.elapsed_time is not None:
|
||||
if args.minutes:
|
||||
elapse_time = dt.timedelta(minutes=args.elapsed_time)
|
||||
else:
|
||||
elapse_time = dt.timedelta(hours=args.elapsed_time)
|
||||
|
||||
startTime = dt.datetime.now()
|
||||
|
||||
if args.both:
|
||||
startTime = clock(Clock.In, username, password, args.email)
|
||||
|
||||
if args.time:
|
||||
split = list(map(lambda x: int(x), args.time.split(':')))
|
||||
end_time = dt.datetime.now() \
|
||||
.replace(hour=split[0],
|
||||
minute=split[1],
|
||||
second=split[2])
|
||||
else:
|
||||
if args.interrupted:
|
||||
end_time = eval(open("time.txt", "r").read())
|
||||
else:
|
||||
end_time = startTime + elapse_time
|
||||
|
||||
f = open("time.txt", "w")
|
||||
f.write(repr(end_time))
|
||||
f.close()
|
||||
|
||||
clockAt(Clock.Out,
|
||||
username, password,
|
||||
end_time,
|
||||
args.quiet,
|
||||
args.email)
|
||||
|
||||
os.remove("time.txt")
|
||||
|
||||
|
||||
def accurate_sleep(delta_time, quiet):
|
||||
end_time = now + delta_time
|
||||
accurate_wait_until(end_time, quiet)
|
||||
|
||||
|
||||
def accurate_wait_until(end_time, quiet):
|
||||
now = dt.datetime.now()
|
||||
while(now < end_time):
|
||||
if not quiet:
|
||||
print("Time Left: " + str(end_time-now), end='\r')
|
||||
time.sleep(1)
|
||||
now = dt.datetime.now()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
3
redundancy/LaunchInterrupt
Executable file
3
redundancy/LaunchInterrupt
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
PYTHON3_PATH="/home/benson/anaconda3/bin/python" xfce4-terminal --hold -T "Clock" -e 'zsh -c "neofetch; cd ~/workspace/python/pyclock; $PYTHON3_PATH ./pyclock.py -i -f file.json"'
|
||||
3
redundancy/ProcessExists
Executable file
3
redundancy/ProcessExists
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
ps -aux | grep "pyclock.py" | grep -v "grep" | wc -l
|
||||
12
redundancy/restart.py
Executable file
12
redundancy/restart.py
Executable file
|
|
@ -0,0 +1,12 @@
|
|||
#!/home/benson/anaconda3/bin/python
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
base_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
result = subprocess.run(["%s/ProcessExists" % (base_dir)], stdout=subprocess.PIPE)
|
||||
res = int(result.stdout)
|
||||
|
||||
if res == 0 and os.path.isfile('%s/../time.txt' % (base_dir)):
|
||||
subprocess.Popen('%s/LaunchInterrupt' % (base_dir))
|
||||
else:
|
||||
print("Don't need to restart!")
|
||||
2
runfromcron
Executable file
2
runfromcron
Executable file
|
|
@ -0,0 +1,2 @@
|
|||
export DISPLAY=:1
|
||||
python3 pyclock.py -b -f file.json -et 5 -e
|
||||
32
selen_help.py
Normal file
32
selen_help.py
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
from selenium import webdriver
|
||||
from selenium.webdriver.support.ui import Select
|
||||
from selenium.webdriver.common.by import By
|
||||
import selenium.webdriver.common.by
|
||||
import urllib3
|
||||
import certifi
|
||||
import time
|
||||
|
||||
def find_element(driver, by, text):
|
||||
while True:
|
||||
try:
|
||||
return driver.find_element(by, text)
|
||||
except Exception:
|
||||
print("Waiting for page to load...", end='\r')
|
||||
|
||||
|
||||
def wait_for_internet_connection():
|
||||
message = False
|
||||
while True:
|
||||
try:
|
||||
urllib3.PoolManager(
|
||||
cert_reqs='CERT_REQUIRED',
|
||||
ca_certs=certifi.where()).request('GET', "https://google.com")
|
||||
# print('Good connection.')
|
||||
return True
|
||||
except Exception:
|
||||
if not message:
|
||||
print('No connection! Please connect to the internet to continue.')
|
||||
message = True
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
Loading…
Reference in a new issue