-
-
Save oxyc/4723474 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 python2 | |
import sys, json, time, datetime, re, argparse, os.path, pickle | |
from netrc import netrc | |
from urllib2 import Request, urlopen | |
from base64 import encodestring | |
class DayAction(argparse.Action): | |
def __call__(self, parser, namespace, values, option_string=None): | |
today = datetime.date.today() | |
if values == 'today': | |
values = today | |
elif values == 'tomorrow': | |
values = (today + datetime.timedelta(days=1)).strftime('%Y-%m-%d') | |
elif re.match('^[\+\-]\d+$', values or ''): | |
values = (today + datetime.timedelta(days=int(values))).strftime('%Y-%m-%d') | |
setattr(namespace, self.dest, values) | |
parser = argparse.ArgumentParser(description="""Fetch ARBS calendar using ARMS. | |
Authentication information can be stored in your .netrc under arms.staffanenberg.com""") | |
parser.add_argument('-u', '--user', help='ARMS username') | |
parser.add_argument('-p', '--password', help='ARMS password') | |
parser.add_argument('--past', help='Include the past', | |
action='store_true', default=False) | |
parser.add_argument('-f', '--force', help='Force a cache refresh', | |
action='store_true', default=False) | |
parser.add_argument('--format', help='Specify the output format passed to format()', | |
default="{0}-{1}\t{2} ({3})") | |
parser.add_argument('--separator', help='Specify the separator beneath the day name', | |
default="="*80) | |
parser.add_argument('--date_format', help='Specify the date format for strftotime().', | |
default="%a %d %B") | |
parser.add_argument('day', help="""Specific day to display, either as | |
YYYY-MM-DD, "today", "tomorrow", +offset, -offset""", | |
action=DayAction, nargs='?') | |
toTime = lambda timestamp: time.strftime('%H:%M', time.localtime(int(timestamp))) | |
arms_url = 'http://arms.staffanenberg.com/api/v1/arbs/%s' | |
args = parser.parse_args() | |
cache_file = '/tmp/arms/arms_%s' % args.day | |
cache_time = 60 * 60 | |
def main(): | |
if args.force or not cacheIsValid(cache_file): | |
cache_dir = os.path.dirname(cache_file) | |
data = fetchFreshData() | |
if not os.path.isdir(cache_dir): | |
os.makedirs(cache_dir) | |
pickle.dump(data, open(cache_file, 'w')) | |
else: | |
data = pickle.load(open(cache_file, 'r')) | |
if isinstance(data, IOError): | |
print data | |
sys.exit(1) | |
if args.day == None: | |
if not args.past: | |
today = datetime.date.today().strftime("%Y-%m-%d") | |
data = dict((key, value) for key, value in data.iteritems() if key >= today) | |
for day in sorted(data, reverse=True): | |
date_string = datetime.datetime.strptime(day, "%Y-%m-%d").strftime(args.date_format) | |
print date_string + '\n' + args.separator | |
outputLessons(data[day]) | |
elif len(data) > 0: | |
outputLessons(data) | |
else: | |
print "Nothing today" | |
def cacheIsValid(cache): | |
if not os.path.exists(cache): return False | |
return (os.path.getmtime(cache) + cache_time) > time.time() | |
def fetchFreshData(): | |
if args.user == None: | |
rc = netrc() | |
(args.user, args.host, args.password) = (netrc()).authenticators('arms.staffanenberg.com') | |
url = arms_url % (args.day if args.day else "") | |
data = getJson(url, args.user, args.password) | |
return data | |
def getJson(url, username, password): | |
req = Request(url) | |
auth = 'Basic %s' % encodestring('%s:%s' % (username, password))[:-1] | |
req.add_header('Authorization', auth); | |
try: | |
handle = urlopen(req) | |
return json.loads(handle.read()) | |
except IOError, e: | |
return e | |
def outputLessons(day): | |
for timestamp in sorted(day.items()): | |
for entry in timestamp[1]: | |
print args.format.format( | |
toTime(entry["start"]), | |
toTime(entry["end"]), | |
entry["summary"].encode('utf8'), | |
entry["location"].encode('utf8')) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment