qBitrr2 5.5.2__py3-none-any.whl → 5.5.3__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.
- qBitrr/arss.py +206 -84
- qBitrr/bundled_data.py +2 -2
- qBitrr/main.py +12 -0
- qBitrr/static/assets/ArrView.js +1 -1
- qBitrr/static/assets/ArrView.js.map +1 -1
- qBitrr/static/assets/ConfigView.js +3 -4
- qBitrr/static/assets/ConfigView.js.map +1 -1
- qBitrr/static/assets/LogsView.js +1 -207
- qBitrr/static/assets/LogsView.js.map +1 -1
- qBitrr/static/assets/ProcessesView.js +1 -1
- qBitrr/static/assets/ProcessesView.js.map +1 -1
- qBitrr/static/assets/app.css +1 -1
- qBitrr/static/assets/app.js +9 -1
- qBitrr/static/assets/app.js.map +1 -1
- qBitrr/static/assets/react-select.esm.js +4 -4
- qBitrr/static/assets/react-select.esm.js.map +1 -1
- qBitrr/static/assets/table.js +1 -1
- qBitrr/static/assets/vendor.js +1 -8
- qBitrr/static/assets/vendor.js.map +1 -1
- qBitrr/static/index.html +8 -22
- qBitrr/static/sw.js +6 -29
- qBitrr/webui.py +2 -0
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/METADATA +2 -2
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/RECORD +28 -29
- qBitrr/static/assets/lidarr.svg +0 -1
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/WHEEL +0 -0
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/entry_points.txt +0 -0
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/licenses/LICENSE +0 -0
- {qbitrr2-5.5.2.dist-info → qbitrr2-5.5.3.dist-info}/top_level.txt +0 -0
qBitrr/arss.py
CHANGED
|
@@ -620,16 +620,32 @@ class Arr:
|
|
|
620
620
|
self.search_api_command = "MissingEpisodeSearch"
|
|
621
621
|
|
|
622
622
|
if not QBIT_DISABLED and not TAGLESS:
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
623
|
+
try:
|
|
624
|
+
self.manager.qbit_manager.client.torrents_create_tags(
|
|
625
|
+
[
|
|
626
|
+
"qBitrr-allowed_seeding",
|
|
627
|
+
"qBitrr-ignored",
|
|
628
|
+
"qBitrr-imported",
|
|
629
|
+
"qBitrr-allowed_stalled",
|
|
630
|
+
]
|
|
631
|
+
)
|
|
632
|
+
except qbittorrentapi.exceptions.APIConnectionError as e:
|
|
633
|
+
self.logger.warning(
|
|
634
|
+
"Could not connect to qBittorrent during initialization for %s: %s. "
|
|
635
|
+
"Will retry when process starts.",
|
|
636
|
+
self._name,
|
|
637
|
+
str(e).split("\n")[0], # Only log first line of error
|
|
638
|
+
)
|
|
631
639
|
elif not QBIT_DISABLED and TAGLESS:
|
|
632
|
-
|
|
640
|
+
try:
|
|
641
|
+
self.manager.qbit_manager.client.torrents_create_tags(["qBitrr-ignored"])
|
|
642
|
+
except qbittorrentapi.exceptions.APIConnectionError as e:
|
|
643
|
+
self.logger.warning(
|
|
644
|
+
"Could not connect to qBittorrent during initialization for %s: %s. "
|
|
645
|
+
"Will retry when process starts.",
|
|
646
|
+
self._name,
|
|
647
|
+
str(e).split("\n")[0], # Only log first line of error
|
|
648
|
+
)
|
|
633
649
|
self.search_setup_completed = False
|
|
634
650
|
self.model_file: Model | None = None
|
|
635
651
|
self.series_file_model: Model | None = None
|
|
@@ -1257,6 +1273,7 @@ class Arr:
|
|
|
1257
1273
|
object_ids = list(object_id)
|
|
1258
1274
|
self.logger.trace("Requeue cache entry list: %s", object_ids)
|
|
1259
1275
|
if self.series_search:
|
|
1276
|
+
series_id = None
|
|
1260
1277
|
while True:
|
|
1261
1278
|
try:
|
|
1262
1279
|
data = self.client.get_series(object_ids[0])
|
|
@@ -1283,27 +1300,35 @@ class Arr:
|
|
|
1283
1300
|
):
|
|
1284
1301
|
continue
|
|
1285
1302
|
except PyarrResourceNotFound as e:
|
|
1286
|
-
self.logger.
|
|
1287
|
-
|
|
1303
|
+
self.logger.warning(
|
|
1304
|
+
"Series %s not found in Sonarr (likely removed): %s",
|
|
1305
|
+
object_ids[0],
|
|
1306
|
+
str(e),
|
|
1307
|
+
)
|
|
1308
|
+
break
|
|
1288
1309
|
for object_id in object_ids:
|
|
1289
1310
|
if object_id in self.queue_file_ids:
|
|
1290
1311
|
self.queue_file_ids.remove(object_id)
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1312
|
+
if series_id:
|
|
1313
|
+
self.logger.trace("Research series id: %s", series_id)
|
|
1314
|
+
while True:
|
|
1315
|
+
try:
|
|
1316
|
+
self.client.post_command(
|
|
1317
|
+
self.search_api_command, seriesId=series_id
|
|
1318
|
+
)
|
|
1319
|
+
break
|
|
1320
|
+
except (
|
|
1321
|
+
requests.exceptions.ChunkedEncodingError,
|
|
1322
|
+
requests.exceptions.ContentDecodingError,
|
|
1323
|
+
requests.exceptions.ConnectionError,
|
|
1324
|
+
JSONDecodeError,
|
|
1325
|
+
):
|
|
1326
|
+
continue
|
|
1327
|
+
if self.persistent_queue:
|
|
1328
|
+
self.persistent_queue.insert(EntryId=series_id).on_conflict_ignore()
|
|
1305
1329
|
else:
|
|
1306
1330
|
for object_id in object_ids:
|
|
1331
|
+
episode_found = False
|
|
1307
1332
|
while True:
|
|
1308
1333
|
try:
|
|
1309
1334
|
data = self.client.get_episode(object_id)
|
|
@@ -1333,6 +1358,7 @@ class Arr:
|
|
|
1333
1358
|
)
|
|
1334
1359
|
else:
|
|
1335
1360
|
self.logger.notice("Re-Searching episode: %s", object_id)
|
|
1361
|
+
episode_found = True
|
|
1336
1362
|
break
|
|
1337
1363
|
except (
|
|
1338
1364
|
requests.exceptions.ChunkedEncodingError,
|
|
@@ -1342,24 +1368,37 @@ class Arr:
|
|
|
1342
1368
|
AttributeError,
|
|
1343
1369
|
):
|
|
1344
1370
|
continue
|
|
1371
|
+
except PyarrResourceNotFound as e:
|
|
1372
|
+
self.logger.warning(
|
|
1373
|
+
"Episode %s not found in Sonarr (likely removed): %s",
|
|
1374
|
+
object_id,
|
|
1375
|
+
str(e),
|
|
1376
|
+
)
|
|
1377
|
+
break
|
|
1345
1378
|
|
|
1346
1379
|
if object_id in self.queue_file_ids:
|
|
1347
1380
|
self.queue_file_ids.remove(object_id)
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1381
|
+
if episode_found:
|
|
1382
|
+
while True:
|
|
1383
|
+
try:
|
|
1384
|
+
self.client.post_command(
|
|
1385
|
+
"EpisodeSearch", episodeIds=[object_id]
|
|
1386
|
+
)
|
|
1387
|
+
break
|
|
1388
|
+
except (
|
|
1389
|
+
requests.exceptions.ChunkedEncodingError,
|
|
1390
|
+
requests.exceptions.ContentDecodingError,
|
|
1391
|
+
requests.exceptions.ConnectionError,
|
|
1392
|
+
JSONDecodeError,
|
|
1393
|
+
):
|
|
1394
|
+
continue
|
|
1395
|
+
if self.persistent_queue:
|
|
1396
|
+
self.persistent_queue.insert(
|
|
1397
|
+
EntryId=object_id
|
|
1398
|
+
).on_conflict_ignore()
|
|
1361
1399
|
elif self.type == "radarr":
|
|
1362
1400
|
self.logger.trace("Requeue cache entry: %s", object_id)
|
|
1401
|
+
movie_found = False
|
|
1363
1402
|
while True:
|
|
1364
1403
|
try:
|
|
1365
1404
|
data = self.client.get_movie(object_id)
|
|
@@ -1376,6 +1415,7 @@ class Arr:
|
|
|
1376
1415
|
)
|
|
1377
1416
|
else:
|
|
1378
1417
|
self.logger.notice("Re-Searching movie: %s", object_id)
|
|
1418
|
+
movie_found = True
|
|
1379
1419
|
break
|
|
1380
1420
|
except (
|
|
1381
1421
|
requests.exceptions.ChunkedEncodingError,
|
|
@@ -1385,23 +1425,30 @@ class Arr:
|
|
|
1385
1425
|
AttributeError,
|
|
1386
1426
|
):
|
|
1387
1427
|
continue
|
|
1428
|
+
except PyarrResourceNotFound as e:
|
|
1429
|
+
self.logger.warning(
|
|
1430
|
+
"Movie %s not found in Radarr (likely removed): %s", object_id, str(e)
|
|
1431
|
+
)
|
|
1432
|
+
break
|
|
1388
1433
|
if object_id in self.queue_file_ids:
|
|
1389
1434
|
self.queue_file_ids.remove(object_id)
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
self.persistent_queue
|
|
1435
|
+
if movie_found:
|
|
1436
|
+
while True:
|
|
1437
|
+
try:
|
|
1438
|
+
self.client.post_command("MoviesSearch", movieIds=[object_id])
|
|
1439
|
+
break
|
|
1440
|
+
except (
|
|
1441
|
+
requests.exceptions.ChunkedEncodingError,
|
|
1442
|
+
requests.exceptions.ContentDecodingError,
|
|
1443
|
+
requests.exceptions.ConnectionError,
|
|
1444
|
+
JSONDecodeError,
|
|
1445
|
+
):
|
|
1446
|
+
continue
|
|
1447
|
+
if self.persistent_queue:
|
|
1448
|
+
self.persistent_queue.insert(EntryId=object_id).on_conflict_ignore()
|
|
1403
1449
|
elif self.type == "lidarr":
|
|
1404
1450
|
self.logger.trace("Requeue cache entry: %s", object_id)
|
|
1451
|
+
album_found = False
|
|
1405
1452
|
while True:
|
|
1406
1453
|
try:
|
|
1407
1454
|
data = self.client.get_album(object_id)
|
|
@@ -1418,6 +1465,7 @@ class Arr:
|
|
|
1418
1465
|
)
|
|
1419
1466
|
else:
|
|
1420
1467
|
self.logger.notice("Re-Searching album: %s", object_id)
|
|
1468
|
+
album_found = True
|
|
1421
1469
|
break
|
|
1422
1470
|
except (
|
|
1423
1471
|
requests.exceptions.ChunkedEncodingError,
|
|
@@ -1427,21 +1475,27 @@ class Arr:
|
|
|
1427
1475
|
AttributeError,
|
|
1428
1476
|
):
|
|
1429
1477
|
continue
|
|
1478
|
+
except PyarrResourceNotFound as e:
|
|
1479
|
+
self.logger.warning(
|
|
1480
|
+
"Album %s not found in Lidarr (likely removed): %s", object_id, str(e)
|
|
1481
|
+
)
|
|
1482
|
+
break
|
|
1430
1483
|
if object_id in self.queue_file_ids:
|
|
1431
1484
|
self.queue_file_ids.remove(object_id)
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
self.persistent_queue
|
|
1485
|
+
if album_found:
|
|
1486
|
+
while True:
|
|
1487
|
+
try:
|
|
1488
|
+
self.client.post_command("AlbumSearch", albumIds=[object_id])
|
|
1489
|
+
break
|
|
1490
|
+
except (
|
|
1491
|
+
requests.exceptions.ChunkedEncodingError,
|
|
1492
|
+
requests.exceptions.ContentDecodingError,
|
|
1493
|
+
requests.exceptions.ConnectionError,
|
|
1494
|
+
JSONDecodeError,
|
|
1495
|
+
):
|
|
1496
|
+
continue
|
|
1497
|
+
if self.persistent_queue:
|
|
1498
|
+
self.persistent_queue.insert(EntryId=object_id).on_conflict_ignore()
|
|
1445
1499
|
|
|
1446
1500
|
def _process_errored(self) -> None:
|
|
1447
1501
|
# Recheck all torrents marked for rechecking.
|
|
@@ -2673,6 +2727,35 @@ class Arr:
|
|
|
2673
2727
|
JSONDecodeError,
|
|
2674
2728
|
):
|
|
2675
2729
|
continue
|
|
2730
|
+
|
|
2731
|
+
# Validate episode object has required fields
|
|
2732
|
+
if not episode or not isinstance(episode, dict):
|
|
2733
|
+
self.logger.warning(
|
|
2734
|
+
"Invalid episode object returned from API for episode ID %s: %s",
|
|
2735
|
+
db_entry.get("id"),
|
|
2736
|
+
type(episode).__name__,
|
|
2737
|
+
)
|
|
2738
|
+
return
|
|
2739
|
+
|
|
2740
|
+
required_fields = [
|
|
2741
|
+
"id",
|
|
2742
|
+
"seriesId",
|
|
2743
|
+
"seasonNumber",
|
|
2744
|
+
"episodeNumber",
|
|
2745
|
+
"title",
|
|
2746
|
+
"airDateUtc",
|
|
2747
|
+
"episodeFileId",
|
|
2748
|
+
]
|
|
2749
|
+
missing_fields = [field for field in required_fields if field not in episode]
|
|
2750
|
+
if missing_fields:
|
|
2751
|
+
self.logger.warning(
|
|
2752
|
+
"Episode %s missing required fields %s. Episode data: %s",
|
|
2753
|
+
db_entry.get("id"),
|
|
2754
|
+
missing_fields,
|
|
2755
|
+
episode,
|
|
2756
|
+
)
|
|
2757
|
+
return
|
|
2758
|
+
|
|
2676
2759
|
if episode.get("monitored", True) or self.search_unmonitored:
|
|
2677
2760
|
while True:
|
|
2678
2761
|
try:
|
|
@@ -2820,24 +2903,24 @@ class Arr:
|
|
|
2820
2903
|
):
|
|
2821
2904
|
continue
|
|
2822
2905
|
|
|
2823
|
-
EntryId = episode
|
|
2906
|
+
EntryId = episode.get("id")
|
|
2824
2907
|
SeriesTitle = episode.get("series", {}).get("title")
|
|
2825
|
-
SeasonNumber = episode
|
|
2826
|
-
Title = episode
|
|
2827
|
-
SeriesId = episode
|
|
2828
|
-
EpisodeFileId = episode
|
|
2829
|
-
EpisodeNumber = episode
|
|
2908
|
+
SeasonNumber = episode.get("seasonNumber")
|
|
2909
|
+
Title = episode.get("title")
|
|
2910
|
+
SeriesId = episode.get("seriesId")
|
|
2911
|
+
EpisodeFileId = episode.get("episodeFileId")
|
|
2912
|
+
EpisodeNumber = episode.get("episodeNumber")
|
|
2830
2913
|
AbsoluteEpisodeNumber = (
|
|
2831
|
-
episode
|
|
2914
|
+
episode.get("absoluteEpisodeNumber")
|
|
2832
2915
|
if "absoluteEpisodeNumber" in episode
|
|
2833
2916
|
else None
|
|
2834
2917
|
)
|
|
2835
2918
|
SceneAbsoluteEpisodeNumber = (
|
|
2836
|
-
episode
|
|
2919
|
+
episode.get("sceneAbsoluteEpisodeNumber")
|
|
2837
2920
|
if "sceneAbsoluteEpisodeNumber" in episode
|
|
2838
2921
|
else None
|
|
2839
2922
|
)
|
|
2840
|
-
AirDateUtc = episode
|
|
2923
|
+
AirDateUtc = episode.get("airDateUtc")
|
|
2841
2924
|
Monitored = episode.get("monitored", True)
|
|
2842
2925
|
QualityMet = not QualityUnmet if db_entry["hasFile"] else False
|
|
2843
2926
|
customFormatMet = customFormat >= minCustomFormat
|
|
@@ -3110,9 +3193,13 @@ class Arr:
|
|
|
3110
3193
|
try:
|
|
3111
3194
|
if movieData:
|
|
3112
3195
|
if not movieData.MinCustomFormatScore:
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3196
|
+
profile = (
|
|
3197
|
+
self.client.get_quality_profile(
|
|
3198
|
+
db_entry["qualityProfileId"]
|
|
3199
|
+
)
|
|
3200
|
+
or {}
|
|
3201
|
+
)
|
|
3202
|
+
minCustomFormat = profile.get("minFormatScore", 0)
|
|
3116
3203
|
else:
|
|
3117
3204
|
minCustomFormat = movieData.MinCustomFormatScore
|
|
3118
3205
|
if db_entry["hasFile"]:
|
|
@@ -3125,9 +3212,11 @@ class Arr:
|
|
|
3125
3212
|
else:
|
|
3126
3213
|
customFormat = 0
|
|
3127
3214
|
else:
|
|
3128
|
-
|
|
3129
|
-
db_entry["qualityProfileId"]
|
|
3130
|
-
|
|
3215
|
+
profile = (
|
|
3216
|
+
self.client.get_quality_profile(db_entry["qualityProfileId"])
|
|
3217
|
+
or {}
|
|
3218
|
+
)
|
|
3219
|
+
minCustomFormat = profile.get("minFormatScore", 0)
|
|
3131
3220
|
if db_entry["hasFile"]:
|
|
3132
3221
|
customFormat = self.client.get_movie_file(
|
|
3133
3222
|
db_entry["movieFile"]["id"]
|
|
@@ -3825,8 +3914,29 @@ class Arr:
|
|
|
3825
3914
|
):
|
|
3826
3915
|
continue
|
|
3827
3916
|
except PyarrResourceNotFound as e:
|
|
3828
|
-
|
|
3829
|
-
|
|
3917
|
+
# Queue item not found - this is expected when Arr has already auto-imported
|
|
3918
|
+
# and removed the item, or if it was manually removed. Clean up internal tracking.
|
|
3919
|
+
self.logger.warning(
|
|
3920
|
+
"Queue item %s not found in Arr (likely already imported/removed): %s",
|
|
3921
|
+
id_,
|
|
3922
|
+
str(e),
|
|
3923
|
+
)
|
|
3924
|
+
# Clean up internal tracking data for this queue entry
|
|
3925
|
+
if id_ in self.requeue_cache:
|
|
3926
|
+
# Remove associated media IDs from queue_file_ids
|
|
3927
|
+
media_ids = self.requeue_cache[id_]
|
|
3928
|
+
if isinstance(media_ids, set):
|
|
3929
|
+
self.queue_file_ids.difference_update(media_ids)
|
|
3930
|
+
elif media_ids in self.queue_file_ids:
|
|
3931
|
+
self.queue_file_ids.discard(media_ids)
|
|
3932
|
+
# Remove from requeue_cache
|
|
3933
|
+
del self.requeue_cache[id_]
|
|
3934
|
+
# Remove from cache (downloadId -> queue entry ID mapping)
|
|
3935
|
+
# We need to find and remove the cache entry by value (queue ID)
|
|
3936
|
+
cache_keys_to_remove = [k for k, v in self.cache.items() if v == id_]
|
|
3937
|
+
for key in cache_keys_to_remove:
|
|
3938
|
+
del self.cache[key]
|
|
3939
|
+
return None
|
|
3830
3940
|
return res
|
|
3831
3941
|
|
|
3832
3942
|
def file_is_probeable(self, file: pathlib.Path) -> bool:
|
|
@@ -5978,7 +6088,11 @@ class Arr:
|
|
|
5978
6088
|
class Meta:
|
|
5979
6089
|
database = self.db
|
|
5980
6090
|
|
|
5981
|
-
|
|
6091
|
+
try:
|
|
6092
|
+
self.db.create_tables([Files, Queue, PersistingQueue, Series], safe=True)
|
|
6093
|
+
except Exception as e:
|
|
6094
|
+
self.logger.error("Failed to create database tables for Sonarr: %s", e)
|
|
6095
|
+
raise
|
|
5982
6096
|
self.series_file_model = Series
|
|
5983
6097
|
self.artists_file_model = None
|
|
5984
6098
|
elif db3 and self.type == "lidarr":
|
|
@@ -5987,12 +6101,20 @@ class Arr:
|
|
|
5987
6101
|
class Meta:
|
|
5988
6102
|
database = self.db
|
|
5989
6103
|
|
|
5990
|
-
|
|
6104
|
+
try:
|
|
6105
|
+
self.db.create_tables([Files, Queue, PersistingQueue, Artists, Tracks], safe=True)
|
|
6106
|
+
except Exception as e:
|
|
6107
|
+
self.logger.error("Failed to create database tables for Lidarr: %s", e)
|
|
6108
|
+
raise
|
|
5991
6109
|
self.artists_file_model = Artists
|
|
5992
6110
|
self.series_file_model = None # Lidarr uses artists, not series
|
|
5993
6111
|
else:
|
|
5994
6112
|
# Radarr or any type without db3/db4 (series/artists/tracks models)
|
|
5995
|
-
|
|
6113
|
+
try:
|
|
6114
|
+
self.db.create_tables([Files, Queue, PersistingQueue], safe=True)
|
|
6115
|
+
except Exception as e:
|
|
6116
|
+
self.logger.error("Failed to create database tables for Radarr: %s", e)
|
|
6117
|
+
raise
|
|
5996
6118
|
self.artists_file_model = None
|
|
5997
6119
|
self.series_file_model = None
|
|
5998
6120
|
|
qBitrr/bundled_data.py
CHANGED
qBitrr/main.py
CHANGED
|
@@ -476,6 +476,18 @@ class qBitManager:
|
|
|
476
476
|
)
|
|
477
477
|
for proc in list(self.child_processes):
|
|
478
478
|
try:
|
|
479
|
+
# Check if process has already been started
|
|
480
|
+
if proc.is_alive() or proc.exitcode is not None:
|
|
481
|
+
meta = self._process_registry.get(proc, {})
|
|
482
|
+
self.logger.warning(
|
|
483
|
+
"Skipping start of already-started %s worker for category '%s' (alive=%s, exitcode=%s)",
|
|
484
|
+
meta.get("role", "worker"),
|
|
485
|
+
meta.get("category", "unknown"),
|
|
486
|
+
proc.is_alive(),
|
|
487
|
+
proc.exitcode,
|
|
488
|
+
)
|
|
489
|
+
continue
|
|
490
|
+
|
|
479
491
|
proc.start()
|
|
480
492
|
meta = self._process_registry.get(proc, {})
|
|
481
493
|
self.logger.debug(
|