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