Skip to content

Instantly share code, notes, and snippets.

@oxyc
Created February 6, 2013 15:52
Show Gist options
  • Save oxyc/4723474 to your computer and use it in GitHub Desktop.
Save oxyc/4723474 to your computer and use it in GitHub Desktop.
#!/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])
print
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