Skip to content

Commit 8fd8424

Browse files
committed
playback: add -rr for re-ranking
1 parent a776d28 commit 8fd8424

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

library/playback/play_actions.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,21 @@ def parse_args(action, default_chromecast=None) -> argparse.Namespace:
9292
--fetch-siblings each -O # get the first result per directory
9393
--fetch-siblings if-audiobook -O # get the first result per directory if 'audiobook' is in the path
9494
--fetch-siblings always -O # get 2,000 results per directory
95+
""",
96+
)
97+
ordering.add_argument(
98+
"--re-rank",
99+
"--rerank",
100+
"-rr",
101+
action=argparse_utils.ArgparseDict,
102+
default={},
103+
metavar="COLUMN=WEIGHT",
104+
help="""Add key/value pairs re-rank sorting by multiple attributes (similar to MCDA)
105+
-rr 'regex_sort=1 cluster_sort=1 -size=3'
106+
will sort the playlist by taking into account size, regex, and clusters prioritizing size over the other two.
107+
108+
-u size desc -L 500 --cols path,title,size,time_modified -rs -rr 'regex_sort=1 time_modified=1'
109+
will get the 500 largest and then sort by regex_sort and time_modified
95110
""",
96111
)
97112

@@ -407,7 +422,37 @@ def process_playqueue(args) -> None:
407422
if args.play_in_order:
408423
media = db_media.natsort_media(args, media)
409424

410-
if args.regex_sort:
425+
if args.re_rank:
426+
import pandas
427+
428+
from library.utils import pd_utils
429+
430+
df = pandas.DataFrame(media)
431+
432+
if args.regex_sort:
433+
from library.text import regex_sort
434+
435+
sorted_media = regex_sort.sort_dicts(args, media)
436+
df = pd_utils.from_dict_add_path_rank(df, sorted_media, "regex_sort")
437+
log.debug("regex-sort: %s", t.elapsed())
438+
elif args.cluster_sort:
439+
from library.text import cluster_sort
440+
441+
sorted_media = cluster_sort.sort_dicts(args, media)
442+
df = pd_utils.from_dict_add_path_rank(df, sorted_media, "cluster_sort")
443+
log.debug("cluster-sort: %s", t.elapsed())
444+
445+
column_weights = {
446+
k.lstrip("-"): {
447+
"direction": "desc" if k.startswith("-") else "asc",
448+
"weight": v or 1,
449+
}
450+
for k, v in args.re_rank.items()
451+
}
452+
df = pd_utils.rank_dataframe(df, column_weights)
453+
media = df.to_dict(orient="records")
454+
log.debug("re-rank: %s", t.elapsed())
455+
elif args.regex_sort:
411456
from library.text import regex_sort
412457

413458
media = regex_sort.sort_dicts(args, media)

library/utils/pd_utils.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,9 @@ def rank_dataframe(df, column_weights):
8585
def count_category(df, key_name):
8686
df[f"{key_name}_count"] = df.groupby(key_name)[key_name].transform("size")
8787
return df
88+
89+
90+
def from_dict_add_path_rank(df, sorted_media, new_rank_column_name):
91+
rank_dict = {item["path"]: rank + 1 for rank, item in enumerate(sorted_media)}
92+
df[new_rank_column_name] = df["path"].map(rank_dict)
93+
return df

tests/utils/test_web.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ def test_parent_property():
251251
assert str(web_path.parent.parent.parent.parent.parent.parent.parent) == "https://<netloc>"
252252
assert str(web_path.parent.parent.parent.parent.parent.parent.parent.parent) == "https://<netloc>"
253253

254+
254255
@pytest.mark.parametrize(
255256
"base_url, href, expected",
256257
[
@@ -264,7 +265,7 @@ def test_parent_property():
264265
("https://unli.xyz/", "//example.com/ch/", "https://example.com/ch/"),
265266
("https://unli.xyz/diskprices", "ftp://example.com/ch/", "ftp://example.com/ch/"),
266267
("https://unli.xyz/diskprices", "ssh://example.com/ch/", "ssh://example.com/ch/"),
267-
]
268+
],
268269
)
269270
def test_construct_absolute_url(base_url, href, expected):
270271
result = construct_absolute_url(base_url, href)

0 commit comments

Comments
 (0)