Skip to content

Commit 718e937

Browse files
committed
3.0.141
1 parent 5ed670f commit 718e937

File tree

4 files changed

+85
-46
lines changed

4 files changed

+85
-46
lines changed

.github/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ To stop playing press Ctrl+C in either the terminal or mpv
9999
<details><summary>List all subcommands</summary>
100100

101101
$ library
102-
library (v3.0.140; 104 subcommands)
102+
library (v3.0.141; 104 subcommands)
103103

104104
Create database subcommands:
105105
╭─────────────────┬──────────────────────────────────────────╮

library/__main__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from library.utils import argparse_utils, iterables
66
from library.utils.log_utils import log
77

8-
__version__ = "3.0.140"
8+
__version__ = "3.0.141"
99

1010
progs = {
1111
"Create database subcommands": {

library/createdb/torrents_add.py

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,26 @@ def torrent_decode(path):
7070

7171

7272
def _extract_metadata(path):
73-
torrent = torrent_decode(path)
74-
assert torrent.num_files() > 0
73+
ltt = torrent_decode(path)
74+
assert ltt.num_files() > 0
7575

76-
files = [{"path": f.path, "size": f.size, "time_deleted": 0} for f in torrent.files()]
76+
files = [{"path": f.path, "size": f.size, "time_deleted": 0} for f in ltt.files()]
7777
file_sizes = [f["size"] for f in files]
7878

7979
stat = os.stat(path, follow_symlinks=False)
8080

8181
web_seeds = []
82-
for ws in torrent.web_seeds():
82+
for ws in ltt.web_seeds():
8383
with suppress(Exception):
8484
url = ws["url"]
8585
if url:
8686
web_seeds.append(url)
8787

8888
return {
8989
"path": path,
90-
"title": torrent.name(),
91-
"tracker": get_tracker_domain(torrent),
92-
"time_uploaded": nums.safe_int(torrent.creation_date()),
90+
"title": ltt.name(),
91+
"tracker": get_tracker_domain(ltt),
92+
"time_uploaded": nums.safe_int(ltt.creation_date()),
9393
"time_created": int(stat.st_ctime),
9494
"time_modified": int(stat.st_mtime) or consts.now(),
9595
"time_deleted": 0,
@@ -98,11 +98,11 @@ def _extract_metadata(path):
9898
"size_avg": statistics.mean(file_sizes),
9999
"size_median": statistics.median(file_sizes),
100100
"file_count": len(files),
101-
"src": torrent.source,
102-
"is_private": torrent.private,
103-
"comment": torrent.comment(),
104-
"author": torrent.creator(),
105-
"info_hash": str(torrent.info_hash()),
101+
"src": ltt.source,
102+
"is_private": ltt.private,
103+
"comment": ltt.comment(),
104+
"author": ltt.creator(),
105+
"info_hash": str(ltt.info_hash()),
106106
"web_seeds": web_seeds,
107107
"files": files,
108108
}

library/playback/torrents_info.py

Lines changed: 71 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#!/usr/bin/python3
21
import argparse, os, statistics
32
from collections import defaultdict
43
from pathlib import Path
4+
5+
#!/usr/bin/python3
6+
from random import randint
57
from statistics import mean, median
68
from time import sleep
79

@@ -99,15 +101,44 @@ def parse_args():
99101
return args
100102

101103

104+
def torrent_files(t):
105+
import qbittorrentapi
106+
107+
attempts = 10
108+
attempt = 0
109+
while attempt < attempts:
110+
attempt += 1
111+
112+
try:
113+
return t.files
114+
except (qbittorrentapi.APIConnectionError, ConnectionRefusedError, TimeoutError):
115+
sleep(randint(1, 10))
116+
117+
return []
118+
119+
102120
def qbt_get_tracker(qbt_client, torrent):
103-
tracker = torrent.tracker
104-
if not tracker:
105-
tracker = iterables.safe_unpack(
106-
sorted(
107-
(tr.url for tr in qbt_client.torrents_trackers(torrent.hash) if tr.url.startswith("http")), reverse=True
108-
)
109-
)
110-
return tld_from_url(tracker)
121+
import qbittorrentapi
122+
123+
attempts = 10
124+
attempt = 0
125+
while attempt < attempts:
126+
attempt += 1
127+
128+
try:
129+
tracker = torrent.tracker
130+
if not tracker:
131+
tracker = iterables.safe_unpack(
132+
sorted(
133+
(tr.url for tr in qbt_client.torrents_trackers(torrent.hash) if tr.url.startswith("http")),
134+
reverse=True,
135+
)
136+
)
137+
return tld_from_url(tracker)
138+
except (qbittorrentapi.APIConnectionError, ConnectionRefusedError, TimeoutError):
139+
sleep(randint(1, 10))
140+
141+
return None
111142

112143

113144
def qbt_enhance_torrents(qbt_client, qbt_torrents):
@@ -174,9 +205,9 @@ def filter_torrents_by_criteria(args, torrents):
174205
if "sizes" not in args.defaults:
175206
torrents = [t for t in torrents if args.sizes(t.total_size)]
176207
if "file_count" not in args.defaults:
177-
torrents = [t for t in torrents if args.file_count(len(t.files))]
208+
torrents = [t for t in torrents if args.file_count(len(torrent_files(t)))]
178209
if "avg_sizes" not in args.defaults:
179-
torrents = [t for t in torrents if args.avg_sizes(median([f.size for f in t.files]))]
210+
torrents = [t for t in torrents if args.avg_sizes(median([f.size for f in torrent_files(t)]))]
180211
if "ratio" not in args.defaults:
181212
torrents = [t for t in torrents if args.ratio(t.ratio)]
182213
if "seeders" not in args.defaults:
@@ -281,9 +312,11 @@ def filter_torrents_by_criteria(args, torrents):
281312
)
282313
]
283314
if args.file_search:
284-
torrents = [t for t in torrents if strings.glob_match_all(args.file_search, [f.name for f in t.files])]
315+
torrents = [t for t in torrents if strings.glob_match_all(args.file_search, [f.name for f in torrent_files(t)])]
285316
if args.file_exclude:
286-
torrents = [t for t in torrents if not strings.glob_match_any(args.file_exclude, [f.name for f in t.files])]
317+
torrents = [
318+
t for t in torrents if not strings.glob_match_any(args.file_exclude, [f.name for f in torrent_files(t)])
319+
]
287320

288321
if args.tracker:
289322
trackers = set(args.tracker)
@@ -298,15 +331,17 @@ def filter_torrents_by_criteria(args, torrents):
298331
for t in torrents
299332
if args.any_exists
300333
is any(
301-
(Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name).exists() for f in t.files
334+
(Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name).exists()
335+
for f in torrent_files(t)
302336
)
303337
]
304338
if args.all_exists is True:
305339
torrents = [
306340
t
307341
for t in torrents
308342
if all(
309-
(Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name).exists() for f in t.files
343+
(Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name).exists()
344+
for f in torrent_files(t)
310345
)
311346
]
312347
elif args.all_exists is False:
@@ -315,7 +350,7 @@ def filter_torrents_by_criteria(args, torrents):
315350
for t in torrents
316351
if any(
317352
not (Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name).exists()
318-
for f in t.files
353+
for f in torrent_files(t)
319354
)
320355
]
321356
if args.opened is not None:
@@ -325,7 +360,7 @@ def filter_torrents_by_criteria(args, torrents):
325360
if args.opened
326361
is any(
327362
file_utils.is_file_open(Path(t.save_path if t.state_enum.is_complete else t.download_path) / f.name)
328-
for f in t.files
363+
for f in torrent_files(t)
329364
)
330365
]
331366

@@ -380,7 +415,9 @@ def print_torrents_by_tracker(args, torrents):
380415
"count": len(tracker_torrents),
381416
"size": sum(t.total_size for t in tracker_torrents),
382417
"remaining": remaining,
383-
"files": (sum(len(t.files) for t in tracker_torrents) if args.file_counts else None), # a bit slow
418+
"files": (
419+
sum(len(torrent_files(t)) for t in tracker_torrents) if args.file_counts else None
420+
), # a bit slow
384421
}
385422
)
386423
if trackers:
@@ -416,7 +453,7 @@ def agg_torrents_state(args, state, state_torrents):
416453
return {
417454
"state": state,
418455
"count": len(state_torrents),
419-
"files": (sum(len(t.files) for t in state_torrents) if args.file_counts else None),
456+
"files": (sum(len(torrent_files(t)) for t in state_torrents) if args.file_counts else None),
420457
"size": strings.file_size(sum(t.total_size for t in state_torrents)),
421458
"downloaded": strings.file_size(downloaded) if downloaded else None,
422459
"uploaded": strings.file_size(uploaded) if uploaded else None,
@@ -488,11 +525,11 @@ def shorten(s, width):
488525
elif args.sort == "remaining":
489526
torrents = sorted(torrents, key=lambda t: t.amount_left, reverse=reverse_sort)
490527
elif args.sort in ["counts", "count"]:
491-
torrents = sorted(torrents, key=lambda t: len(t.files), reverse=reverse_sort)
528+
torrents = sorted(torrents, key=lambda t: len(torrent_files(t)), reverse=reverse_sort)
492529
elif args.sort in ["size", "total_size"]:
493530
torrents = sorted(torrents, key=lambda t: t.total_size, reverse=reverse_sort)
494531
elif args.sort in ["avg_size"]:
495-
torrents = sorted(torrents, key=lambda t: mean([f.size for f in t.files]), reverse=reverse_sort)
532+
torrents = sorted(torrents, key=lambda t: mean([f.size for f in torrent_files(t)]), reverse=reverse_sort)
496533
elif args.sort in ["network", "download+upload", "ingress+egress"]:
497534
torrents = sorted(
498535
torrents,
@@ -590,7 +627,9 @@ def shorten(s, width):
590627

591628
base_path = None
592629
for test_path in base_paths:
593-
if test_path and ((Path(test_path) / t.name).exists() or (Path(test_path) / t.files[0].name).exists()):
630+
if test_path and (
631+
(Path(test_path) / t.name).exists() or (Path(test_path) / torrent_files(t)[0].name).exists()
632+
):
594633
base_path = test_path
595634
break
596635

@@ -603,7 +642,7 @@ def shorten(s, width):
603642
continue
604643

605644
if "f" in args.print:
606-
for f in t.files:
645+
for f in torrent_files(t):
607646
file_path = Path(base_path) / f.name
608647
print(file_path)
609648
else:
@@ -646,16 +685,16 @@ def gen_row(t):
646685
d |= {"tracker": t.tracker_domain()}
647686

648687
if args.file_search:
649-
files = t.files
650-
files = [f for f in t.files if strings.glob_match_all(args.file_search, [f.name])]
688+
files = torrent_files(t)
689+
files = [f for f in torrent_files(t) if strings.glob_match_all(args.file_search, [f.name])]
651690

652691
print(t.name)
653692
printing.extended_view(files)
654693
print()
655694

656-
d |= {"files": f"{len(files)} ({len(t.files)})"}
695+
d |= {"files": f"{len(files)} ({len(torrent_files(t))})"}
657696
elif args.file_counts:
658-
d |= {"files": len(t.files)}
697+
d |= {"files": len(torrent_files(t))}
659698

660699
if args.paths:
661700
if t.state_enum.is_complete:
@@ -719,16 +758,16 @@ def gen_row(t):
719758
d |= {"tracker": t.tracker_domain()}
720759

721760
if args.file_search:
722-
files = t.files
723-
files = [f for f in t.files if strings.glob_match_all(args.file_search, [f.name])]
761+
files = torrent_files(t)
762+
files = [f for f in torrent_files(t) if strings.glob_match_all(args.file_search, [f.name])]
724763

725764
print(t.name)
726765
printing.extended_view(files)
727766
print()
728767

729-
d |= {"files": f"{len(files)} ({len(t.files)})"}
768+
d |= {"files": f"{len(files)} ({len(torrent_files(t))})"}
730769
elif args.file_counts:
731-
d |= {"files": len(t.files)}
770+
d |= {"files": len(torrent_files(t))}
732771

733772
if args.paths:
734773
if t.state_enum.is_complete:
@@ -778,7 +817,7 @@ def gen_row(t):
778817
if invalid_state:
779818
continue
780819

781-
for file in t.files:
820+
for file in torrent_files(t):
782821
for base_path in base_paths:
783822
file_path = Path(base_path) / file.name
784823
if file_path.exists() and not file_path.is_dir():

0 commit comments

Comments
 (0)