reykit 1.1.67__py3-none-any.whl → 1.1.69__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 +149 -176
- {reykit-1.1.67.dist-info → reykit-1.1.69.dist-info}/METADATA +1 -1
- {reykit-1.1.67.dist-info → reykit-1.1.69.dist-info}/RECORD +5 -5
- {reykit-1.1.67.dist-info → reykit-1.1.69.dist-info}/WHEEL +0 -0
- {reykit-1.1.67.dist-info → reykit-1.1.69.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,26 +74,22 @@ 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
|
+
### Start.
|
80
|
+
self.scheduler.start()
|
81
|
+
|
82
|
+
## Database.
|
79
83
|
self.database = database
|
80
|
-
|
81
|
-
|
84
|
+
|
85
|
+
### Database path name.
|
82
86
|
self.db_names = {
|
83
87
|
'base': 'base',
|
84
88
|
'base.schedule': 'schedule',
|
85
|
-
'base.
|
89
|
+
'base.stats_schedule': 'stats_schedule'
|
86
90
|
}
|
87
91
|
|
88
|
-
|
89
|
-
def start(self) -> None:
|
90
|
-
"""
|
91
|
-
Start scheduler.
|
92
|
-
"""
|
93
|
-
|
94
|
-
# Start.
|
95
|
-
self.scheduler.start()
|
92
|
+
self.notes: dict[str, str] = {}
|
96
93
|
|
97
94
|
|
98
95
|
def pause(self) -> None:
|
@@ -136,12 +133,91 @@ class Schedule(Base):
|
|
136
133
|
return jobs
|
137
134
|
|
138
135
|
|
136
|
+
def wrap_record_db(
|
137
|
+
self,
|
138
|
+
task: Callable,
|
139
|
+
note: str | None
|
140
|
+
) -> None:
|
141
|
+
"""
|
142
|
+
Decorator, record to database.
|
143
|
+
|
144
|
+
Parameters
|
145
|
+
----------
|
146
|
+
task : Task.
|
147
|
+
note : Task note.
|
148
|
+
"""
|
149
|
+
|
150
|
+
|
151
|
+
# Define.
|
152
|
+
@functools_wraps(task)
|
153
|
+
def _task(*args, **kwargs) -> None:
|
154
|
+
"""
|
155
|
+
Decorated function.
|
156
|
+
|
157
|
+
Parameters
|
158
|
+
----------
|
159
|
+
args : Position arguments of function.
|
160
|
+
kwargs : Keyword arguments of function.
|
161
|
+
"""
|
162
|
+
|
163
|
+
# Handle parameter.
|
164
|
+
nonlocal task, note
|
165
|
+
|
166
|
+
# Status executing.
|
167
|
+
data = {
|
168
|
+
'status': 0,
|
169
|
+
'task': task.__name__,
|
170
|
+
'note': note
|
171
|
+
}
|
172
|
+
conn = self.database.connect()
|
173
|
+
conn.execute_insert(
|
174
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
175
|
+
data
|
176
|
+
)
|
177
|
+
id_ = conn.variables['identity']
|
178
|
+
conn.commit()
|
179
|
+
|
180
|
+
# Try execute.
|
181
|
+
|
182
|
+
## Record error.
|
183
|
+
task = self.database.error.wrap(task, note=note)
|
184
|
+
|
185
|
+
try:
|
186
|
+
task(*args, **kwargs)
|
187
|
+
|
188
|
+
# Status occurred error.
|
189
|
+
except BaseException:
|
190
|
+
data = {
|
191
|
+
'id': id_,
|
192
|
+
'status': 2
|
193
|
+
}
|
194
|
+
self.database.execute_update(
|
195
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
196
|
+
data
|
197
|
+
)
|
198
|
+
raise
|
199
|
+
|
200
|
+
# Status completed.
|
201
|
+
else:
|
202
|
+
data = {
|
203
|
+
'id': id_,
|
204
|
+
'status': 1
|
205
|
+
}
|
206
|
+
self.database.execute_update(
|
207
|
+
(self.db_names['base'], self.db_names['base.schedule']),
|
208
|
+
data
|
209
|
+
)
|
210
|
+
|
211
|
+
return _task
|
212
|
+
|
213
|
+
|
139
214
|
def add_task(
|
140
215
|
self,
|
141
216
|
task: Callable,
|
142
217
|
plan: dict[str, Any],
|
143
|
-
|
144
|
-
|
218
|
+
args: Any | None = None,
|
219
|
+
kwargs: Any | None = None,
|
220
|
+
note: str | None = None
|
145
221
|
) -> Job:
|
146
222
|
"""
|
147
223
|
Add task.
|
@@ -152,6 +228,7 @@ class Schedule(Base):
|
|
152
228
|
plan : Plan trigger keyword arguments.
|
153
229
|
args : Task position arguments.
|
154
230
|
kwargs : Task keyword arguments.
|
231
|
+
note : Task note.
|
155
232
|
|
156
233
|
Returns
|
157
234
|
-------
|
@@ -169,6 +246,11 @@ class Schedule(Base):
|
|
169
246
|
}
|
170
247
|
|
171
248
|
# Add.
|
249
|
+
|
250
|
+
## Database.
|
251
|
+
if self.database is not None:
|
252
|
+
task = self.wrap_record_db(task, note)
|
253
|
+
|
172
254
|
job = self.scheduler.add_job(
|
173
255
|
task,
|
174
256
|
trigger,
|
@@ -177,6 +259,9 @@ class Schedule(Base):
|
|
177
259
|
**trigger_args
|
178
260
|
)
|
179
261
|
|
262
|
+
# Note.
|
263
|
+
self.notes[job.id] = note
|
264
|
+
|
180
265
|
return job
|
181
266
|
|
182
267
|
|
@@ -184,8 +269,9 @@ class Schedule(Base):
|
|
184
269
|
self,
|
185
270
|
task: Job | str,
|
186
271
|
plan: dict[str, Any],
|
187
|
-
|
188
|
-
|
272
|
+
args: Any | None = None,
|
273
|
+
kwargs: Any | None = None,
|
274
|
+
note: str | None = None
|
189
275
|
) -> None:
|
190
276
|
"""
|
191
277
|
Modify task.
|
@@ -196,6 +282,7 @@ class Schedule(Base):
|
|
196
282
|
plan : Plan trigger keyword arguments.
|
197
283
|
args : Task position arguments.
|
198
284
|
kwargs : Task keyword arguments.
|
285
|
+
note : Task note.
|
199
286
|
"""
|
200
287
|
|
201
288
|
# Handle parameter.
|
@@ -210,7 +297,7 @@ class Schedule(Base):
|
|
210
297
|
if key != 'trigger'
|
211
298
|
}
|
212
299
|
|
213
|
-
# Modify
|
300
|
+
# Modify plan.
|
214
301
|
if plan != {}:
|
215
302
|
self.scheduler.reschedule_job(
|
216
303
|
task,
|
@@ -224,11 +311,14 @@ class Schedule(Base):
|
|
224
311
|
or kwargs != {}
|
225
312
|
):
|
226
313
|
self.scheduler.modify_job(
|
227
|
-
task
|
314
|
+
task,
|
228
315
|
args=args,
|
229
316
|
kwargs=kwargs
|
230
317
|
)
|
231
318
|
|
319
|
+
# Modify note.
|
320
|
+
self.notes[task] = note
|
321
|
+
|
232
322
|
|
233
323
|
def remove_task(
|
234
324
|
self,
|
@@ -310,14 +400,14 @@ class Schedule(Base):
|
|
310
400
|
## Database.
|
311
401
|
databases = [
|
312
402
|
{
|
313
|
-
'name': self.db_names['
|
403
|
+
'name': self.db_names['base']
|
314
404
|
}
|
315
405
|
]
|
316
406
|
|
317
407
|
## Table.
|
318
408
|
tables = [
|
319
409
|
|
320
|
-
### '
|
410
|
+
### 'schedule'.
|
321
411
|
{
|
322
412
|
'path': (self.db_names['base'], self.db_names['base.schedule']),
|
323
413
|
'fields': [
|
@@ -336,123 +426,25 @@ class Schedule(Base):
|
|
336
426
|
{
|
337
427
|
'name': 'id',
|
338
428
|
'type': 'int unsigned',
|
339
|
-
'constraint': 'NOT NULL',
|
340
|
-
'comment': '
|
341
|
-
},
|
342
|
-
{
|
343
|
-
'name': 'imdb',
|
344
|
-
'type': 'char(10)',
|
345
|
-
'comment': 'IMDb ID.'
|
429
|
+
'constraint': 'NOT NULL AUTO_INCREMENT',
|
430
|
+
'comment': 'ID.'
|
346
431
|
},
|
347
432
|
{
|
348
|
-
'name': '
|
349
|
-
'type': '
|
433
|
+
'name': 'status',
|
434
|
+
'type': 'tinyint',
|
350
435
|
'constraint': 'NOT NULL',
|
351
|
-
'comment': '
|
436
|
+
'comment': 'Schedule status, 0 is executing, 1 is completed, 2 is occurred error.'
|
352
437
|
},
|
353
438
|
{
|
354
|
-
'name': '
|
355
|
-
'type': 'varchar(
|
439
|
+
'name': 'task',
|
440
|
+
'type': 'varchar(100)',
|
356
441
|
'constraint': 'NOT NULL',
|
357
|
-
'comment': '
|
358
|
-
},
|
359
|
-
{
|
360
|
-
'name': 'year',
|
361
|
-
'type': 'year',
|
362
|
-
'constraint': 'NOT NULL',
|
363
|
-
'comment': 'Release year.'
|
364
|
-
},
|
365
|
-
{
|
366
|
-
'name': 'desc',
|
367
|
-
'type': 'varchar(1000)',
|
368
|
-
'comment': 'Media content description.'
|
442
|
+
'comment': 'Schedule task function name.'
|
369
443
|
},
|
370
444
|
{
|
371
|
-
'name': '
|
372
|
-
'type': '
|
373
|
-
'comment': '
|
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.'
|
445
|
+
'name': 'note',
|
446
|
+
'type': 'varchar(500)',
|
447
|
+
'comment': 'Schedule note.'
|
456
448
|
}
|
457
449
|
],
|
458
450
|
'primary': 'id',
|
@@ -470,19 +462,13 @@ class Schedule(Base):
|
|
470
462
|
'comment': 'Record update time normal index.'
|
471
463
|
},
|
472
464
|
{
|
473
|
-
'name': '
|
474
|
-
'fields': '
|
475
|
-
'type': 'unique',
|
476
|
-
'comment': 'IMDb number unique index.'
|
477
|
-
},
|
478
|
-
{
|
479
|
-
'name': 'n_name',
|
480
|
-
'fields': 'name',
|
465
|
+
'name': 'n_task',
|
466
|
+
'fields': 'task',
|
481
467
|
'type': 'noraml',
|
482
|
-
'comment': '
|
468
|
+
'comment': 'Schedule task function name normal index.'
|
483
469
|
}
|
484
470
|
],
|
485
|
-
'comment': '
|
471
|
+
'comment': 'Schedule execute record table.'
|
486
472
|
}
|
487
473
|
|
488
474
|
]
|
@@ -490,76 +476,60 @@ class Schedule(Base):
|
|
490
476
|
## View stats.
|
491
477
|
views_stats = [
|
492
478
|
|
493
|
-
### '
|
479
|
+
### 'stats_schedule'.
|
494
480
|
{
|
495
|
-
'path': (self.db_names['base'], self.db_names['base.
|
481
|
+
'path': (self.db_names['base'], self.db_names['base.stats_schedule']),
|
496
482
|
'items': [
|
497
483
|
{
|
498
484
|
'name': 'count',
|
499
485
|
'select': (
|
500
486
|
'SELECT COUNT(1)\n'
|
501
|
-
f'FROM `{self.db_names['
|
487
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
502
488
|
),
|
503
|
-
'comment': '
|
489
|
+
'comment': 'Schedule count.'
|
504
490
|
},
|
505
491
|
{
|
506
492
|
'name': 'past_day_count',
|
507
493
|
'select': (
|
508
494
|
'SELECT COUNT(1)\n'
|
509
|
-
f'FROM `{self.db_names['
|
495
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
510
496
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) = 0'
|
511
497
|
),
|
512
|
-
'comment': '
|
498
|
+
'comment': 'Schedule count in the past day.'
|
513
499
|
},
|
514
500
|
{
|
515
501
|
'name': 'past_week_count',
|
516
502
|
'select': (
|
517
503
|
'SELECT COUNT(1)\n'
|
518
|
-
f'FROM `{self.db_names['
|
504
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
519
505
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 6'
|
520
506
|
),
|
521
|
-
'comment': '
|
507
|
+
'comment': 'Schedule count in the past week.'
|
522
508
|
},
|
523
509
|
{
|
524
510
|
'name': 'past_month_count',
|
525
511
|
'select': (
|
526
512
|
'SELECT COUNT(1)\n'
|
527
|
-
f'FROM `{self.db_names['
|
513
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`\n'
|
528
514
|
'WHERE TIMESTAMPDIFF(DAY, `create_time`, NOW()) <= 29'
|
529
515
|
),
|
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.'
|
516
|
+
'comment': 'Schedule count in the past month.'
|
539
517
|
},
|
540
518
|
{
|
541
|
-
'name': '
|
519
|
+
'name': 'task_count',
|
542
520
|
'select': (
|
543
|
-
'SELECT
|
544
|
-
f'FROM `{self.db_names['
|
521
|
+
'SELECT COUNT(DISTINCT `task`)\n'
|
522
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
545
523
|
),
|
546
|
-
'comment': '
|
524
|
+
'comment': 'Task count.'
|
547
525
|
},
|
548
526
|
{
|
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',
|
527
|
+
'name': 'last_time',
|
558
528
|
'select': (
|
559
529
|
'SELECT IFNULL(MAX(`update_time`), MAX(`create_time`))\n'
|
560
|
-
f'FROM `{self.db_names['
|
530
|
+
f'FROM `{self.db_names['base']}`.`{self.db_names['base.schedule']}`'
|
561
531
|
),
|
562
|
-
'comment': '
|
532
|
+
'comment': 'Schedule last record time.'
|
563
533
|
}
|
564
534
|
]
|
565
535
|
|
@@ -570,5 +540,8 @@ class Schedule(Base):
|
|
570
540
|
# Build.
|
571
541
|
self.database.build.build(databases, tables, views_stats=views_stats)
|
572
542
|
|
543
|
+
## Error.
|
544
|
+
self.database.error.build_db()
|
545
|
+
|
573
546
|
|
574
547
|
__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=FC_8mfF9mj7EmmcDDgtVPEt9X1DST_iwNK15SctFSws,14901
|
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.69.dist-info/METADATA,sha256=j_h9WMxqDklZbv-Ch2SGAm7qWqW-nlLfqD_SUVVlWf4,1872
|
26
|
+
reykit-1.1.69.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
27
|
+
reykit-1.1.69.dist-info/licenses/LICENSE,sha256=UYLPqp7BvPiH8yEZduJqmmyEl6hlM3lKrFIefiD4rvk,1059
|
28
|
+
reykit-1.1.69.dist-info/RECORD,,
|
File without changes
|
File without changes
|