52 lines
1.7 KiB
Python
Executable File
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}")
|