Fixed linting and added entry in index.rst

This commit is contained in:
MatMacinf 2026-01-05 13:43:57 +01:00
parent edc09b4eab
commit 3694b82bce
3 changed files with 54 additions and 35 deletions

View file

@ -21,7 +21,7 @@ from beets.ui import Subcommand, print_
class ReportPlugin(BeetsPlugin):
"""A Beets plugin that generates a library report with statistics and Wrapped-style insights."""
"""A Beets plugin that generates a library report with Wrapped-style insights."""
def commands(self):
report_cmd = Subcommand(
@ -114,8 +114,6 @@ class ReportPlugin(BeetsPlugin):
def print_report(self, summary):
"""Print the library report based on precomputed summary statistics."""
items = summary["items"]
if summary["total_tracks"] == 0:
print_("Your Beets library is empty.")
return
@ -144,11 +142,10 @@ class ReportPlugin(BeetsPlugin):
print_(f" Artists: {len(summary['artists'])}")
print_(f" Genres: {len(summary['genres'])}")
years = list(summary["years"].keys())
print_(
f" Years: {min(years)} {max(years)}"
if years
else " Years: n/a"
)
if years:
print_(f" Years: {min(years)} {max(years)}")
else:
print_(" Years: n/a")
print_("-" * 60)
# --- Duration & quality ---
@ -157,11 +154,13 @@ class ReportPlugin(BeetsPlugin):
print_(f" Avg track length: {fmt_time(summary['avg_length'])}")
if summary["avg_bitrate"] is not None:
print_(
f" Avg bitrate: {summary['avg_bitrate']} kbps ({summary['quality']})"
f" Avg bitrate: {summary['avg_bitrate']} kbps "
f"({summary['quality']})"
)
if summary["formats"]:
print_(
f" Primary format: {summary['formats'].most_common(1)[0][0]}"
f" Primary format: "
f"{summary['formats'].most_common(1)[0][0]}"
)
print_("-" * 60)
@ -172,7 +171,8 @@ class ReportPlugin(BeetsPlugin):
for d, c in summary["decade_counter"].most_common():
pct = (c / total_decade_tracks) * 100
print_(
f" {decade_label(d):>4} ({d}-{d + 9}): {c:>5} tracks ({pct:4.1f}%)"
f" {decade_label(d):>4} ({d}-{d + 9}): "
f"{c:>5} tracks ({pct:4.1f}%)"
)
else:
print_(" n/a")
@ -182,7 +182,8 @@ class ReportPlugin(BeetsPlugin):
print_("Your Music Wrapped")
if top_artist:
print_(
f" Top artist: {top_artist[0][0]} ({top_artist[0][1]} tracks)"
f" Top artist: {top_artist[0][0]} "
f"({top_artist[0][1]} tracks)"
)
if top_genre:
print_(
@ -200,12 +201,14 @@ class ReportPlugin(BeetsPlugin):
if summary["longest_track"]:
lt = summary["longest_track"]
print_(
f" Longest track: {lt.artist} {lt.title} ({fmt_time(lt.length)})"
f" Longest track: {lt.artist} {lt.title} "
f"({fmt_time(lt.length)})"
)
if summary["shortest_track"]:
st = summary["shortest_track"]
print_(
f" Shortest track: {st.artist} {st.title} ({fmt_time(st.length)})"
f" Shortest track: {st.artist} {st.title} "
f"({fmt_time(st.length)})"
)
recent_tracks = sum(1 for y in summary["years"].keys() if y >= 2015)

View file

@ -117,6 +117,7 @@ databases. They share the following configuration options:
random
replace
replaygain
report
rewrite
scrub
smartplaylist

View file

@ -2,9 +2,8 @@ import pytest
from beets.library import Item
from beetsplug.report import ReportPlugin
# --- Fixtures ---
@pytest.fixture
def library(tmp_path):
"""Create a temporary empty Beets library."""
@ -42,8 +41,6 @@ def add_item(
# --- Tests ---
def test_empty_library(capsys, library):
"""Test empty library: should output message without crashing."""
plugin = ReportPlugin()
@ -118,16 +115,24 @@ def test_multiple_items(capsys, library):
captured = capsys.readouterr()
# --- Basic stats ---
assert "Tracks:" in captured.out and "4" in captured.out
assert "Albums:" in captured.out and "3" in captured.out
assert "Artists:" in captured.out and "3" in captured.out
assert "Genres:" in captured.out and "3" in captured.out
assert "Tracks:" in captured.out
assert "4" in captured.out
assert "Albums:" in captured.out
assert "3" in captured.out
assert "Artists:" in captured.out
assert "3" in captured.out
assert "Genres:" in captured.out
assert "3" in captured.out
# --- Wrapped-style insights ---
assert "Top artist:" in captured.out and "Artist A" in captured.out
assert "Top genre:" in captured.out and "Rock" in captured.out
assert "Top decade:" in captured.out and "90s" in captured.out
assert "Top year:" in captured.out and "1995" in captured.out
assert "Top artist:" in captured.out
assert "Artist A" in captured.out
assert "Top genre:" in captured.out
assert "Rock" in captured.out
assert "Top decade:" in captured.out
assert "90s" in captured.out
assert "Top year:" in captured.out
assert "1995" in captured.out
# --- Decade distribution ---
assert "90s" in captured.out
@ -163,12 +168,22 @@ def test_missing_metadata(capsys, library):
captured = capsys.readouterr()
# --- Check missing metadata counts ---
# Use 'in' check instead of exact string match
assert any(
"Missing genre tags:" in line and "1" in line
for line in captured.out.splitlines()
)
assert any(
"Missing year tags:" in line and "1" in line
for line in captured.out.splitlines()
)
lines = captured.out.splitlines()
# Check for missing genre
genre_found = False
for line in lines:
if "Missing genre tags:" in line:
assert "1" in line
genre_found = True
break
assert genre_found
# Check for missing year
year_found = False
for line in lines:
if "Missing year tags:" in line:
assert "1" in line
year_found = True
break
assert year_found