[2026-09-27] eagle: personal/plans/music-artist-albumartist-repair.md personal/plans/tagwriter-container.md personal/tech/batch-data-edit-review-loop.md personal/tech/scripts/find_va_misuse.py
This commit is contained in:
1 parent
c0a76a56c9
commit
13d503e37c
4 files changed
+557
-23
No files matched your search
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""Детектор: aa='Various Artists' у папки, где БОЛЬШИНСТВО файлов имеет одного artist.
|
||||
|
||||
Класс дефекта (сессия 8, 2026-09-27):
|
||||
Папка-АЛЬБОМ помечена 'Various Artists', хотя исполнитель один.
|
||||
Причины ложного срабатывания критерия «разные artist = сборник»:
|
||||
1. разнобой написания одного исполнителя
|
||||
('Иванушки' / 'Иванушки Int.' / 'Иванушки International');
|
||||
2. несколько чужих файлов в корне папки артиста
|
||||
(7 чужих треков среди 52 треков 'Агата Кристи').
|
||||
|
||||
Правило Alex: «Папка с 1 уникальным артистом → АЛЬБОМ, albumartist = artist».
|
||||
|
||||
Запуск:
|
||||
python3 find_va_misuse.py [путь_к_APPLY-PLAN.csv]
|
||||
|
||||
Выход: список папок-кандидатов с частотой доминирующего артиста.
|
||||
⚠️ Кандидат ≠ дефект. Каждый случай подтверждать у Alex (правило сессии 7:
|
||||
«не отвечать за Alex»). Спорный случай: '!Рэп/НТЛ' — формально попадает
|
||||
под правило сборника из сессии 5 (треки в корне при наличии подпапок-альбомов).
|
||||
|
||||
Контроль после правок: гонять детектор, пока он не вернёт пусто или только
|
||||
подтверждённые Alex спорные случаи (класс выявляется итеративно).
|
||||
"""
|
||||
import csv
|
||||
import collections
|
||||
import sys
|
||||
|
||||
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)
|
||||
# доминирует один артист: >50% файлов
|
||||
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}")
|
||||
Reference in new issue
Block a user