63 lines
2.9 KiB
Python
Executable File
63 lines
2.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""Класс A2 (второй детектор): albumartist='Various Artists', но это АЛЬБОМ ОДНОГО АВТОРА.
|
||
|
||
Признак: папка названа по автору (или автор доминирует в artist), а стоит 'Various Artists'.
|
||
Дополняет find_va_misuse.py (тот ловит «>50% один artist» без учёта имени папки).
|
||
|
||
Питфолл: 47 папок-сборников дают «кандидат» ложно (Sbornik_Novij_Rok, !Retro, !Radio/*,
|
||
Final Fantasy VI, трибьюты, Gazgolder) — они в SKIP. Остаток после чистки:
|
||
`Блестящие, Фриске` и `Eminem,50cent` — папки-склейки, Various Artists там ВЕРЕН.
|
||
|
||
Использование: python3 find_va_author.py
|
||
Итог сессии 10: кандидатов 2 (оба защитимые).
|
||
"""
|
||
import csv
|
||
import collections
|
||
import os
|
||
|
||
P = '/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()
|
||
|
||
|
||
# музыкальные папки-КОНТЕЙНЕРЫ, где Various Artists законен сам по себе
|
||
SKIP_PARTS = ('!Radio', 'Sbornik', 'Трибьют', 'VA ', 'Сборник', 'Сборка')
|
||
SKIP_EXACT = {
|
||
'!Retro', '!Rock&Folk/!rock_o_pop', '!Классика', '!Rock&Folk/Неголубой огонёк НГ 2004',
|
||
'!A Not sorted/Sbornik_Novij_Rok',
|
||
}
|
||
|
||
by = collections.defaultdict(list)
|
||
for r in rows:
|
||
if s(r['new_albumartist']) == 'Various Artists':
|
||
by[r['folder']].append(r)
|
||
|
||
print("КАНДИДАТЫ: папка-АВТОР + Various Artists\n")
|
||
hits = 0
|
||
for folder, rs in sorted(by.items()):
|
||
if any(p in folder for p in SKIP_PARTS):
|
||
continue
|
||
if folder in SKIP_EXACT or any(folder.startswith(x) for x in SKIP_EXACT):
|
||
continue
|
||
fam = os.path.basename(folder) # имя самой папки
|
||
parent = os.path.basename(os.path.dirname(folder)) # имя родителя
|
||
arts = collections.Counter(s(r['new_artist']) for r in rs if s(r['new_artist']))
|
||
top, cnt = arts.most_common(1)[0] if arts else ('', 0)
|
||
n = len(rs)
|
||
# автор = доминирующий artist, и он же имя родительской папки
|
||
if top and cnt >= 2 and (top == parent or top in parent or parent in top):
|
||
print(f" {n:4d} файлов top={top!r} ({cnt}/{n}) автор-папка={parent!r}")
|
||
print(f" {folder}")
|
||
hits += 1
|
||
# либо альбом назван так же, как папка, и 1 исполнитель
|
||
elif n <= 20 and cnt >= max(2, n * 0.4):
|
||
print(f" {n:4d} файлов top={top!r} ({cnt}/{n}) папка={fam!r}")
|
||
print(f" {folder}")
|
||
hits += 1
|
||
|
||
print(f"\nвсего кандидатов: {hits}")
|