2012-08-13 23:36:40 +00:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
# Fire up virtualenv
|
|
|
|
activate_this = "venv/bin/activate_this.py"
|
|
|
|
execfile(activate_this, dict(__file__=activate_this))
|
2012-08-17 00:41:05 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
"""
|
2012-08-17 01:54:59 +00:00
|
|
|
data = self._query('SELECT uuid,command,arguments,due,originator,completed FROM jobs WHERE uuid = "' + uuid + '" LIMIT 1;', returns="one")
|
2012-08-17 00:41:05 +00:00
|
|
|
print data
|
2012-08-17 01:54:59 +00:00
|
|
|
if data:
|
|
|
|
(self.uuid, self.command, self.arguments, self.due, self.originator, self.completed) = data
|
2012-08-17 00:41:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
"""
|
2012-08-17 01:54:59 +00:00
|
|
|
return pretty_date(self.due)
|
2012-08-17 00:41:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
def what_work(self):
|
|
|
|
""" what_work()
|
|
|
|
public function to see what work is going to be done.
|
|
|
|
"""
|
|
|
|
return self._full_exec()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-08-17 01:54:59 +00:00
|
|
|
def pretty_date(time=False):
|
|
|
|
"""
|
|
|
|
Get a datetime object or a int() Epoch timestamp and return a
|
|
|
|
pretty string like 'an hour ago', 'Yesterday', '3 months ago',
|
|
|
|
'just now', etc
|
|
|
|
"""
|
|
|
|
from datetime import datetime
|
|
|
|
now = datetime.now()
|
|
|
|
if type(time) is int:
|
|
|
|
d = datetime.fromtimestamp(time)
|
|
|
|
elif type(time) is float:
|
|
|
|
d = datetime.fromtimestamp(time)
|
|
|
|
elif not time:
|
|
|
|
diff = now - now
|
2012-08-17 00:41:05 +00:00
|
|
|
|
2012-08-17 01:54:59 +00:00
|
|
|
if now > d:
|
|
|
|
diff = now - d
|
|
|
|
elif d > now:
|
|
|
|
diff = d - now
|
2012-08-17 00:41:05 +00:00
|
|
|
else:
|
2012-08-17 01:54:59 +00:00
|
|
|
diff = now - now
|
|
|
|
|
|
|
|
second_diff = diff.seconds
|
|
|
|
day_diff = diff.days
|
|
|
|
|
|
|
|
if now > d:
|
|
|
|
if day_diff == 0:
|
|
|
|
if second_diff < 10:
|
|
|
|
return "just now"
|
|
|
|
if second_diff < 60:
|
|
|
|
return str(second_diff) + " seconds ago"
|
|
|
|
if second_diff < 120:
|
|
|
|
return "a minute ago"
|
|
|
|
if second_diff < 3600:
|
|
|
|
return str( second_diff / 60 ) + " minutes ago"
|
|
|
|
if second_diff < 7200:
|
|
|
|
return "an hour ago"
|
|
|
|
if second_diff < 86400:
|
|
|
|
return str( second_diff / 3600 ) + " hours ago"
|
|
|
|
if day_diff == 1:
|
|
|
|
return "Yesterday"
|
|
|
|
if day_diff < 7:
|
|
|
|
return str(day_diff) + " days ago"
|
|
|
|
if day_diff < 31:
|
|
|
|
return str(day_diff/7) + " weeks ago"
|
|
|
|
if day_diff < 365:
|
|
|
|
return str(day_diff/30) + " months ago"
|
|
|
|
return str(day_diff/365) + " years ago"
|
|
|
|
elif d > now:
|
|
|
|
if day_diff == 0:
|
|
|
|
if second_diff < 10:
|
|
|
|
return "just now"
|
|
|
|
if second_diff < 60:
|
|
|
|
return str(second_diff) + " seconds from now"
|
|
|
|
if second_diff < 120:
|
|
|
|
return "a minute from now"
|
|
|
|
if second_diff < 3600:
|
|
|
|
return str( second_diff / 60 ) + " minutes from now"
|
|
|
|
if second_diff < 7200:
|
|
|
|
return "an hour from now"
|
|
|
|
if second_diff < 86400:
|
|
|
|
return str( second_diff / 3600 ) + " hours from now"
|
|
|
|
if day_diff == 1:
|
|
|
|
return "Tomorrow"
|
|
|
|
if day_diff < 7:
|
|
|
|
return str(day_diff) + " days from now"
|
|
|
|
if day_diff < 31:
|
|
|
|
return str(day_diff/7) + " weeks from now"
|
|
|
|
if day_diff < 365:
|
|
|
|
return str(day_diff/30) + " months from now"
|
|
|
|
return str(day_diff/365) + " years from now"
|