forked from robweber/cronxbmc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
service.py
156 lines (122 loc) · 5.54 KB
/
service.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import time
import xbmc
import xbmcaddon
import xml.dom.minidom
import datetime
import os
from resources.lib.croniter import croniter
class CronJob:
def __init__( self):
self.name = ""
self.command = ""
self.expression = []
self.show_notification = "false"
class CronXbmc:
addon_id = "service.cronxbmc"
Addon = xbmcaddon.Addon(addon_id)
datadir = Addon.getAddonInfo('profile')
addondir = Addon.getAddonInfo('path')
sleep_time = 10
last_check = -1
def runProgram(self):
#run until XBMC quits
while(not xbmc.abortRequested):
structTime = time.localtime()
now = time.time()
#only do all this if we are in a new minute
if(structTime[4] != self.last_check):
self.last_check = structTime[4]
#get a list of all the cron jobs
cron_jobs = self.readCronFile()
for command in cron_jobs:
#create a cron expression for this command
cron_exp = croniter(command.expression,datetime.datetime.fromtimestamp(now - 60))
self.nextRun(command)
runTime = cron_exp.get_next(float);
#if this command should run then run it
if(runTime <= now):
self.runJob(command)
self.log(command.name + " will run again on " + datetime.datetime.fromtimestamp(cron_exp.get_next(float)).strftime('%m-%d-%Y %H:%M'))
#get as close to the top of each minute as we can
self.sleep_time = 10 - (time.time() % 60 % 10)
if(int(self.sleep_time) == 0):
self.sleep_time = 10
time.sleep(self.sleep_time)
def runJob(self,cronJob,override_notification = False):
self.log("running command " + cronJob.name)
if(cronJob.show_notification == "true" or override_notification):
#show a notification that this command is running
xbmc.executebuiltin("Notification(Cron XBMC," + cronJob.name + " is executing,2000," + xbmc.translatePath(self.addondir + "/icon.png") + ")")
#run the command
xbmc.executebuiltin(cronJob.command)
def readCronFile(self):
if(not os.path.exists(xbmc.translatePath(self.datadir))):
os.makedirs(xbmc.translatePath(self.datadir))
adv_jobs = []
try:
doc = xml.dom.minidom.parse(xbmc.translatePath(self.datadir + "cron.xml"))
for node in doc.getElementsByTagName("job"):
tempJob = CronJob()
tempJob.name = str(node.getAttribute("name"))
tempJob.command = str(node.getAttribute("command"))
tempJob.expression = str(node.getAttribute("expression"))
tempJob.show_notification = str(node.getAttribute("show_notification"))
adv_jobs.append(tempJob)
except IOError:
#the file doesn't exist, return empty array
doc = xml.dom.minidom.Document()
rootNode = doc.createElement("cron")
doc.appendChild(rootNode)
#write the file
f = open(xbmc.translatePath(self.datadir + "cron.xml"),"w")
doc.writexml(f," ")
f.close()
return adv_jobs
def writeCronFile(self,job,overwrite=-1):
#read in the cron file
try:
doc = xml.dom.minidom.parse(xbmc.translatePath(self.datadir + "cron.xml"))
rootNode = doc.getElementsByTagName("cron")[0]
#create the child
newChild = doc.createElement("job")
newChild.setAttribute("name",job.name)
newChild.setAttribute("expression",job.expression)
newChild.setAttribute("command",job.command)
newChild.setAttribute("show_notification",job.show_notification)
if overwrite >= 0:
#we are modifying an existing job
oldJob = rootNode.getElementsByTagName("job")[overwrite]
rootNode.replaceChild(newChild,oldJob)
else:
#we are writing a new job
rootNode.appendChild(newChild)
#write the file
f = open(xbmc.translatePath(self.datadir + "cron.xml"),"w")
doc.writexml(f," ")
f.close()
except IOError:
self.log("error writing cron file")
def nextRun(self,cronJob):
#create a cron expression
cron_exp = croniter(cronJob.expression,datetime.datetime.fromtimestamp(time.time()))
#compare now with next date
nextRun = cron_exp.get_next(float)
cronDiff = nextRun - time.time()
hours = int((cronDiff / 60) / 60)
minutes = int(cronDiff / 60 - hours * 60)
#we always have at least one minute
if minutes == 0:
minutes = 1
result = str(hours) + " h " + str(minutes) + " m"
if hours == 0:
result = str(minutes) + " m"
elif hours > 36:
#just show the date instead
result = datetime.datetime.fromtimestamp(nextRun).strftime('%m/%d %I:%M%p')
elif hours > 24:
days = int(hours / 24)
hours = hours - days * 24
result = str(days) + " d " + str(hours) + " h " + str(minutes) + " m"
return result
def log(self,message):
xbmc.log('service.cronxbmc: ' + message)