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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
#!/usr/bin/python2
import argparse, os, re, subprocess, sys, time
from datetime import datetime, date, timedelta
def msg(cmdargs,msg):
if cmdargs.silent is False:
print "%s" %msg
def mythshutdownlock_check(cmdargs,cursor):
if (cmdargs.lock):
msg(cmdargs," Checking mythshutdown for lock...")
try:
cursor.execute("select data from settings where value = 'MythShutdownLock'")
results=cursor.fetchone()
except:
return True
lock=results[0]
if int(lock) == 0 :
msg(cmdargs," mythshutdown is NOT locked.")
return True
else:
msg(cmdargs," mythshutdown is locked.")
return False
else:
return True
def dailywake_check(cmdargs,cursor):
if (cmdargs.daily):
msg(cmdargs," Checking if in a daily wake period...")
dailyWake=False
today = date.today()
now = datetime.now()
try:
cursor.execute("select data from settings where value = 'DailyWakeupStartPeriod1'")
results=cursor.fetchone()
p1Start=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M")
cursor.execute("select data from settings where value = 'DailyWakeupEndPeriod1'")
results=cursor.fetchone()
p1End=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M")
cursor.execute("select data from settings where value = 'DailyWakeupStartPeriod2'")
results=cursor.fetchone()
p2Start=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M")
cursor.execute("select data from settings where value = 'DailyWakeupEndPeriod2'")
results=cursor.fetchone()
p2End=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M")
except:
print "error"
return True
# Check for time periods that cross midnight
if (p1End < p1Start):
if (now > p1End):
p1End = p1End + timedelta(days=1)
else:
p1Start = p1Start + timedelta(days=-1)
if (p2End < p2Start):
if (now > p2End):
p2End = p2End + timedelta(days=1)
else:
p2Start = p2Start + timedelta(days=-1)
#Check for one of the daily wakeup periods
if (p1Start != p1End):
if (now >= p1Start and now <= p1End):
msg(cmdargs," Currently in daily wake period 1.")
return False
if (p2Start != p2End):
if (now >= p2Start and now <= p2End):
msg(cmdargs," Currently in daily wake period 2.")
return False
#Are we about to start a daily wakeup period using the -t TIME var
if (p1Start != p1End):
delta=p1Start-now
if (delta.seconds >= 0 and delta.seconds <= cmdargs.time * 60):
msg(cmdargs," Daily wake period 1 will start in less than %s minutes." %cmdargs.time)
return False
if (p2Start != p2End):
delta=p2Start-now
if (delta.seconds >= 0 and delta.seconds <= cmdargs.time * 60):
msg(cmdargs," Daily wake period 2 will start in less than %s minutes." %cmdargs.time)
return False
msg(cmdargs," Currently NOT in a daily wake period.")
return True
else:
return True
def schemalock_check(cmdargs,cursor):
msg(cmdargs," Checking if the schema is locked...")
try:
cursor.execute("select count(*) from schemalock")
results=cursor.fetchone()
except:
return True
schemalock=results[0]
if schemalock == 0:
msg(cmdargs," The schema is NOT locked.")
return True
else:
msg(cmdargs," The schema is locked.")
return False
def in_use(cmdargs,cursor):
msg(cmdargs," Checking if programs are in use...")
try:
cursor.execute("select count(*) from inuseprograms")
results=cursor.fetchone()
except:
return True
prginuse=results[0]
if prginuse == 0 :
msg(cmdargs," Programs are NOT in use.")
return True
else:
msg(cmdargs," Programs are in use.")
return False
def job_check(cmdargs,cursor):
msg(cmdargs," Checking jobqueue for active jobs...")
try:
cursor.execute("select count(*) from jobqueue where status between 2 and 5")
results=cursor.fetchone()
except:
return True
jobs=results[0]
if jobs == 0 :
msg(cmdargs," No jobs are active.")
return True
else:
msg(cmdargs," Jobs are active.")
return False
def upcoming_check(cmdargs,mythBE):
msg(cmdargs," Checking for recordings in the next %s minutes..." %cmdargs.time)
try:
upcoming = mythBE.getUpcomingRecordings()
except:
msg(cmdargs," Could not get upcoming recordings.")
return True
time_diff=10000
r=0
for i in upcoming:
r += 1
if r > 1:
break
show=str(i)
show=show.strip()
showtime=re.split("[-+]\d\d:\d\d",str(i.starttime))[0]
now=time.time()
rec_time=time.strptime( showtime ,"%Y-%m-%d %H:%M:%S" )
r=time.mktime(rec_time)
time_diff = ( r - now ) / 60
if ( time_diff > cmdargs.time) :
msg(cmdargs," No recordings starting in %s minutes." %cmdargs.time)
return True
else:
msg(cmdargs," A recording is starting in %s minutes." %int(time_diff))
return False
def mfd_check(cmdargs):
msg(cmdargs," Checking if mythfilldatabase is running...")
with open(os.devnull, "w") as fnull:
mythfilldatabase_ret = subprocess.call(["pidof", "mythfilldatabase"], stdout=fnull)
if mythfilldatabase_ret == 0 :
msg(cmdargs," mythfilldatabase is running.")
return False
else:
msg(cmdargs," mythfilldatabase is NOT running.")
return True
def mythtvsetup_check(cmdargs):
msg(cmdargs," Checking if mythtv-setup is running...")
with open(os.devnull, "w") as fnull:
mythsetup_ret = subprocess.call(["pidof", "mythtv-setup"], stdout=fnull)
if mythsetup_ret == 0 :
msg(cmdargs," mythtv-setup is running.")
return False
else:
msg(cmdargs," mythtv-setup is NOT running.")
return True
def userlogins_check(cmdargs):
if (cmdargs.logins):
u=False
msg(cmdargs," Checking for users logged in...")
users=subprocess.check_output("who")
names=([x.split() for x in users.splitlines()])
for i in names:
if (i[0] == "mythtv" and i[4] == "(:0)"):
msg(cmdargs," Ignoring %s %s" %(i[0],i[4]))
else:
msg(cmdargs," User logged in: %s %s" %(i[0],i[4]))
u=True
if u:
return False
else:
return True
else:
return True
def sambafiles_check(cmdargs):
if (cmdargs.sambafiles):
msg(cmdargs," Checking if Samba files are in use...")
try:
smbstatus=subprocess.check_output(["smbstatus", "-L"])
except:
smbstatus="No locked files"
if "No locked files" in smbstatus:
msg(cmdargs," Samba files are NOT in use.")
return True
else:
msg(cmdargs," Samba files are in use.")
return False
else:
return True
def mythfe_check(cmdargs,cursor,mythDB):
#checks to see if a frontend is considered idle
# True means FE is idle
if ( cmdargs.runningfe ):
msg(cmdargs," Checking for running and playing mythfrontends...")
else:
msg(cmdargs," Checking for playing mythfrontends...")
try:
cursor.execute("select distinct hostname from settings where hostname is not null;")
frontends=cursor.fetchall()
except:
return True
for i in frontends:
try:
msg(cmdargs," Checking %s's mythfrontend status..." %i)
frontend = mythDB.getFrontend(''.join(i))
if ( cmdargs.runningfe ):
msg(cmdargs," %s's mythfrontend is RUNNING." %i)
return False
location = frontend.sendQuery('Location')
if location == "standbymode":
msg(cmdargs," %s's mythfrontend is in Standby Mode." %i)
continue
if ( location.startswith('Playback ') ):
msg(cmdargs," %s's mythfrontend is PLAYING." %i)
return False
else:
msg(cmdargs," %s's mythfrontend is NOT playing." %i)
if '.xml' in location or 'mainmenu' in location:
msg(cmdargs," %s's mythfrontend is in MENUS." %i)
else:
#FE is not in menus, so it must be active in a plugin
msg(cmdargs," %s's mythfrontend is NOT in menus." %i)
return False
except:
msg(cmdargs," Could not connect to %s's mythfrontend." %i)
if ( cmdargs.runningfe ):
msg(cmdargs," mythfrontends are not running or playing or are in menus.")
else:
msg(cmdargs," mythfrontends are not playing or are in menus.")
return True
def usage():
line = '''
idle.py checks if the system is idle.
Use idle.py -h to see options.
idle.py checks these parts of the system in this order to
determine if it is idle:
- (option -g) users are logged in return busy
ignores mythtv (:0) for busy
- (option -f) Samba files are in use return busy
- (option -l) mythshutdown is locked return busy
- (option -d) in a daily wake period or
about to start a daily wake period return busy
checks the next 15 minutes. -t TIME changes time
- schema is locked return busy
- there are in use programs return busy
- there are active jobs in the job queue return busy
- mythfilldatabase is running return busy
- mythtv-setup is running return busy
- there are upcoming recordings return busy
checks the next 15 minutes. -t TIME changes time
- (option -r) mythfrontends running return busy
- mythfrontends playing back a recording or video return busy
- mythfrontends not in menus return busy
idle.py stops checking and returns false (busy) when the first busy is found.
'''
print line
sys.exit(0)
def main(args=[False]):
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--daily', action='store_true', help='Include daily wake & about to start wake in system busy. (default: daily wake & about to start wake is system idle)')
parser.add_argument('-g', '--logins', action='store_true', help='Include user logins in system busy. Ignores mythtv (:0) in system busy.')
parser.add_argument('-f', '--sambafiles', action='store_true', help='Include Samba files in use in system busy.')
parser.add_argument('-l', '--lock', action='store_true', help='Include mythshutdown lock in system busy. (default: mythshutdown lock is system idle)')
parser.add_argument('-r', '--runningfe', action='store_true', help='Include running mythfrontends in system busy. (default: running mythfrontends are system idle)')
parser.add_argument('-s', '--silent', action='store_true', help='Run without printing output. Recommended for use in cron jobs or scripts.')
parser.add_argument('-t', '--time', type=int, default=15, help='Minutes of idle time needed to return idle for upcoming recordings and daily wake.')
parser.add_argument('-u', '--usage', action='store_true', help='Print usage instructions.')
if args[0] is False:
cmdargs = parser.parse_args()
else:
cmdargs = parser.parse_args(args)
if cmdargs.usage:
usage()
idle=True
msg(cmdargs,"Checking system idle...")
if (userlogins_check(cmdargs)):
idle = True
else:
idle = False
if (idle and sambafiles_check(cmdargs)):
idle = True
else:
idle = False
try:
from MythTV import MythDB
mythDB = MythDB()
cursor = mythDB.cursor()
db_conn=True
except:
msg(cmdargs,"Couldn't connect to MythTV database.")
db_conn=False
try:
from MythTV import MythBE
mythBE = MythBE()
be_conn=True
except:
msg(cmdargs,"Couldn't connect to MythTV backend.")
be_conn=False
if ( db_conn and idle ):
if (mythshutdownlock_check(cmdargs,cursor) and dailywake_check(cmdargs,cursor) and schemalock_check(cmdargs,cursor) and in_use(cmdargs,cursor) and job_check(cmdargs,cursor)):
idle=True
else:
idle=False
if ( be_conn and idle ):
if (mfd_check(cmdargs) and mythtvsetup_check(cmdargs) and upcoming_check(cmdargs,mythBE)):
idle=True
else:
idle=False
if ( db_conn and idle ):
if (mythfe_check(cmdargs,cursor,mythDB)):
idle=True
else:
idle=False
if ( idle ):
msg(cmdargs,"System is idle.")
else:
msg(cmdargs,"System is busy.")
return idle
if __name__ == "__main__":
idle=main()
if ( idle ):
exit(0)
else:
exit(1)
|