reykit 1.1.67__py3-none-any.whl → 1.1.68__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reykit/rschedule.py +147 -168
- {reykit-1.1.67.dist-info → reykit-1.1.68.dist-info}/METADATA +1 -1
- {reykit-1.1.67.dist-info → reykit-1.1.68.dist-info}/RECORD +5 -5
- {reykit-1.1.67.dist-info → reykit-1.1.68.dist-info}/WHEEL +0 -0
- {reykit-1.1.67.dist-info → reykit-1.1.68.dist-info}/licenses/LICENSE +0 -0
reykit/rschedule.py
CHANGED
@@ -10,6 +10,7 @@
|
|
10
10
|
|
11
11
|
|
12
12
|
from typing import Any, Literal, TypedDict, NotRequired
|
13
|
+
from functools import wraps as functools_wraps
|
13
14
|
from collections.abc import Callable
|
14
15
|
from apscheduler.executors.pool import ThreadPoolExecutor
|
15
16
|
from apscheduler.schedulers.background import BackgroundScheduler
|
@@ -54,15 +55,15 @@ class Schedule(Base):
|
|
54
55
|
- `Database`: Automatic record to database.
|
55
56
|
"""
|
56
57
|
|
57
|
-
#
|
58
|
+
# Build.
|
59
|
+
|
60
|
+
## Scheduler.
|
58
61
|
executor = ThreadPoolExecutor(max_workers)
|
59
62
|
executors = {'default': executor}
|
60
63
|
job_defaults = {
|
61
64
|
'coalesce': coalesce,
|
62
65
|
'max_instances': max_instances
|
63
66
|
}
|
64
|
-
|
65
|
-
# Instance.
|
66
67
|
if block:
|
67
68
|
scheduler = BlockingScheduler(
|
68
69
|
executors=executors,
|
@@ -73,18 +74,20 @@ class Schedule(Base):
|
|
73
74
|
executors=executors,
|
74
75
|
job_defaults=job_defaults
|
75
76
|
)
|
76
|
-
|
77
|
-
# Set attribute.
|
78
77
|
self.scheduler = scheduler
|
78
|
+
|
79
|
+
## Database.
|
79
80
|
self.database = database
|
80
|
-
|
81
|
-
|
81
|
+
|
82
|
+
### Database path name.
|
82
83
|
self.db_names = {
|
83
84
|
'base': 'base',
|
84
85
|
'base.schedule': 'schedule',
|
85
|
-
'base.
|
86
|
+
'base.stats_schedule': 'stats_schedule'
|
86
87
|
}
|
87
88
|
|
89
|
+
self.notes: dict[str, str] = {}
|
90
|
+
|
88
91
|
|
89
92
|
def start(self) -> None:
|
90
93
|
"""
|
@@ -136,12 +139,91 @@ class Schedule(Base):
|
|
136
139
|
return jobs
|
137
140
|
|
138
141
|
|
142
|
+
def wrap_record_db(
|
143
|
+
self,
|
144
|
+
task: Callable,
|
145
|
+
note: str | None
|
146
|
+
) -> None:
|
147
|
+
"""
|
148
|
+
Decorator, record to database.
|
149
|
+
|
150
|
+
Parameters
|
151
|
+
----------
|
152
|
+
task : Task.
|
153
|
+
note : Task note.
|
154
|
+
"""
|
155
|
+
|
156
|
+
|
157
|
+
# Define.
|
158
|
+
@functools_wraps(task)
|
159
|
+
def _task(*args, **kwargs) -> None:
|
160
|
+
"""
|
161
|
+
Decorated function.
|
162
|
+
|
163
|
+
Parameters
|
164
|
+
----------
|
165
|
+
args : Position arguments of function.
|
166
|
+
kwargs : Keyword arguments of function.
|
167
|
+
"""
|
168
|
+
|
169
|
+
# Handle parameter.
|
170
|
+
nonlocal task, note
|
171
|
+
|
172
|
+
# Status executing.
|
173
|
+
data = {
|
174
|
+
'status': 0,
|
175
|
+
'task': task.__name__,
|
176
|
+
'note': note
|
177
|
+
}
|
178
|
+
conn = self.database.connect()
|
179
|
+
conn.execute_insert(
|
180
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
181
|
+
data
|
182
|
+
)
|
183
|
+
id_ = conn.variables['identity']
|
184
|
+
conn.commit()
|
185
|
+
|
186
|
+
# Try execute.
|
187
|
+
|
188
|
+
## Record error.
|
189
|
+
task = self.database.error.wrap(task, note=note)
|
190
|
+
|
191
|
+
try:
|
192
|
+
task(*args, **kwargs)
|
193
|
+
|
194
|
+
# Status occurred error.
|
195
|
+
except BaseException:
|
196
|
+
data = {
|
197
|
+
'id': id_,
|
198
|
+
'status': 2
|
199
|
+
}
|
200
|
+
self.database.execute_update(
|
201
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
202
|
+
data
|
203
|
+
)
|
204
|
+
raise
|
205
|
+
|
206
|
+
# Status completed.
|
207
|
+
else:
|
208
|
+
data = {
|
209
|
+
'id': id_,
|
210
|
+
'status': 1
|
211
|
+
}
|
212
|
+
self.database.execute_update(
|
213
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
214
|
+
data
|
215
|
+
)
|
216
|
+
|
217
|
+
return _task
|
218
|
+
|
219
|
+
|
139
220
|
def add_task(
|
140
221
|
self,
|
141
222
|
task: Callable,
|
142
223
|
plan: dict[str, Any],
|
143
|
-
|
144
|
-
|
224
|
+
args: Any | None = None,
|
225
|
+
kwargs: Any | None = None,
|
226
|
+
note: str | None = None
|
145
227
|
) -> Job:
|
146
228
|
"""
|
147
229
|
Add task.
|
@@ -152,6 +234,7 @@ class Schedule(Base):
|
|
152
234
|
plan : Plan trigger keyword arguments.
|
153
235
|
args : Task position arguments.
|
154
236
|
kwargs : Task keyword arguments.
|
237
|
+
note : Task note.
|
155
238
|
|
156
239
|
Returns
|
157
240
|
-------
|
@@ -169,6 +252,11 @@ class Schedule(Base):
|
|
169
252
|
}
|
170
253
|
|
171
254
|
# Add.
|
255
|
+
|
256
|
+
## Database.
|
257
|
+
if self.database is not None:
|
258
|
+
task = self.wrap_record_db(task, note)
|
259
|
+
|
172
260
|
job = self.scheduler.add_job(
|
173
261
|
task,
|
174
262
|
trigger,
|
@@ -177,6 +265,9 @@ class Schedule(Base):
|
|
177
265
|
**trigger_args
|
178
266
|
)
|
179
267
|
|
268
|
+
# Note.
|
269
|
+
self.notes[job.id] = note
|
270
|
+
|
180
271
|
return job
|
181
272
|
|
182
273
|
|
@@ -184,8 +275,9 @@ class Schedule(Base):
|
|
184
275
|
self,
|
185
276
|
task: Job | str,
|
186
277
|
plan: dict[str, Any],
|
187
|
-
|
188
|
-
|
278
|
+
args: Any | None = None,
|
279
|
+
kwargs: Any | None = None,
|
280
|
+
note: str | None = None
|
189
281
|
) -> None:
|
190
282
|
"""
|
191
283
|
Modify task.
|
@@ -196,6 +288,7 @@ class Schedule(Base):
|
|
196
288
|
plan : Plan trigger keyword arguments.
|
197
289
|
args : Task position arguments.
|
198
290
|
kwargs : Task keyword arguments.
|
291
|
+
note : Task note.
|
199
292
|
"""
|
200
293
|
|
201
294
|
# Handle parameter.
|
@@ -210,7 +303,7 @@ class Schedule(Base):
|
|
210
303
|
if key != 'trigger'
|
211
304
|
}
|
212
305
|
|
213
|
-
# Modify
|
306
|
+
# Modify plan.
|
214
307
|
if plan != {}:
|
215
308
|
self.scheduler.reschedule_job(
|
216
309
|
task,
|
@@ -224,11 +317,14 @@ class Schedule(Base):
|
|
224
317
|
or kwargs != {}
|
225
318
|
):
|
226
319
|
self.scheduler.modify_job(
|
227
|
-
task
|
320
|
+
task,
|
228
321
|
args=args,
|
229
322
|
kwargs=kwargs
|
230
323
|
)
|
231
324
|
|
325
|
+
# Modify note.
|
326
|
+
self.notes[task] = note
|
327
|
+
|
232
328
|
|
233
329
|
def remove_task(
|
234
330
|
self,
|
@@ -310,14 +406,14 @@ class Schedule(Base):
|
|
310
406
|
## Database.
|
311
407
|
databases = [
|
312
408
|
{
|
313
|
-
'name': self.db_names['
|
409
|
+
'name': self.db_names['base']
|
314
410
|
}
|
315
411
|
]
|
316
412
|
|
317
413
|
## Table.
|
318
414
|
tables = [
|
319
415
|
|
320
|
-
### '
|
416
|
+
### 'schedule'.
|
321
417
|
{
|
322
418
|
'path': (self.db_names['base'], self.db_names['base.schedule']),
|
323
419
|
'fields': [
|
@@ -336,123 +432,25 @@ class Schedule(Base):
|
|
336
432
|
{
|
337
433
|
'name': 'id',
|
338
434
|
'type': 'int unsigned',
|
339
|
-
'constraint': 'NOT NULL',
|
340
|
-
'comment': '
|
435
|
+
'constraint': 'NOT NULL AUTO_INCREMENT',
|
436
|
+
'comment': 'ID.'
|
341
437
|
},
|
342
438
|
{
|
343
|
-
'name': '
|
344
|
-
'type': '
|
345
|
-
'comment': 'IMDb ID.'
|
346
|
-
},
|
347
|
-
{
|
348
|
-
'name': 'type',
|
349
|
-
'type': 'varchar(5)',
|
350
|
-
'constraint': 'NOT NULL',
|
351
|
-
'comment': 'Media type.'
|
352
|
-
},
|
353
|
-
{
|
354
|
-
'name': 'name',
|
355
|
-
'type': 'varchar(50)',
|
439
|
+
'name': 'status',
|
440
|
+
'type': 'tinyint',
|
356
441
|
'constraint': 'NOT NULL',
|
357
|
-
'comment': '
|
442
|
+
'comment': 'Schedule status, 0 is executing, 1 is completed, 2 is occurred error.'
|
358
443
|
},
|
359
444
|
{
|
360
|
-
'name': '
|
361
|
-
'type': '
|
445
|
+
'name': 'task',
|
446
|
+
'type': 'varchar(100)',
|
362
447
|
'constraint': 'NOT NULL',
|
363
|
-
'comment': '
|
448
|
+
'comment': 'Schedule task function name.'
|
364
449
|
},
|
365
450
|
{
|
366
|
-
'name': '
|
367
|
-
'type': 'varchar(
|
368
|
-
'comment': '
|
369
|
-
},
|
370
|
-
{
|
371
|
-
'name': 'score',
|
372
|
-
'type': 'float',
|
373
|
-
'comment': 'Media score, [0,10].'
|
374
|
-
},
|
375
|
-
{
|
376
|
-
'name': 'score_count',
|
377
|
-
'type': 'int',
|
378
|
-
'comment': 'Media score count.'
|
379
|
-
},
|
380
|
-
{
|
381
|
-
'name': 'minute',
|
382
|
-
'type': 'smallint',
|
383
|
-
'comment': 'Movie or TV drama episode minute.'
|
384
|
-
},
|
385
|
-
{
|
386
|
-
'name': 'episode',
|
387
|
-
'type': 'smallint',
|
388
|
-
'comment': 'TV drama total episode number.'
|
389
|
-
},
|
390
|
-
{
|
391
|
-
'name': 'episode_now',
|
392
|
-
'type': 'smallint',
|
393
|
-
'comment': 'TV drama current episode number.'
|
394
|
-
},
|
395
|
-
{
|
396
|
-
'name': 'premiere',
|
397
|
-
'type': 'json',
|
398
|
-
'comment': 'Premiere region and date dictionary.'
|
399
|
-
},
|
400
|
-
{
|
401
|
-
'name': 'country',
|
402
|
-
'type': 'json',
|
403
|
-
'comment': 'Release country list.'
|
404
|
-
},
|
405
|
-
{
|
406
|
-
'name': 'class',
|
407
|
-
'type': 'json',
|
408
|
-
'comment': 'Class list.'
|
409
|
-
},
|
410
|
-
{
|
411
|
-
'name': 'director',
|
412
|
-
'type': 'json',
|
413
|
-
'comment': 'Director list.'
|
414
|
-
},
|
415
|
-
{
|
416
|
-
'name': 'star',
|
417
|
-
'type': 'json',
|
418
|
-
'comment': 'Star list.'
|
419
|
-
},
|
420
|
-
{
|
421
|
-
'name': 'scriptwriter',
|
422
|
-
'type': 'json',
|
423
|
-
'comment': 'Scriptwriter list.'
|
424
|
-
},
|
425
|
-
{
|
426
|
-
'name': 'language',
|
427
|
-
'type': 'json',
|
428
|
-
'comment': 'Language list.'
|
429
|
-
},
|
430
|
-
{
|
431
|
-
'name': 'alias',
|
432
|
-
'type': 'json',
|
433
|
-
'comment': 'Alias list.'
|
434
|
-
},
|
435
|
-
{
|
436
|
-
'name': 'comment',
|
437
|
-
'type': 'json',
|
438
|
-
'comment': 'Comment list.'
|
439
|
-
},
|
440
|
-
{
|
441
|
-
'name': 'image',
|
442
|
-
'type': 'varchar(150)',
|
443
|
-
'constraint': 'NOT NULL',
|
444
|
-
'comment': 'Picture image URL.'
|
445
|
-
},
|
446
|
-
{
|
447
|
-
'name': 'image_low',
|
448
|
-
'type': 'varchar(150)',
|
449
|
-
'constraint': 'NOT NULL',
|
450
|
-
'comment': 'Picture image low resolution URL.'
|
451
|
-
},
|
452
|
-
{
|
453
|
-
'name': 'video',
|
454
|
-
'type': 'varchar(150)',
|
455
|
-
'comment': 'Preview video Douban page URL.'
|
451
|
+
'name': 'note',
|
452
|
+
'type': 'varchar(500)',
|
453
|
+
'comment': 'Schedule note.'
|
456
454
|
}
|
457
455
|
],
|
458
456
|
'primary': 'id',
|
@@ -470,19 +468,13 @@ class Schedule(Base):
|
|
470
468
|
'comment': 'Record update time normal index.'
|
471
469
|
},
|
472
470
|
{
|
473
|
-
'name': '
|
474
|
-
'fields': '
|
475
|
-
'type': 'unique',
|
476
|
-
'comment': 'IMDb number unique index.'
|
477
|
-
},
|
478
|
-
{
|
479
|
-
'name': 'n_name',
|
480
|
-
'fields': 'name',
|
471
|
+
'name': 'n_task',
|
472
|
+
'fields': 'task',
|
481
473
|
'type': 'noraml',
|
482
|
-
'comment': '
|
474
|
+
'comment': 'Schedule task function name normal index.'
|
483
475
|
}
|
484
476
|
],
|
485
|
-
'comment': '
|
477
|
+
'comment': 'Schedule execute record table.'
|
486
478
|
}
|
487
479
|
|
488
480
|
]
|
@@ -490,76 +482,60 @@ class Schedule(Base):
|
|
490
482
|
## View stats.
|
491
483
|
views_stats = [
|
492
484
|
|
493
|
-
### '
|
485
|
+
### 'stats_schedule'.
|
494
486
|
{
|
495
|
-
'path': (self.db_names['base'], self.db_names['base.
|
487
|
+
'path': (self.db_names['base'], self.db_names['base.stats_schedule']),
|
496
488
|
'items': [
|
497
489
|
{
|
498
490
|
'name': 'count',
|
499
491
|
'select': (
|
500
492
|
'SELECT COUNT(1)\n'
|
501
|
-
f'FROM `{self.db_names['
|
493
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
502
494
|
),
|
503
|
-
'comment': '
|
495
|
+
'comment': 'Schedule count.'
|
504
496
|
},
|
505
497
|
{
|
506
498
|
'name': 'past_day_count',
|
507
499
|
'select': (
|
508
500
|
'SELECT COUNT(1)\n'
|
509
|
-
f'FROM `{self.db_names['
|
501
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
510
502
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) = 0'
|
511
503
|
),
|
512
|
-
'comment': '
|
504
|
+
'comment': 'Schedule count in the past day.'
|
513
505
|
},
|
514
506
|
{
|
515
507
|
'name': 'past_week_count',
|
516
508
|
'select': (
|
517
509
|
'SELECT COUNT(1)\n'
|
518
|
-
f'FROM `{self.db_names['
|
510
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
519
511
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 6'
|
520
512
|
),
|
521
|
-
'comment': '
|
513
|
+
'comment': 'Schedule count in the past week.'
|
522
514
|
},
|
523
515
|
{
|
524
516
|
'name': 'past_month_count',
|
525
517
|
'select': (
|
526
518
|
'SELECT COUNT(1)\n'
|
527
|
-
f'FROM `{self.db_names['
|
519
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
528
520
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 29'
|
529
521
|
),
|
530
|
-
'comment': '
|
531
|
-
},
|
532
|
-
{
|
533
|
-
'name': 'avg_score',
|
534
|
-
'select': (
|
535
|
-
'SELECT ROUND(AVG(`score`), 1)\n'
|
536
|
-
f'FROM `{self.db_names['worm']}`.`{self.db_names['worm.douban_media']}`'
|
537
|
-
),
|
538
|
-
'comment': 'Media average score.'
|
522
|
+
'comment': 'Schedule count in the past month.'
|
539
523
|
},
|
540
524
|
{
|
541
|
-
'name': '
|
525
|
+
'name': 'task_count',
|
542
526
|
'select': (
|
543
|
-
'SELECT
|
544
|
-
f'FROM `{self.db_names['
|
527
|
+
'SELECT COUNT(DISTINCT `task`)\n'
|
528
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
545
529
|
),
|
546
|
-
'comment': '
|
530
|
+
'comment': 'Task count.'
|
547
531
|
},
|
548
532
|
{
|
549
|
-
'name': '
|
550
|
-
'select': (
|
551
|
-
'SELECT MAX(`create_time`)\n'
|
552
|
-
f'FROM `{self.db_names['worm']}`.`{self.db_names['worm.douban_media']}`'
|
553
|
-
),
|
554
|
-
'comment': 'Media last record create time.'
|
555
|
-
},
|
556
|
-
{
|
557
|
-
'name': 'last_update_time',
|
533
|
+
'name': 'last_time',
|
558
534
|
'select': (
|
559
535
|
'SELECT IFNULL(MAX(`update_time`), MAX(`create_time`))\n'
|
560
|
-
f'FROM `{self.db_names['
|
536
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
561
537
|
),
|
562
|
-
'comment': '
|
538
|
+
'comment': 'Schedule last record time.'
|
563
539
|
}
|
564
540
|
]
|
565
541
|
|
@@ -570,5 +546,8 @@ class Schedule(Base):
|
|
570
546
|
# Build.
|
571
547
|
self.database.build.build(databases, tables, views_stats=views_stats)
|
572
548
|
|
549
|
+
## Error.
|
550
|
+
self.database.error.build_db()
|
551
|
+
|
573
552
|
|
574
553
|
__iter__ = tasks
|
@@ -11,7 +11,7 @@ reykit/rnum.py,sha256=PhG4V_BkVfCJUsbpMDN1umGZly1Hsus80TW8bpyBtyY,3653
|
|
11
11
|
reykit/ros.py,sha256=Yi_mfYzVHwjjUZke0BNX7PKFLZpoT5NRyj5aDOSNQRU,46911
|
12
12
|
reykit/rrand.py,sha256=4VwooITgox54_GonELcJfcIpStDi-UJchpnyWKnyeIA,8606
|
13
13
|
reykit/rre.py,sha256=1qva7xatKVE9qC2j7IujjXSM59qxHWwTYpiizFFQ8Xo,6024
|
14
|
-
reykit/rschedule.py,sha256=
|
14
|
+
reykit/rschedule.py,sha256=uUSZyWAjurkWPlvDO57OgRLAreeE7WHOV0J_MG6S-zY,14985
|
15
15
|
reykit/rstdout.py,sha256=yesWo7wIGablpyAu-2J2Gw11Qp3GdQjGICTyIcvLyt4,8200
|
16
16
|
reykit/rsys.py,sha256=AP62KyN40flCeQJBclfJq8shachSAFT0LkVjiKsXkrw,24946
|
17
17
|
reykit/rtable.py,sha256=UQ-JlwjssMR3gY1iY-VGQEKQ5_BZabpJy6TL7Fx19c4,12200
|
@@ -22,7 +22,7 @@ reykit/rwrap.py,sha256=FEmeK_fboJ-OyXeJf8bilc7U2ph8xIbZGNHb6fLCy2c,15063
|
|
22
22
|
reykit/rzip.py,sha256=BGEONswuBZxQ-zcgd_xp2fcvYesC9AmKaaXWvnT3bTI,3456
|
23
23
|
reykit/rdll/__init__.py,sha256=nLSb8onBm2ilyoxzpDzUeGfSCKwkLEesIhzK3LiJ8mk,701
|
24
24
|
reykit/rdll/rdll_core.py,sha256=o6-rKcTQgxZQe0kD3GnwyNb3KL9IogzgCQNOmYLMm7A,5086
|
25
|
-
reykit-1.1.
|
26
|
-
reykit-1.1.
|
27
|
-
reykit-1.1.
|
28
|
-
reykit-1.1.
|
25
|
+
reykit-1.1.68.dist-info/METADATA,sha256=VkV4-QQHi1iAAq-8m7WMj0KO9qyqIsRkNfes0n2l6RM,1872
|
26
|
+
reykit-1.1.68.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
27
|
+
reykit-1.1.68.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
28
|
+
reykit-1.1.68.dist-info/RECORD,,
|
File without changes
|
File without changes
|