Files
obsidian-vault/personal/tech/scripts/find_va_misuse.py
T

52 lines
1.7 KiB
Python
Executable File

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""Detector A2 — 'Various Artists' on a folder that has only ONE artist.
Rule (Alex): Various Artists ONLY when the performers are genuinely different.
One artist — including spelling variants (Иванушки / Иванушки Int. / Иванушки
International) and featured credits — gets THAT artist. For a DJ-mix compilation the
albumartist is the DJ who compiled it, not Various Artists.
Iterate until it reports zero candidates: the classes are nested — fixing one reveals
the next (e.g. Агата Кристи → 9999 - Разное/Проекты).
Usage:
python3 find_va_misuse.py [путь_к_APPLY-PLAN.csv]
"""
import sys
import csv
import collections
P = sys.argv[1] if len(sys.argv) > 1 else '/Users/admin/Downloads/music-tags/APPLY-PLAN.csv'
rows = list(csv.DictReader(open(P, encoding='utf-8-sig', newline='')))
def s(v):
return (v or '').strip()
by = collections.defaultdict(list)
for r in rows:
by[r['folder']].append(r)
suspects = []
for folder, rs in sorted(by.items()):
aa = {s(r['new_albumartist']) for r in rs}
if aa != {'Various Artists'}:
continue
art = collections.Counter(s(r['new_artist']) for r in rs if s(r['new_artist']))
if not art:
continue
top, n = art.most_common(1)[0]
total = len(rs)
# one artist dominates — folder is NOT a genuine compilation
if n / total > 0.5 and n >= 2:
suspects.append((n, total, top, folder))
print(f"ПАПОК-КАНДИДАТОВ: {len(suspects)} (файлов: {sum(s[1] for s in suspects)})")
print()
for n, total, top, folder in sorted(suspects, key=lambda x: -x[1]):
print(f" {n:3d}/{total:<3d} artist={top!r}")
print(f" {folder}")