Created
February 16, 2017 22:58
-
-
Save Palisand/0b19f5ca8cf00cb5dc8cdc68b1b354b3 to your computer and use it in GitHub Desktop.
Time Puncher
This file contains hidden or 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/local/bin/python | |
import sys | |
import ast | |
import inspect | |
import keyring # for storing password in OS X Keychain | |
from datetime import datetime | |
from subprocess import check_output | |
from astunparse import unparse | |
from grab import Grab | |
from getpass import getpass | |
CLOCK_IN = True | |
AST_INDEX = (inspect.currentframe().f_lineno - 4) # index of tree node holding CLOCK_IN Assign | |
USERNAME = '1450398' | |
SERVICE_NAME = 'ct' # as it will appear on OS X Keychain | |
PT_IN = 'timeIn' | |
PT_OUT = 'timeOut' | |
def pt_to_str(pt): | |
# "timeIn" -> "In" | |
return pt.lstrip('time') | |
def get_and_set_password(): | |
password = getpass('password: ') | |
keyring.set_password(SERVICE_NAME, USERNAME, password) | |
return password | |
if "-p" in sys.argv: # when password reset time comes around | |
password = get_and_set_password() | |
else: | |
password = keyring.get_password(SERVICE_NAME, USERNAME) or get_and_set_password() | |
# manual clock in/out or automatic (based on CLOCK_IN value) | |
if "in" in sys.argv: | |
punch_type = PT_IN | |
elif "out" in sys.argv: | |
punch_type = PT_OUT | |
else: | |
punch_type = PT_IN if CLOCK_IN else PT_OUT | |
g = Grab() | |
g.setup(follow_location=True) # this might not be necessary | |
try: | |
# login | |
g.go("CITY TIME URL") | |
g.doc.set_input('username', USERNAME) | |
g.doc.set_input('password', password) | |
g.doc.set_input('startPage', 'webClock') | |
g.doc.submit() # does not take you to webClock, ahhh city time... | |
# clock in/out | |
g.go("WEB CLOCK URL") | |
g.doc.set_input('punchType', punch_type) | |
g.doc.submit() | |
except Exception as e: | |
print("Failed to clock {}: {}".format(pt_to_str(punch_type), e)) | |
else: | |
print("Clocked {} at {}".format(pt_to_str(punch_type), datetime.now())) | |
# parse this file into an abstract syntax tree | |
with open(__file__) as fp: | |
tree = ast.parse(fp.read()) | |
# set CLOCK_IN value based on punch type | |
tree.body[AST_INDEX].value.id = str(punch_type != PT_IN) | |
# 'update' this file with the new value | |
with open(__file__, 'w') as fp: | |
# comments (including shebang) are not part of the syntax tree and will not be preserved | |
fp.write(('#!' + str(check_output(['which', 'python'])))) | |
fp.write(unparse(tree)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Tested only with Python 2.7
./ct.py [in|out] [-p]
Dependencies: