This repository was archived by the owner on Oct 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcommon.py
More file actions
470 lines (322 loc) · 10.5 KB
/
Copy pathcommon.py
File metadata and controls
470 lines (322 loc) · 10.5 KB
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
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# -*- coding: utf-8 -*-
"""common module app and analyze
* cache check
* queue flow control
* get youtube_id
"""
import os
import json
from glob import glob
import urllib.parse
import app as ap
import state_list as state
import datetime
# cache max number
CACHE_ELMS = 7
def save_cache(youtube_id, title, time_line, time_line_enemy, time_data, total_damage, debuff_value, status):
"""save cache
save cache if cache not found
save cache if before cache is tmp sd analyze
change status if before and now status are same
Args:
youtube_id (string): youtube id
title (string): youtube movie title
time_line (list, boolean): found ub data or False
time_line_enemy (list, boolean): found ub data with enemy data or False
time_data (list, boolean): spend time while analyze or False
total_damage (string, boolean): total damage or False
debuff_value (list, boolean): ub timing debuff values or False
status (int): error status
Returns:
status (int): error status
"""
past_status = cache_status_check(youtube_id)
present_status = status
if past_status is False:
json.dump([title, time_line, time_line_enemy, time_data, total_damage, debuff_value, present_status],
open(ap.cache_dir + urllib.parse.quote(youtube_id) + ".json", "w"))
else:
result, present_status = status_comparison(past_status, status)
if result is True:
json.dump([title, time_line, time_line_enemy, time_data, total_damage, debuff_value, present_status],
open(ap.cache_dir + urllib.parse.quote(youtube_id) + ".json", "w"))
return present_status
def cache_check(youtube_id):
"""cache check with youtube_id
search cache and get cache data
cache: (6)
[title, time_line, time_data, total_damage, debuff_value, status]
Args:
youtube_id (str): user input youtube_id
Returns:
status (int): cache or False
"""
try:
cache_path = ap.cache_dir + urllib.parse.quote(youtube_id) + ".json"
ret = json.load(open(cache_path))
if len(ret) is CACHE_ELMS: # in case of number of cached elements is correct
title, time_line, time_line_enemy, time_data, total_damage, debuff_value, past_status = ret
if past_status // 100 == 3:
if check_pass_time(cache_path, 300): # through 3xx error if passed 5 minutes
return False
else:
return ret
else:
return ret
else: # in case of number of cached elements is incorrect
# delete cache
clear_path(cache_path)
return False
except FileNotFoundError:
# not found cache
return False
def queue_cache_check(youtube_id):
"""cache check with youtube_id while queue
search cache and get cache data
cache: (6)
[title, time_line, time_data, total_damage, debuff_value, status]
Args:
youtube_id (str): user input youtube_id
Returns:
status (int): cache or False
"""
try:
cache_path = ap.cache_dir + urllib.parse.quote(youtube_id) + ".json"
ret = json.load(open(cache_path))
if len(ret) is CACHE_ELMS: # in case of number of cached elements is correct
return ret
else: # in case of number of cached elements is incorrect
return False
except FileNotFoundError:
# not found cache
return False
def cache_status_check(youtube_id):
"""cache status check with youtube_id
search cache and get cache data
cache: (6)
[title, time_line, time_data, total_damage, debuff_value, status]
and if status is 3xx error, then return past status
Args:
youtube_id (str): user input youtube_id
Returns:
status (int, boolean): error status or False (in case of cache status is not 3xx)
"""
try:
cache_path = ap.cache_dir + urllib.parse.quote(youtube_id) + ".json"
ret = json.load(open(cache_path))
if len(ret) is CACHE_ELMS: # in case of number of cached elements is correct
past_status = ret[-1]
return past_status
else: # in case of number of cached elements is incorrect
# not found cache
return False
except FileNotFoundError:
# not found cache
return False
def status_comparison(past, present):
"""status compares with past and present
this function calls if valid cache exists
Args:
past (int): past analyze status (should be 3xx)
present (int): present analyze status
Returns:
cacheable (boolean): cache is able to make or not
set_status (int): chosen status by combination
"""
# past status is 2xx/4xx return confirmed status
if past // 100 == 2 or past // 100 == 4:
return False, past
# present status is 2xx/4xx return confirmed status
if present // 100 == 2 or present // 100 == 4:
return True, present
# Only 3xx should go below but it dose not matter
# past status is 30x and recently 3xx, do not update
if not past % 100 // 10 and present % 100 // 10:
return False, past
# past status is 30x and recently 30x, fix as 20x
elif not past % 100 // 10 and not present % 100 // 10:
return True, present - 100
# past status is 3xx and recently 30x, yield to try one more time
elif not present % 100 // 10:
return True, present
# past status is 3xx and recently 3xx, fix as 4xx
elif past % 100 // 10 and present % 100 // 10:
return True, present + 100
# all pattern should be covered on above, but just in case throw exception
else:
return True, 399
def queue_append(path):
"""analyze queue append to file
control analyze queue to download only one file
Args:
path (str): analyze control queue file path
Returns:
"""
try:
with open(path, mode="w"):
pass
except FileExistsError:
pass
return
def pending_append(path):
"""pending append to file
control pending queue to analyze only one file
Args:
path (str): analyze pending file path
Returns:
"""
try:
with open(path, mode="w"):
pass
except FileExistsError:
pass
return
def is_path_due(path):
"""check path
check path turn
Args:
path (str): analyze control file path
Returns:
True/False (boolean): oldest path:True secondly path:False
"""
try:
# get list queue file
directory = os.path.dirname(path)
fl = glob(directory + "/*")
if not fl:
return False
# sort time stamp and find oldest queue
fl.sort(key=lambda x: os.path.getctime(x))
comp = fl[0].replace("\\", "/")
if comp == path:
return True
else:
return False
except:
return False
def is_path_exists(path):
"""check path
check path existence
Args:
path (str): analyze control queue file path
Returns:
True/False (boolean): exist:True not found:False
"""
try:
directory = os.path.dirname(path)
fl = os.listdir(directory + "/")
if not fl:
return False
else:
return True
except:
return False
def is_pending_download(margin):
"""check is download job ready
check pending timestamp to download available
for avoid too many query to YouTube
Args:
margin (int):
Returns:
result (boolean): True: ready to download / False: not ready
"""
queue_path = ap.dl_pending_dir + "pending"
result = False
if os.path.exists(queue_path):
if check_pass_time(queue_path, margin):
clear_path(queue_path)
result = True
else:
result = True
return result
def watchdog(youtube_id, is_parent, margin, err_type):
"""check is job timeout
check pending and queue timestamp to determine timeout
Args:
youtube_id: str
is_parent: bool
margin: int
err_type: ERR_CODE
Returns:
None
"""
queue_path = ap.queue_dir + str(youtube_id)
pending_path = ap.pending_dir + str(youtube_id)
if is_parent:
job_path = pending_path
else:
job_path = queue_path
if os.path.exists(job_path):
if check_pass_time(job_path, margin):
save_cache(youtube_id, "", False, False, False, False, False, err_type)
clear_path(job_path)
if is_parent:
clear_path(queue_path)
return
def watchdog_download(youtube_id, margin):
"""check is download job timeout
check pending and queue timestamp to determine timeout
Args:
youtube_id: str
margin: int
Returns:
True/False: boolean
"""
queue_path = ap.dl_queue_dir + str(youtube_id)
result = False
if os.path.exists(queue_path):
if check_pass_time(queue_path, margin):
clear_path(queue_path)
result = True
return result
def tmp_movie_clear():
"""delete movie file
delete oldest 1 movie file if its made 2 hours later
this function is intended as every query
Args:
Returns:
"""
try:
fl = glob(ap.stream_dir + "/*")
if not fl:
return
fl.sort(key=lambda x: os.path.getctime(x))
if check_pass_time(fl[0], 7200):
clear_path(fl[0])
except FileNotFoundError:
pass
def check_pass_time(file_path, thresh):
"""check time
check file update time with current time
Args:
file_path (str): time as datetime
thresh (int): thresh value "seconds" for check
Returns:
True (boolean): passed time or file not found
False (boolean): not passed time
"""
now = datetime.datetime.today()
try:
timestamp = datetime.datetime.fromtimestamp(int(os.path.getmtime(file_path)))
except FileNotFoundError:
return True
if (now - timestamp).total_seconds() >= thresh:
return True
else:
return False
def clear_path(path):
"""delete file
delete file safely
Args:
path (str): file path
Returns:
"""
try:
os.remove(path)
except PermissionError:
pass
except FileNotFoundError:
pass
except TypeError:
pass
return