Template
fix: reject metadata-only lyrics and refresh stale sidecars
This commit is contained in:
@@ -7,7 +7,25 @@ AUTH="${MANGTOOL_LYRICS_AUTH:-}"
|
||||
export BASE_URL AUTH
|
||||
find "$LIBRARY_DIR" -type f \( -iname '*.mp3' -o -iname '*.flac' -o -iname '*.m4a' -o -iname '*.aac' -o -iname '*.ogg' -o -iname '*.opus' -o -iname '*.wma' \) -print0 |
|
||||
while IFS= read -r -d '' audio; do
|
||||
lrc="${audio%.*}.lrc"; [[ -s "$lrc" ]] && { echo "SKIP $audio"; continue; }
|
||||
lrc="${audio%.*}.lrc"
|
||||
if [[ -s "$lrc" ]] && python3 - "$lrc" <<'PY'
|
||||
import re,sys
|
||||
text=open(sys.argv[1],encoding='utf-8-sig',errors='replace').read().replace('\r','')
|
||||
meta=re.compile(r'^\[(?:ti|ar|al|by|re|ve|offset):',re.I)
|
||||
timed=re.compile(r'^\s*\[(?:\d{1,2}:)?\d{1,2}:\d{2}(?:\.\d+)?\]\s*(.*)$')
|
||||
labels=re.compile(r'^(?:作词|作曲|词曲|编曲|制作人?|混音(?:师|助理)?|录音(?:师)?|工程师|弦乐|鼓和钢琴|电贝斯|额外编程|数字编辑|原唱|演唱|出品|发行|版权|produced|written|composer|arranged|lyrics?|music|artist|title)\s*[::\-].*$',re.I)
|
||||
body=[]
|
||||
for raw in text.split('\n'):
|
||||
line=raw.strip()
|
||||
if not line or meta.match(line): continue
|
||||
match=timed.match(line); line=(match.group(1).strip() if match else line)
|
||||
if line and not labels.match(line): body.append(line)
|
||||
sys.exit(0 if len(body)>=2 and len(''.join(body).replace(' ',''))>=8 else 1)
|
||||
PY
|
||||
then
|
||||
echo "SKIP $audio"
|
||||
continue
|
||||
fi
|
||||
meta=$(ffprobe -v error -show_entries format_tags=title,artist -of json "$audio" 2>/dev/null || true)
|
||||
result=$(AUDIO_META="$meta" python3 - <<'PY'
|
||||
import json,os,sys,urllib.parse,urllib.request
|
||||
@@ -19,10 +37,22 @@ try:
|
||||
with urllib.request.urlopen(req,timeout=15) as r: rows=json.load(r)
|
||||
except Exception: sys.exit(0)
|
||||
def n(x): return ''.join(c.lower() for c in x if c.isalnum())
|
||||
def meaningful(text):
|
||||
import re
|
||||
meta=re.compile(r'^\[(?:ti|ar|al|by|re|ve|offset):',re.I)
|
||||
timed=re.compile(r'^\s*\[(?:\d{1,2}:)?\d{1,2}:\d{2}(?:\.\d+)?\]\s*(.*)$')
|
||||
labels=re.compile(r'^(?:作词|作曲|词曲|编曲|制作人?|混音(?:师|助理)?|录音(?:师)?|工程师|弦乐|鼓和钢琴|电贝斯|额外编程|数字编辑|原唱|演唱|出品|发行|版权|produced|written|composer|arranged|lyrics?|music|artist|title)\s*[::\-].*$',re.I)
|
||||
body=[]
|
||||
for raw in text.replace('\r','').split('\n'):
|
||||
line=raw.strip()
|
||||
if not line or meta.match(line): continue
|
||||
match=timed.match(line); line=(match.group(1).strip() if match else line)
|
||||
if line and not labels.match(line): body.append(line)
|
||||
return len(body)>=2 and len(''.join(body).replace(' ',''))>=8
|
||||
best=None
|
||||
for x in rows if isinstance(rows,list) else []:
|
||||
l=x.get('lyrics','').strip(); ct=x.get('title',''); ca=x.get('artist','')
|
||||
if not l: continue
|
||||
if not meaningful(l): continue
|
||||
s=(45 if n(t)==n(ct) else 25 if n(t) in n(ct) or n(ct) in n(t) else 0)+(45 if n(a)==n(ca) else 20 if n(a) in n(ca) or n(ca) in n(a) else -40)
|
||||
s+=10 if '[' in l and ':' in l else 0
|
||||
if s>=60 and (best is None or s>best[0]): best=(s,l)
|
||||
|
||||
Reference in New Issue
Block a user