From 7d2a37010458dc1c401c6ec91b5539ccaea27d6a Mon Sep 17 00:00:00 2001 From: Andrew Davidson Date: Thu, 16 Aug 2012 17:41:05 -0700 Subject: [PATCH] work done to indenture... not yet functional --- indenture.py | 216 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/indenture.py b/indenture.py index 224e267..33da8d3 100644 --- a/indenture.py +++ b/indenture.py @@ -3,3 +3,219 @@ # Fire up virtualenv activate_this = "venv/bin/activate_this.py" execfile(activate_this, dict(__file__=activate_this)) + +import os +import time +import uuid +from subprocess import call +import sqlite3 + +# Job Class +class Job: + def __init__(self, due = time.time() + 3600, command = 'true', originator = 'indenture', + completed = False, arguments = ''): + self.arguments = arguments + self.due = due + self.command = command + self.uuid = uuid.uuid4() + self.originator = originator + self.completed = completed + + def _connect(self, db="jobs.db"): + """ _connect() + connects to the sqlite database, uses a try/except to return False if it fails + """ + try: + self._conn = sqlite3.connect('jobs.db') + self._c = self._conn.cursor() + return True + except: + return False + + def _full_exec(self): + """ _full_exec() + returns the full command to be executed with the arguments + """ + return self.command+' '+self.arguments + + def _query(self,query,returns="list",timeout=10,db="jobs.db"): + """ _query() + run a query against the sqlite database. will attempt to reconnect if necessary. + will timeout after $timeout seconds. + """ + t = time.time() + timeout + while True: + try: + self._c.execute(query) + break + except: + if db != "jobs.db": + self.connect(db=db) + else: + self._connect() + time.sleep(2) + + if time.time() > t: + print 'ERROR: Query timed out.' + break + + if returns == "list": + return self._c.fetchall() + elif returns == "one": + return self._c.fetchone() + + + + def _disconnect(self): + """ _disconnect() + flushes writes to sqlite and closes the connection + """ + self._conn.commit() + self._c.close() + + def describe(self): + """ describe(): + a public function that describes the job to be completed. + """ + description = [] + description.append('UUID: ' + self.uuid) + description.append('Commmand: ' + self._full_exec) + description.append('Due Date: ' + self.what_time()) + if self.completed: + description.append('Completion: Completed') + else: + description.append('Completion: Incomplete') + + print '\n'.join(description) + return '\n'.join(description) + + + + def do_work(self): + """ do_work() + actually performs the work to be completed. + """ + return call(self.full_exec().split()) + + def list_jobs(self, include_completed=False): + """ list_jobs(include_completed = False) + list all the jobs that need to be done, does not include completed + jobs by default. + """ + + query = 'SELECT * FROM jobs' + if include_completed == False: + query += ' WHERE `completed` = 0' + query += ';' + + for row in self._query(query): + print row + + def open(self, uuid): + """ open() + runs a query to populate with the information of an existing job + in the database + """ + print uuid + print "Opening" + data = self._query('SELECT * FROM jobs WHERE uuid = "' + uuid + '" LIMIT 1;', returns="one") + print data + + + def save(self): + """ save() + saves the current job to the database. will determine if it's + necessary insert a new job or update an old job. + """ + print 'Does this ID exist?' + test = 'SELECT uuid FROM jobs WHERE uuid = "' + str(self.uuid) + '";' + print test + if self._query(test): + print 'Yes.' + query = 'UPDATE jobs SET ' + query += 'uuid = "' + str(self.uuid) + '", ' + query += 'command = "' + self.command + '", ' + query += 'arguments = "' + self.arguments + '", ' + query += 'due = "' + str(self.due) + '", ' + query += 'originator = "' + self.originator + '", ' + if self.completed: + query += 'completed = 1' + else: + query += 'completed = 0' + query += ';' + print self._query(query) + self._conn.commit() + else: + print 'No.' + query = 'INSERT INTO jobs (uuid, command, arguments, due, originator, completed) ' + query += 'VALUES (' + query += '"' + str(self.uuid) + '",' + query += '"' + self.command + '",' + query += '"' + self.arguments + '",' + query += '"' + str(self.due) + '",' + query += '"' + self.originator + '",' + if self.completed: + query += str(1) + else: + query += str(0) + query += ');' + print 'Executing: ' + print query + self._query(query) + self._conn.commit() + + def what_time(self): + """ what_time() + returns a prettified version of the due date. + """ + return pretty(self.due) + + + def what_work(self): + """ what_work() + public function to see what work is going to be done. + """ + return self._full_exec() + + + + + + +def pretty(time): + '''Returns a pretty formatted date. + Inputs: + time is a datetime object or an int timestamp + asdays is True if you only want to measure days, not seconds + short is True if you want "1d ago", "2d ago", etc. False if you want + ''' + + import datetime + + now = datetime.datetime.now() + if type(time) is float: time = datetime.datetime.fromtimestamp(time) + elif not time: time = now + + if time > now: past, diff = False, time - now + else: past, diff = True, now - time + seconds = diff.seconds + days = diff.days + + if days == 0 and not asdays: + if seconds < 10: return 'now' + elif seconds < 60: return _df(seconds, 1, ' seconds', past) + elif seconds < 120: return past and 'a minute ago' or 'in a minute' + elif seconds < 3600: return _df(seconds, 60, ' minutes', past) + elif seconds < 7200: return past and 'an hour ago' or'in an hour' + else: return _df(seconds, 3600, ' hours', past) + else: + if days == 0: return 'today' + elif days == 1: return past and 'yesterday' or'tomorrow' + elif days == 2: return past and 'day before' or 'day after' + elif days < 7: return _df(days, 1, ' days', past) + elif days < 14: return past and 'last week' or 'next week' + elif days < 31: return _df(days, 7, ' weeks', past) + elif days < 61: return past and 'last month' or 'next month' + elif days < 365: return _df(days, 30, ' months', past) + elif days < 730: return past and 'last year' or 'next year' + else: return _df(days, 365, ' years', past)