1
|
#!/usr/bin/env python3
|
2
|
# -*- coding: UTF-8 -*-
|
3
|
#Import recordings or add missing recordings
|
4
|
|
5
|
import json, urllib, time, datetime, subprocess, os, re, sys, uuid
|
6
|
reload(sys)
|
7
|
sys.setdefaultencoding('utf-8')
|
8
|
|
9
|
#Variables
|
10
|
oldlogdir = "/storage/log/"
|
11
|
url = "http://localhost:9981/"
|
12
|
recordingsdir = "/media/HDD1/Video/Aufnahmen/"
|
13
|
|
14
|
#write log
|
15
|
timestr = time.strftime("%Y-%m-%d")
|
16
|
logfile = open("TVHImport"+timestr+".log","a")
|
17
|
|
18
|
Newmask = """{
|
19
|
"start": 1000,
|
20
|
"stop": 1000,
|
21
|
"enabled": true,
|
22
|
"channel": "",
|
23
|
"channelname": "imported",
|
24
|
"creator": "imported",
|
25
|
"title": {
|
26
|
"ger": "my title"
|
27
|
},
|
28
|
"subtitle": {
|
29
|
"ger": ""
|
30
|
},
|
31
|
"description": {
|
32
|
"ger": ""
|
33
|
},
|
34
|
"errors": 0,
|
35
|
"data_errors": 0,
|
36
|
"playposition": 0,
|
37
|
"playcount": 0,
|
38
|
"noresched": true,
|
39
|
"comment": "added by ImportAddRecords.py",
|
40
|
"files": [
|
41
|
{
|
42
|
"filename": "/full/path/to/videofile.ts",
|
43
|
"start": 1000,
|
44
|
"stop": 1000
|
45
|
}
|
46
|
]
|
47
|
}"""
|
48
|
Newmask = Newmask.replace("\n", "") # remove the line feeds
|
49
|
|
50
|
def log(Text):
|
51
|
logtime = time.strftime("%H:%M:%S")
|
52
|
logfile.write(logtime+" "+Text+"\n")
|
53
|
|
54
|
def askyn(Text):
|
55
|
selection = raw_input(Text + " (y/n) ")
|
56
|
if selection == "n":
|
57
|
return False
|
58
|
elif selection == "y":
|
59
|
return True
|
60
|
else:
|
61
|
askyn(Text)
|
62
|
|
63
|
def testOldLogDir():
|
64
|
files = os.listdir(oldlogdir)
|
65
|
print str(len(files)) + " files in " + oldlogdir
|
66
|
log(str(len(files)) + " files in " + oldlogdir)
|
67
|
if not askyn("use this directory?"):
|
68
|
print ("Please edit the script!")
|
69
|
exit(1)
|
70
|
|
71
|
def testRecordingDir():
|
72
|
isExist = os.path.exists(recordingsdir)
|
73
|
if isExist:
|
74
|
print recordingsdir
|
75
|
log("Directory for recordings "+recordingsdir)
|
76
|
if not askyn("Is this the Directory for the recordings?"):
|
77
|
print ("Please edit the script!")
|
78
|
exit(1)
|
79
|
else:
|
80
|
log("The recording directory does not exist! " + recordingsdir)
|
81
|
print ("The recording directory does not exist!")
|
82
|
print ("Please edit the script!")
|
83
|
exit(1)
|
84
|
|
85
|
def getExistingRecordings():
|
86
|
apiurl = url+"api/dvr/entry/grid_finished?&limit=9999999"
|
87
|
filehandle = urllib.urlopen(apiurl)
|
88
|
Recordings = filehandle.read()
|
89
|
new_mask = json.loads(Recordings)
|
90
|
#print(json.dumps(new_mask, indent=4, sort_keys=True))
|
91
|
list = []
|
92
|
for entry in new_mask['entries']:
|
93
|
if 'files' in entry:
|
94
|
if 'filename' in entry['files'][0]:
|
95
|
list.append(entry['files'][0]['filename'])
|
96
|
if 'filename' in entry:
|
97
|
list.append(entry['filename'])
|
98
|
|
99
|
print "Found "+str(len(list))+" finsihed recordings"
|
100
|
log("Found "+str(len(list))+" finsihed recordings")
|
101
|
return list
|
102
|
|
103
|
def ImportRecordings():
|
104
|
print "1 - Check if recording exist"
|
105
|
print "2 - No check if recording exist"
|
106
|
selection = raw_input("Please select ")
|
107
|
|
108
|
finishedRecordings = getExistingRecordings()
|
109
|
|
110
|
files = os.listdir(oldlogdir)
|
111
|
firstok = False
|
112
|
firstimportok = False
|
113
|
for reclog in files:
|
114
|
f = open(oldlogdir+reclog,"r")
|
115
|
print "--------------------------------"
|
116
|
print "file:"
|
117
|
print reclog
|
118
|
log("--------------------------------")
|
119
|
log("file:")
|
120
|
log(reclog)
|
121
|
|
122
|
mask = f.read()
|
123
|
old_mask = json.loads(mask)
|
124
|
|
125
|
new_mask = json.loads(Newmask)
|
126
|
filename = ""
|
127
|
|
128
|
if 'enabled' in old_mask:
|
129
|
new_mask['enabled'] = old_mask['enabled']
|
130
|
if 'start' in old_mask:
|
131
|
new_mask['start'] = old_mask['start']
|
132
|
if 'stop' in old_mask:
|
133
|
new_mask['stop'] = old_mask['stop']
|
134
|
#if 'channel' in old_mask:
|
135
|
# new_mask['channel'] = old_mask['channel']
|
136
|
if 'channelname' in old_mask:
|
137
|
new_mask['channelname'] = old_mask['channelname']
|
138
|
if 'creator' in old_mask:
|
139
|
new_mask['creator'] = old_mask['creator']
|
140
|
if 'title' in old_mask:
|
141
|
new_mask['title'] = old_mask['title']
|
142
|
if 'subtitle' in old_mask:
|
143
|
new_mask['subtitle'] = old_mask['subtitle']
|
144
|
if 'description' in old_mask:
|
145
|
new_mask['description'] = old_mask['description']
|
146
|
if 'errors' in old_mask:
|
147
|
new_mask['errors'] = old_mask['errors']
|
148
|
if 'data_errors' in old_mask:
|
149
|
new_mask['data_errors'] = old_mask['data_errors']
|
150
|
if 'playposition' in old_mask:
|
151
|
new_mask['playposition'] = old_mask['playposition']
|
152
|
if 'playcount' in old_mask:
|
153
|
new_mask['playcount'] = old_mask['playcount']
|
154
|
if 'comment' in old_mask:
|
155
|
new_mask['comment'] = old_mask['comment']
|
156
|
|
157
|
if 'files' in old_mask:
|
158
|
new_mask['files'] = old_mask['files']
|
159
|
filename = old_mask['files'][0]['filename']
|
160
|
if 'start' in old_mask['files'][0]:
|
161
|
new_mask['start'] = old_mask['files'][0]['start']
|
162
|
if 'stop' in old_mask['files'][0]:
|
163
|
new_mask['stop'] = old_mask['files'][0]['stop']
|
164
|
else:
|
165
|
if 'filename' in old_mask:
|
166
|
new_mask['files'][0]['filename'] = old_mask['filename']
|
167
|
filename = old_mask['filename']
|
168
|
if 'start' in old_mask:
|
169
|
new_mask['files'][0]['start'] = old_mask['start']
|
170
|
if 'stop' in old_mask:
|
171
|
new_mask['files'][0]['stop'] = old_mask['stop']
|
172
|
|
173
|
#check if recording exist
|
174
|
if filename in finishedRecordings:
|
175
|
print "File "+ filename + " already exist as Recording"
|
176
|
log("File "+ filename + " already exist as Recording")
|
177
|
continue
|
178
|
finishedRecordings.append(filename)
|
179
|
|
180
|
#check if file exist
|
181
|
if selection == "1":
|
182
|
filename = new_mask['files'][0]['filename']
|
183
|
isExist = os.path.exists(filename)
|
184
|
if isExist == False:
|
185
|
print "File " + filename + " does not exist!"
|
186
|
log("File " + filename + " does not exist!")
|
187
|
continue
|
188
|
if firstok == False:
|
189
|
print(json.dumps(new_mask, indent=4, sort_keys=True))
|
190
|
|
191
|
if not askyn("OK?"):
|
192
|
print ("Please edit the script!")
|
193
|
exit(1)
|
194
|
firstok = True
|
195
|
|
196
|
#Import
|
197
|
apiurl = url+"api/dvr/entry/create?conf="
|
198
|
api_string = apiurl + json.dumps(new_mask).encode('utf8')
|
199
|
filehandle = urllib.urlopen(api_string)
|
200
|
ServerAnswer=filehandle.read()
|
201
|
print "Server Answer:"+ServerAnswer
|
202
|
log("Server Answer:"+ServerAnswer)
|
203
|
|
204
|
if firstimportok == False:
|
205
|
print ("Imported to TVH")
|
206
|
print ("Please check if import is succesfully")
|
207
|
if not askyn("OK?"):
|
208
|
print ("Please edit the script!")
|
209
|
exit(1)
|
210
|
firstimportok = True
|
211
|
|
212
|
def getExistingVideoFiles():
|
213
|
list = []
|
214
|
for dirpath, dirnames, filenames in os.walk(recordingsdir):
|
215
|
for filename in [f for f in filenames if f.endswith(".ts")]:
|
216
|
list.append(os.path.join(dirpath, filename))
|
217
|
print "Found "+str(len(list))+" Video files"
|
218
|
log("Found "+str(len(list))+" Video files")
|
219
|
return list
|
220
|
|
221
|
def getStarttime(file):
|
222
|
try:
|
223
|
#find DateTime in File
|
224
|
match = re.search('\d{4}-\d{2}-\d{2}.\d{2}-\d{2}', file)
|
225
|
dt = datetime.datetime.strptime(match.group(), '%Y-%m-%d.%H-%M')
|
226
|
print dt
|
227
|
dt = int(time.mktime(dt.timetuple()))
|
228
|
#dt = int(time.mktime(datetime.datetime.strptime(match.group(), '%Y-%m-%d.%H-%M').timetuple()))
|
229
|
except:
|
230
|
print("Unexpected error:", sys.exc_info()[0])
|
231
|
log("Can't find time in filename")
|
232
|
print "Filename starts with Datetime?"
|
233
|
"""Convert filename that starts with 'YYYY-MM-DDTHH-MM' to a unix timestamp; use cdate, i.e. last inode change time not creation, on error"""
|
234
|
try:
|
235
|
dt = int(time.mktime(datetime.datetime.strptime(filepath.split("/")[-1][0:15], "%Y-%m-%dT%H-%M").timetuple()))
|
236
|
except:
|
237
|
print "no...file name doesn't start with 'YYYY-MM-DDTHH-MM.ts'. Use Inode Change Time instead."
|
238
|
log("use Filetime as Time")
|
239
|
dt = int(os.stat(file).st_ctime)
|
240
|
return dt
|
241
|
|
242
|
def ImportMissingRecords():
|
243
|
testRecordingDir()
|
244
|
existingRecords = getExistingRecordings()
|
245
|
VideoFiles = getExistingVideoFiles()
|
246
|
|
247
|
list = []
|
248
|
for file in VideoFiles:
|
249
|
if file in existingRecords:
|
250
|
continue
|
251
|
list.append(file)
|
252
|
print "Found "+str(len(list))+" missing recordings"
|
253
|
log("Found "+str(len(list))+" missing recordings")
|
254
|
|
255
|
firstok = False
|
256
|
firstimportok = False
|
257
|
for rec in list:
|
258
|
new_mask = json.loads(Newmask)
|
259
|
print "--------------------------------"
|
260
|
print "file:"
|
261
|
print rec
|
262
|
log("--------------------------------")
|
263
|
log("file:")
|
264
|
log(rec)
|
265
|
|
266
|
#Directory name = title
|
267
|
title = os.path.basename(os.path.dirname(rec))
|
268
|
if recordingsdir.endswith(title + "/"):
|
269
|
title = os.path.splitext(os.path.basename(rec))[0]
|
270
|
print "title: " + title
|
271
|
#Subtitle = Filename without extension
|
272
|
subtitle = os.path.splitext(os.path.basename(rec))[0]
|
273
|
print "subtitle: " + subtitle
|
274
|
start = getStarttime(rec)
|
275
|
print "start: " + datetime.datetime.utcfromtimestamp(start).strftime('%Y-%m-%dT%H:%M:%SZ')
|
276
|
stop = start + 1
|
277
|
print "stop: " + datetime.datetime.utcfromtimestamp(stop).strftime('%Y-%m-%dT%H:%M:%SZ')
|
278
|
|
279
|
new_mask['title']['ger'] = title
|
280
|
new_mask['subtitle']['ger'] = subtitle
|
281
|
new_mask['files'][0]['filename'] = rec
|
282
|
new_mask['files'][0]['start'] = start
|
283
|
new_mask['files'][0]['stop'] = stop
|
284
|
new_mask['start'] = start
|
285
|
new_mask['stop'] = stop
|
286
|
new_mask['description'] = subtitle
|
287
|
|
288
|
if firstok == False:
|
289
|
print(json.dumps(new_mask, indent=4, sort_keys=True))
|
290
|
if not askyn("OK?"):
|
291
|
print ("Please edit the script!")
|
292
|
exit(1)
|
293
|
firstok = True
|
294
|
|
295
|
apiurl = url+"api/dvr/entry/create?conf="
|
296
|
api_string = apiurl + json.dumps(new_mask)
|
297
|
filehandle = urllib.urlopen(api_string)
|
298
|
serveranswer=filehandle.read()
|
299
|
print "Server Answer:"+serveranswer
|
300
|
log("Server Answer:"+serveranswer)
|
301
|
|
302
|
if firstimportok == False:
|
303
|
print ("Imported to TVH")
|
304
|
print ("Please check if import is succesfully")
|
305
|
if not askyn("OK?"):
|
306
|
print ("Please edit the script!")
|
307
|
exit(1)
|
308
|
firstimportok = True
|
309
|
|
310
|
def listMissingRecordings():
|
311
|
existingRecords = getExistingRecordings()
|
312
|
testRecordingDir()
|
313
|
VideoFiles = getExistingVideoFiles()
|
314
|
|
315
|
list = []
|
316
|
for file in VideoFiles:
|
317
|
if file in existingRecords:
|
318
|
continue
|
319
|
list.append(file)
|
320
|
print ("Missing records:")
|
321
|
print("\n".join(list))
|
322
|
print "Found "+str(len(list))+" missing recordings"
|
323
|
log("Missing records:")
|
324
|
for i in list:
|
325
|
log(i)
|
326
|
log("Found "+str(len(list))+" missing recordings")
|
327
|
|
328
|
|
329
|
log("Start")
|
330
|
print "1 - import from oldLogDir"
|
331
|
print "2 - find and import missing records"
|
332
|
print "3 - list missing records"
|
333
|
|
334
|
selection = input("Please select ")
|
335
|
|
336
|
if selection == 1:
|
337
|
print "1"
|
338
|
log("import from oldLogDir")
|
339
|
testOldLogDir()
|
340
|
ImportRecordings()
|
341
|
elif selection == 2:
|
342
|
print "2"
|
343
|
log("find and import missing records")
|
344
|
ImportMissingRecords()
|
345
|
elif selection == 3:
|
346
|
print "3"
|
347
|
log("list missing records")
|
348
|
listMissingRecordings()
|
349
|
|
350
|
else:
|
351
|
print "Invalid selection"
|
352
|
|
353
|
|