Initial commit
This commit is contained in:
commit
c208198a67
12 files changed
+1083
No files matched your search
+81
@@ -0,0 +1,81 @@
|
||||
title: Artist Sortierung mit Anfangsbuchstaben
|
||||
description: "# MusicBrainz Picard Umbenennungsscript\n\nDieses Script organisiert\
|
||||
\ Musikdateien automatisch anhand ihrer\nMetadaten in eine klare und konsistente\
|
||||
\ Ordnerstruktur.\\\nEs ist f\xFCr gro\xDFe Musiksammlungen optimiert und funktioniert\
|
||||
\ zuverl\xE4ssig\nmit MusicBrainz Picard.\n\n------------------------------------------------------------------------\n\
|
||||
\n\n## Grundprinzip\n\nDie Musik wird nach folgendem Schema einsortiert:\nArtist/<Buchstabe>/<Albumartist>/<Release-Typ>/<Album>/<Trackdatei>\n\
|
||||
\nbzw. f\xFCr Sampler:\nCompilations/<Album>/<Trackdatei>\n\n------------------------------------------------------------------------\n\
|
||||
\n## Sortierung (A\u2013Z)\n- K\xFCnstler werden anhand ihres Namens (albumartist)\
|
||||
\ einsortiert\n- Artikel wie The, Die, Der werden ignoriert\n- Unicode wird f\xFC\
|
||||
r die Sortierung vereinfacht (z.B. \xC4 \u2192 A)\n- Alles, was nicht mit einem\
|
||||
\ Buchstaben beginnt wird in # einsortiert\n\n------------------------------------------------------------------------\n\
|
||||
\n## Ordnerstruktur im Detail\n\n### Normale Artists\n\n Artist/A/Artistname/Alben/Albumname\
|
||||
\ [Infos]/01-01 - Titel.mp3\n\n # Release-Typen:\n Je nach Release wird in Unterordner\
|
||||
\ einsortiert:\n\n - Alben\n - EPs\n - Singles\n - Live\n - Remixes\n - Soundtracks\n\
|
||||
\ - Compilations\n - Mixtapes\n\n### Compilations (Various Artists)\n\n Compilations/Albumname\
|
||||
\ [Infos]/01-01 - Artist - Titel.mp3\n\n------------------------------------------------------------------------\n\
|
||||
\n## Albumordner\n\nDer Albumname wird automatisch erweitert um:\n\n- Ver\xF6ffentlichungsjahr\n\
|
||||
- Release-Kommentar (z.B. Remaster)\n- Land\n- Katalognummer\n\nBeispiel:\nHelp!\
|
||||
\ [2014 Mono Remaster] [1965] [US] [PMC 1255]\n\n------------------------------------------------------------------------\n\
|
||||
\n## Dateinamen\n\nTracks werden einheitlich benannt:\n01-01 - Titel.mp3\nbzw. bei\
|
||||
\ Compilations:\n01-01 - Artist - Titel.mp3\n\n\n------------------------------------------------------------------------\n\
|
||||
\n## Besonderheiten\n\n- Verwendet vom Anfangsbuchstaben vom %albumartist% als\
|
||||
\ Hauptkriterium f\xFCr die Ordnerstruktur\n- Disc- und Tracknummern werden automatisch\
|
||||
\ korrekt formatiert (z.B.\n 01-01)\n- Unterst\xFCtzt Multi-Disc-Releases\n\
|
||||
\n------------------------------------------------------------------------\n\n##\
|
||||
\ Ziel\n\nDas Script erzeugt eine:\n\n- klare und nachvollziehbare Ordnerstruktur\\\
|
||||
\n- konsistente Dateibenennung\\\n- saubere Trennung von Compilations und normalen\
|
||||
\ Releases\n\nIdeal f\xFCr die Nutzung mit Musikservern wie Navidrome oder \xE4\
|
||||
hnlichen\nSystemen.\n\n------------------------------------------------------------------------\n\
|
||||
\n## Voraussetzungen\n\n- Musikdateien m\xFCssen korrekt mit MusicBrainz Picard\
|
||||
\ getaggt sein\n- Felder wie %albumartist%, %album%, %tracknumber% sollten vorhanden\n\
|
||||
\ sein\n\n------------------------------------------------------------------------\n"
|
||||
author: Gofel
|
||||
license: ''
|
||||
version: '1.0'
|
||||
last_updated: 2026-03-25 17:10:09 UTC
|
||||
script_language_version: '1.1'
|
||||
script: "$noop(########################################)\n$noop(BASIS VARIABLEN)\n\
|
||||
$noop(########################################)\n\n$set(_year,\n$if($eq(%albumartist%,Various\
|
||||
\ Artists),\n$if(%_release_date%,[$left(%_release_date%,4)],),\n$if($if2(%originaldate%,%date%),[$left($if2(%originaldate%,%date%),4)],)))\n\
|
||||
\n$set(_relcomment,$if(%_releasecomment%,[$title(%_releasecomment%)],))\n\n$set(_country,$if(%releasecountry%,[%releasecountry%],))\n\
|
||||
\n$set(_catno,$if(%catalognumber%,[%catalognumber%],))\n\n$set(_foldername,\n%album%\n\
|
||||
$if(%_relcomment%, %_relcomment%,)\n$if(%_year%, %_year%,)\n$if(%_country%, %_country%,)\n\
|
||||
$if(%_catno%, %_catno%,)\n)\n\n\n$set(_discnum,\n$num(%discnumber%,$if($gt(%totaldiscs%,99),3,2)))\n\
|
||||
\n$set(_tracknum,\n$num(%tracknumber%,$if($gt(%totaltracks%,99),3,2)))\n\n\n\n$noop(########################################)\n\
|
||||
$noop(SORTIERUNG A\u2013Z)\n$noop(########################################)\n\n\
|
||||
$set(_aa,$lower(%albumartist%))\n\n$noop(Unicode Normalisierung)\n\n$set(_aa_clean,%_aa%)\n\
|
||||
\n$set(_aa_clean,$replace(%_aa_clean%,\xE4,a))\n$set(_aa_clean,$replace(%_aa_clean%,\xF6\
|
||||
,o))\n$set(_aa_clean,$replace(%_aa_clean%,\xFC,u))\n$set(_aa_clean,$replace(%_aa_clean%,\xDF\
|
||||
,ss))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xE1,a))\n$set(_aa_clean,$replace(%_aa_clean%,\xE0\
|
||||
,a))\n$set(_aa_clean,$replace(%_aa_clean%,\xE2,a))\n$set(_aa_clean,$replace(%_aa_clean%,\xE3\
|
||||
,a))\n$set(_aa_clean,$replace(%_aa_clean%,\xE5,a))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xE9\
|
||||
,e))\n$set(_aa_clean,$replace(%_aa_clean%,\xE8,e))\n$set(_aa_clean,$replace(%_aa_clean%,\xEA\
|
||||
,e))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xED,i))\n$set(_aa_clean,$replace(%_aa_clean%,\xEC\
|
||||
,i))\n$set(_aa_clean,$replace(%_aa_clean%,\xEE,i))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xF3\
|
||||
,o))\n$set(_aa_clean,$replace(%_aa_clean%,\xF2,o))\n$set(_aa_clean,$replace(%_aa_clean%,\xF4\
|
||||
,o))\n$set(_aa_clean,$replace(%_aa_clean%,\xF5,o))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xFA\
|
||||
,u))\n$set(_aa_clean,$replace(%_aa_clean%,\xF9,u))\n$set(_aa_clean,$replace(%_aa_clean%,\xFB\
|
||||
,u))\n\n$set(_aa_clean,$replace(%_aa_clean%,\xE7,c))\n\n$noop(########################################)\n\
|
||||
$noop(Artikel entfernen | nur am Anfang)\n$noop(########################################)\n\
|
||||
\n$set(_aa_stripped,%_aa_clean%)\n\n$if($rsearch(%_aa_stripped%,^the ),$set(_aa_stripped,$replace(%_aa_stripped%,the\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^der ),$set(_aa_stripped,$replace(%_aa_stripped%,der\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^die ),$set(_aa_stripped,$replace(%_aa_stripped%,die\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^das ),$set(_aa_stripped,$replace(%_aa_stripped%,das\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^ein ),$set(_aa_stripped,$replace(%_aa_stripped%,ein\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^eine ),$set(_aa_stripped,$replace(%_aa_stripped%,eine\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^le ),$set(_aa_stripped,$replace(%_aa_stripped%,le\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^la ),$set(_aa_stripped,$replace(%_aa_stripped%,la\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^les ),$set(_aa_stripped,$replace(%_aa_stripped%,les\
|
||||
\ ,)))\n$if($rsearch(%_aa_stripped%,^el ),$set(_aa_stripped,$replace(%_aa_stripped%,el\
|
||||
\ ,)))\n\n$noop(Buchstabe bestimmen)\n$set(_letter,$if($rsearch(%_aa_stripped%,^[a-z]),$upper($left(%_aa_stripped%,1)),#))\n\
|
||||
\n$noop(########################################)\n$noop(RELEASE TYPE)\n$noop(########################################)\n\
|
||||
\n$set(_type,Alben)\n\n$if($or($in(%releasetype%,mixtape),$in(%releasetype%,street)),$set(_type,Mixtapes))\n\
|
||||
$if($in(%releasetype%,compilation),$set(_type,Compilations))\n$if($in(%releasetype%,soundtrack),$set(_type,Soundtracks))\n\
|
||||
$if($in(%releasetype%,live),$set(_type,Live))\n$if($in(%releasetype%,remix),$set(_type,Remixes))\n\
|
||||
$if($in(%releasetype%,ep),$set(_type,EPs))\n$if($in(%releasetype%,single),$set(_type,Singles))\n\
|
||||
\n$noop(########################################)\n$noop(PFAD)\n$noop(########################################)\n\
|
||||
\n$if($eq(%albumartist%,Various Artists),\nCompilations/%_foldername%/%_discnum%-%_tracknum%\
|
||||
\ - %artist% - %title%,\nArtist/%_letter%/%albumartist%/%_type%/%_foldername%/%_discnum%-%_tracknum%\
|
||||
\ - %title%)\n"
|
||||
id: cc4b3c8b-f8c7-447e-9fcf-f7be7350baa1
|
||||
@@ -0,0 +1,105 @@
|
||||
# 🎵 MusicBrainz Picard Umbenennungsscript
|
||||
|
||||
Dieses Script organisiert Musikdateien automatisch anhand ihrer
|
||||
Metadaten in eine klare und konsistente Ordnerstruktur.\
|
||||
Es ist für große Musiksammlungen optimiert und funktioniert zuverlässig
|
||||
mit MusicBrainz Picard.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
|
||||
## ⚙️ Grundprinzip
|
||||
|
||||
Die Musik wird nach folgendem Schema einsortiert:
|
||||
Artist/<Buchstabe>/<Albumartist>/<Release-Typ>/<Album>/<Trackdatei>
|
||||
|
||||
bzw. für Sampler:
|
||||
Compilations/<Album>/<Trackdatei>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🔤 Sortierung (A–Z)
|
||||
- Künstler werden anhand ihres Namens (albumartist) einsortiert
|
||||
- Artikel wie The, Die, Der werden ignoriert
|
||||
- Unicode wird für die Sortierung vereinfacht (z.B. Ä → A)
|
||||
- Alles, was nicht mit einem Buchstaben beginnt wird in # einsortiert
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 📁 Ordnerstruktur im Detail
|
||||
|
||||
### 👤 Normale Artists
|
||||
|
||||
Artist/A/Artistname/Alben/Albumname [Infos]/01-01 - Titel.mp3
|
||||
|
||||
# Release-Typen:
|
||||
Je nach Release wird in Unterordner einsortiert:
|
||||
|
||||
- Alben
|
||||
- EPs
|
||||
- Singles
|
||||
- Live
|
||||
- Remixes
|
||||
- Soundtracks
|
||||
- Compilations
|
||||
- Mixtapes
|
||||
|
||||
### 🎧 Compilations (Various Artists)
|
||||
|
||||
Compilations/Albumname [Infos]/01-01 - Artist - Titel.mp3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🏷️ Albumordner
|
||||
|
||||
Der Albumname wird automatisch erweitert um:
|
||||
|
||||
- Veröffentlichungsjahr
|
||||
- Release-Kommentar (z.B. Remaster)
|
||||
- Land
|
||||
- Katalognummer
|
||||
|
||||
Beispiel:
|
||||
Help! [2014 Mono Remaster] [1965] [US] [PMC 1255]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🔢Dateinamen
|
||||
|
||||
Tracks werden einheitlich benannt:
|
||||
01-01 - Titel.mp3
|
||||
bzw. bei Compilations:
|
||||
01-01 - Artist - Titel.mp3
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🧠 Besonderheiten
|
||||
|
||||
- Verwendet vom Anfangsbuchstaben vom %albumartist% als Hauptkriterium für die Ordnerstruktur
|
||||
- Disc- und Tracknummern werden automatisch korrekt formatiert (z.B.
|
||||
01-01)
|
||||
- Unterstützt Multi-Disc-Releases
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🎯 Ziel
|
||||
|
||||
Das Script erzeugt eine:
|
||||
|
||||
- klare und nachvollziehbare Ordnerstruktur\
|
||||
- konsistente Dateibenennung\
|
||||
- saubere Trennung von Compilations und normalen Releases
|
||||
|
||||
Ideal für die Nutzung mit Musikservern wie Navidrome oder ähnlichen
|
||||
Systemen.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## ⚙️ Voraussetzungen
|
||||
|
||||
- Musikdateien müssen korrekt mit MusicBrainz Picard getaggt sein
|
||||
- Felder wie %albumartist%, %album%, %tracknumber% sollten vorhanden
|
||||
sein
|
||||
|
||||
------------------------------------------------------------------------
|
||||
@@ -0,0 +1,91 @@
|
||||
title: Artist Sortierung
|
||||
description: "# MusicBrainz Picard Umbenennungsscript\n\nDieses Script organisiert\
|
||||
\ Musikdateien automatisch anhand ihrer\nMetadaten in eine klare und konsistente\
|
||||
\ Ordnerstruktur.\\\nEs ist f\xFCr gro\xDFe Musiksammlungen optimiert und funktioniert\
|
||||
\ zuverl\xE4ssig\nmit MusicBrainz Picard.\n\n------------------------------------------------------------------------\n\
|
||||
\n## Ordnerstruktur\n\nDie Musik wird nach folgendem Schema einsortiert:\n\n###\
|
||||
\ Normale Artists\n\nArtist/<Albumartist>/<Release-Typ>/<Album>/<Trackdatei>\n\n\
|
||||
\n### Compilations (Various Artists)\n\nCompilations/<Album>/<Trackdatei>\n\n------------------------------------------------------------------------\n\
|
||||
\n## Release-Typen\n\nDas Script erkennt den Release-Typ automatisch und sortiert\
|
||||
\ entsprechend\nin Unterordner:\n\n- Alben\n- EPs\n- Singles\n- Live\n-\
|
||||
\ Remixes\n- Soundtracks\n- Compilations\n- Mixtapes\n\nFalls kein Typ erkannt\
|
||||
\ wird, wird standardm\xE4\xDFig \u201EAlben\" verwendet.\n\n------------------------------------------------------------------------\n\
|
||||
\n## Albumordner\n\nDer Albumordner wird dynamisch erweitert und kann folgende Informationen\n\
|
||||
enthalten:\n\n- Albumname\n- Release-Kommentar (z.B. Remaster, Deluxe Edition)\n\
|
||||
- Ver\xF6ffentlichungsjahr\n- Ver\xF6ffentlichungsland\n- Katalognummer\n\n\
|
||||
### Beispiel:\n\nHelp! \\[2014 Mono Remaster\\] \\[1965\\] \\[US\\] \\[PMC 1255\\\
|
||||
]\n\n------------------------------------------------------------------------\n\n\
|
||||
## Dateinamen\n\nTracks werden einheitlich benannt:\n\n### Normale Alben\n\n01-01\
|
||||
\ - Titel.mp3\n\n### Compilations\n\n01-01 - Artist - Titel.mp3\n\n------------------------------------------------------------------------\n\
|
||||
\n## Besonderheiten\n\n- Verwendet %albumartist% als Hauptkriterium f\xFCr die\
|
||||
\ Ordnerstruktur\n- Mehrere Artists bleiben im Ordnernamen erhalten (z.B. Artist\
|
||||
\ A &\n Artist B)\n- Keine alphabetische Vorsortierung (A--Z) -- alle Artists\
|
||||
\ liegen\n direkt unter Artist/\n- Disc- und Tracknummern werden automatisch\
|
||||
\ korrekt formatiert (z.B.\n 01-01)\n- Unterst\xFCtzt Multi-Disc-Releases\n\
|
||||
\n------------------------------------------------------------------------\n\n##\
|
||||
\ Ziel\n\nDas Script erzeugt eine:\n\n- klare und nachvollziehbare Ordnerstruktur\\\
|
||||
\n- konsistente Dateibenennung\\\n- saubere Trennung von Compilations und normalen\
|
||||
\ Releases\n\nIdeal f\xFCr die Nutzung mit Musikservern wie Navidrome oder \xE4\
|
||||
hnlichen\nSystemen.\n\n------------------------------------------------------------------------\n\
|
||||
\n## Voraussetzungen\n\n- Musikdateien m\xFCssen korrekt mit MusicBrainz Picard\
|
||||
\ getaggt sein\n- Felder wie %albumartist%, %album%, %tracknumber% sollten vorhanden\n\
|
||||
\ sein\n\n------------------------------------------------------------------------\n\
|
||||
\n## Beispielstruktur\n\nArtist/Justin Bieber/Alben/Purpose \\[2015\\]/01-01 - Sorry.mp3\\\
|
||||
\nArtist/Rammstein/Live/Paris \\[2017\\]/01-01 - Intro.mp3\\\nCompilations/Bravo\
|
||||
\ Hits 90/01-01 - Artist - Titel.mp3\n"
|
||||
author: Gofel
|
||||
license: ''
|
||||
version: '1.0'
|
||||
last_updated: 2026-03-25 17:07:24 UTC
|
||||
script_language_version: '1.0'
|
||||
script: |
|
||||
$set(_year,
|
||||
$if($eq(%albumartist%,Various Artists),
|
||||
$if(%_release_date%,[$left(%_release_date%,4)],),
|
||||
$if($if2(%originaldate%,%date%),[$left($if2(%originaldate%,%date%),4)],)
|
||||
)
|
||||
)
|
||||
|
||||
$set(_relcomment,
|
||||
$if(%_releasecomment%,[$title(%_releasecomment%)],)
|
||||
)
|
||||
|
||||
$set(_country,
|
||||
$if(%releasecountry%,[%releasecountry%],)
|
||||
)
|
||||
|
||||
$set(_catno,
|
||||
$if(%catalognumber%,[%catalognumber%],)
|
||||
)
|
||||
|
||||
$set(_foldername,
|
||||
%album%
|
||||
$if(%_relcomment%, %_relcomment%,)
|
||||
$if(%_year%, %_year%,)
|
||||
$if(%_country%, %_country%,)
|
||||
$if(%_catno%, %_catno%,)
|
||||
)
|
||||
|
||||
$set(_discnum,
|
||||
$num(%discnumber%,$if($gt(%totaldiscs%,99),3,2))
|
||||
)
|
||||
|
||||
$set(_tracknum,
|
||||
$num(%tracknumber%,$if($gt(%totaltracks%,99),3,2))
|
||||
)
|
||||
|
||||
$if($eq(%albumartist%,Various Artists),
|
||||
Compilations/%_foldername%/
|
||||
%_discnum%-%_tracknum% - %artist% - %title%,
|
||||
Artist/%albumartist%/
|
||||
$if($or($in(%releasetype%,mixtape),$in(%releasetype%,street)),Mixtapes,
|
||||
$if($in(%releasetype%,compilation),Compilations,
|
||||
$if($in(%releasetype%,soundtrack),Soundtracks,
|
||||
$if($in(%releasetype%,live),Live,
|
||||
$if($in(%releasetype%,remix),Remixes,
|
||||
$if($in(%releasetype%,ep),EPs,
|
||||
$if($in(%releasetype%,single),Singles,
|
||||
Alben)))))))/
|
||||
%_foldername%/
|
||||
%_discnum%-%_tracknum% - %title%)
|
||||
id: Preset 2
|
||||
@@ -0,0 +1,112 @@
|
||||
# 🎵 MusicBrainz Picard Umbenennungsscript
|
||||
|
||||
Dieses Script organisiert Musikdateien automatisch anhand ihrer
|
||||
Metadaten in eine klare und konsistente Ordnerstruktur.\
|
||||
Es ist für große Musiksammlungen optimiert und funktioniert zuverlässig
|
||||
mit MusicBrainz Picard.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 📁 Ordnerstruktur
|
||||
|
||||
Die Musik wird nach folgendem Schema einsortiert:
|
||||
|
||||
### 👤 Normale Artists
|
||||
|
||||
Artist/<Albumartist>/<Release-Typ>/<Album>/<Trackdatei>
|
||||
|
||||
|
||||
### 🎧 Compilations (Various Artists)
|
||||
|
||||
Compilations/<Album>/<Trackdatei>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🗂️ Release-Typen
|
||||
|
||||
Das Script erkennt den Release-Typ automatisch und sortiert entsprechend
|
||||
in Unterordner:
|
||||
|
||||
- Alben
|
||||
- EPs
|
||||
- Singles
|
||||
- Live
|
||||
- Remixes
|
||||
- Soundtracks
|
||||
- Compilations
|
||||
- Mixtapes
|
||||
|
||||
Falls kein Typ erkannt wird, wird standardmäßig „Alben" verwendet.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🏷️ Albumordner
|
||||
|
||||
Der Albumordner wird dynamisch erweitert und kann folgende Informationen
|
||||
enthalten:
|
||||
|
||||
- Albumname
|
||||
- Release-Kommentar (z.B. Remaster, Deluxe Edition)
|
||||
- Veröffentlichungsjahr
|
||||
- Veröffentlichungsland
|
||||
- Katalognummer
|
||||
|
||||
### Beispiel:
|
||||
|
||||
Help! \[2014 Mono Remaster\] \[1965\] \[US\] \[PMC 1255\]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🔢 Dateinamen
|
||||
|
||||
Tracks werden einheitlich benannt:
|
||||
|
||||
### Normale Alben
|
||||
|
||||
01-01 - Titel.mp3
|
||||
|
||||
### Compilations
|
||||
|
||||
01-01 - Artist - Titel.mp3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🧠 Besonderheiten
|
||||
|
||||
- Verwendet %albumartist% als Hauptkriterium für die Ordnerstruktur
|
||||
- Mehrere Artists bleiben im Ordnernamen erhalten (z.B. Artist A &
|
||||
Artist B)
|
||||
- Keine alphabetische Vorsortierung (A--Z) -- alle Artists liegen
|
||||
direkt unter Artist/
|
||||
- Disc- und Tracknummern werden automatisch korrekt formatiert (z.B.
|
||||
01-01)
|
||||
- Unterstützt Multi-Disc-Releases
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🎯 Ziel
|
||||
|
||||
Das Script erzeugt eine:
|
||||
|
||||
- klare und nachvollziehbare Ordnerstruktur\
|
||||
- konsistente Dateibenennung\
|
||||
- saubere Trennung von Compilations und normalen Releases
|
||||
|
||||
Ideal für die Nutzung mit Musikservern wie Navidrome oder ähnlichen
|
||||
Systemen.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## ⚙️ Voraussetzungen
|
||||
|
||||
- Musikdateien müssen korrekt mit MusicBrainz Picard getaggt sein
|
||||
- Felder wie %albumartist%, %album%, %tracknumber% sollten vorhanden
|
||||
sein
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## 🚀 Beispielstruktur
|
||||
|
||||
Artist/Justin Bieber/Alben/Purpose \[2015\]/01-01 - Sorry.mp3\
|
||||
Artist/Rammstein/Live/Paris \[2017\]/01-01 - Intro.mp3\
|
||||
Compilations/Bravo Hits 90/01-01 - Artist - Titel.mp3
|
||||
@@ -0,0 +1 @@
|
||||
Sammlung von Dateibenennungsscripten für den Import in Musicbrainz Picard
|
||||
@@ -0,0 +1,202 @@
|
||||
[application]
|
||||
version=2.13.3.final0
|
||||
|
||||
[persist]
|
||||
album_view_header_locked=false
|
||||
album_view_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x12\xf8\xff\x3\0\0\0\xf\0\0\0\x6\0\0\0\x64\0\0\0\x5\0\0\0\x64\0\0\0\x4\0\0\0\x64\0\0\0\x3\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\f\0\0\0\x64\0\0\0\v\0\0\0\x64\0\0\0\n\0\0\0\x64\0\0\0\t\0\0\0\x64\0\0\0\b\0\0\0\x64\0\0\0\a\0\0\0\x64\0\0\x4\xcc\0\0\0\x12\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x12\0\0\x2q\0\0\0\x1\0\0\0\0\0\0\0\x32\0\0\0\x1\0\0\0\0\0\0\x2)\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\x2\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\x3\xe8\x1\0\0\0\x64)
|
||||
albumsearchdialog_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\r\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\a\xa3\0\0\0\xe\0\x1\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x84\0\0\0\0\0\0\0\xe\0\0\x1\xa8\0\0\0\x1\0\0\0\0\0\0\0X\0\0\0\x1\0\0\0\0\0\0\0w\0\0\0\x1\0\0\0\0\0\0\0\x39\0\0\0\x1\0\0\0\0\0\0\0L\0\0\0\x1\0\0\0\0\0\0\0<\0\0\0\x1\0\0\0\0\0\0\x1\x65\0\0\0\x1\0\0\0\0\0\0\0\xc8\0\0\0\x1\0\0\0\0\0\0\0o\0\0\0\x1\0\0\0\0\0\0\0P\0\0\0\x1\0\0\0\0\0\0\0}\0\0\0\x1\0\0\0\0\0\0\0H\0\0\0\x1\0\0\0\0\0\0\0\x65\0\0\0\x1\0\0\0\0\0\0\0U\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\xff\xff\xff\xff)
|
||||
current_browser_path=/srv/cifs/unRAID/Media/Musik/[0] Navidrome/Artist
|
||||
file_view_header_locked=false
|
||||
file_view_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x12\xf8\xff\x3\0\0\0\xf\0\0\0\x6\0\0\0\x64\0\0\0\x5\0\0\0\x64\0\0\0\x4\0\0\0\x64\0\0\0\x3\0\0\0\x64\0\0\0\x11\0\0\0\x64\0\0\0\x10\0\0\0\x64\0\0\0\xf\0\0\0\x64\0\0\0\xe\0\0\0\x64\0\0\0\r\0\0\0\x64\0\0\0\f\0\0\0\x64\0\0\0\v\0\0\0\x64\0\0\0\n\0\0\0\x64\0\0\0\t\0\0\0\x64\0\0\0\b\0\0\0\x64\0\0\0\a\0\0\0\x64\0\0\x2\xbb\0\0\0\x12\x1\x1\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\0\0\0\0\x12\0\0\x2%\0\0\0\x1\0\0\0\0\0\0\0\x32\0\0\0\x1\0\0\0\0\0\0\0\x64\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\x2\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\x3\xe8\x1\0\0\0\x64)
|
||||
geometry_AlbumInfoDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\a\x80\0\0\0\x14\0\0\n\xcc\0\0\x2Y\0\0\a\x80\0\0\0\x14\0\0\n\xcc\0\0\x2Y\0\0\0\x2\0\0\0\0\a\x80\0\0\a\x80\0\0\0\x14\0\0\n\xcc\0\0\x2Y)
|
||||
geometry_AlbumSearchDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\a\x80\0\0\0\x14\0\0\xe\xe1\0\0\x2\x44\0\0\a\x80\0\0\0\x14\0\0\xe\xe1\0\0\x2\x44\0\0\0\x2\0\0\0\0\a\x80\0\0\a\x80\0\0\0\x14\0\0\xe\xe1\0\0\x2\x44)
|
||||
geometry_CAATypesSelectorDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x1\x33\0\0\0\xa5\0\0\x4\xbc\0\0\x2\x64\0\0\x1\x33\0\0\0\xa5\0\0\x4\xbc\0\0\x2\x64\0\0\0\x1\0\0\0\0\a\x80\0\0\x1\x33\0\0\0\xa5\0\0\x4\xbc\0\0\x2\x64)
|
||||
geometry_ClusterInfoDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2j\0\0\0\xf6\0\0\x5\x2\0\0\x2\xa9\0\0\x2j\0\0\0\xf6\0\0\x5\x2\0\0\x2\xa9\0\0\0\x1\0\0\0\0\a\x80\0\0\x2j\0\0\0\xf6\0\0\x5\x2\0\0\x2\xa9)
|
||||
geometry_EditTagDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2\xee\0\0\x1S\0\0\x4}\0\0\x2L\0\0\x2\xee\0\0\x1S\0\0\x4}\0\0\x2L\0\0\0\x1\0\0\0\0\a\x80\0\0\x2\xee\0\0\x1S\0\0\x4}\0\0\x2L)
|
||||
geometry_FileInfoDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\xf\0\0\0\0\x14\0\0\x11\x98\0\0\x1\xc7\0\0\xf\0\0\0\0\x14\0\0\x11\x98\0\0\x1\xc7\0\0\0\0\0\0\0\0\a\x80\0\0\xf\0\0\0\0\x14\0\0\x11\x98\0\0\x1\xc7)
|
||||
geometry_MainWindow=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\a\x7f\0\0\x3\xef\0\0\a\x80\0\0\0\0\0\0\rT\0\0\x3g\0\0\0\x1\x2\0\0\0\a\x80\0\0\0\0\0\0\0\0\0\0\a\x7f\0\0\x3\xef)
|
||||
geometry_OptionsDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\xf\0\0\0\0\x14\0\0\x15\x3\0\0\x3z\0\0\xf\0\0\0\0\x14\0\0\x15\x3\0\0\x3z\0\0\0\0\0\0\0\0\a\x80\0\0\xf\0\0\0\0\x14\0\0\x15\x3\0\0\x3z)
|
||||
geometry_ScriptEditorDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\a\x7f\0\0\x3Z\0\0\0\0\0\0\0\0\0\0\a\x7f\0\0\x3Z\0\0\0\x1\0\0\0\0\a\x80\0\0\0\0\0\0\0\0\0\0\a\x7f\0\0\x3Z)
|
||||
geometry_ScriptingDocumentationDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\a\x80\0\0\0\0\0\0\xe\xff\0\0\x3\xef\0\0\a\x80\0\0\0\x14\0\0\t\xb9\0\0\x1\xa3\0\0\0\0\x2\0\0\0\a\x80\0\0\a\x80\0\0\0\0\0\0\xe\xff\0\0\x3\xef)
|
||||
geometry_TrackInfoDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\fg\0\0\0\x14\0\0\xe\xff\0\0\x1\xc7\0\0\fg\0\0\0\x14\0\0\xe\xff\0\0\x1\xc7\0\0\0\x2\0\0\0\0\a\x80\0\0\fg\0\0\0\x14\0\0\xe\xff\0\0\x1\xc7)
|
||||
geometry_TrackSearchDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\x2]\0\0\0\x14\0\0\t/\0\0\x2\x83\0\0\x2]\0\0\0\x14\0\0\t/\0\0\x2\x83\0\0\0\x1\0\0\0\0\a\x80\0\0\x2]\0\0\0\x14\0\0\t/\0\0\x2\x83)
|
||||
geometry_WinCompatDialog=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\xd9\0\0\0\x64\0\0\x2\x33\0\0\x1\xb5\0\0\0\xd9\0\0\0\x64\0\0\x2\x33\0\0\x1\xb5\0\0\0\x1\0\0\0\0\a\x80\0\0\0\xd9\0\0\0\x64\0\0\x2\x33\0\0\x1\xb5)
|
||||
last_selected_profile_pos=0
|
||||
last_selected_script_pos=2
|
||||
mediaplayer_playback_rate=1
|
||||
mediaplayer_volume=50
|
||||
metadatabox_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6\xee\0\0\0\x3\0\0\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x84\0\0\0\0\0\0\0\x3\0\0\0\xd4\0\0\0\x1\0\0\0\0\0\0\x2\x65\0\0\0\x1\0\0\0\0\0\0\x3\xb5\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64)
|
||||
options_last_active_page=profiles
|
||||
options_pages_tree_state=@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x19\x80\x5\x95\xe\0\0\0\0\0\0\0\x8c\ageneral\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\bprofiles\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\bmetadata\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\breleases\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x18\x80\x5\x95\r\0\0\0\0\0\0\0\x8c\x6genres\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x19\x80\x5\x95\xe\0\0\0\0\0\0\0\x8c\aratings\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x16\x80\x5\x95\v\0\0\0\0\0\0\0\x8c\x4tags\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0(\x80\x5\x95\x1d\0\0\0\0\0\0\0\x8c\x16tags_compatibility_id3\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0(\x80\x5\x95\x1d\0\0\0\0\0\0\0\x8c\x16tags_compatibility_aac\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0(\x80\x5\x95\x1d\0\0\0\0\0\0\0\x8c\x16tags_compatibility_ac3\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0)\x80\x5\x95\x1e\0\0\0\0\0\0\0\x8c\x17tags_compatibility_wave\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x17\x80\x5\x95\f\0\0\0\0\0\0\0\x8c\x5\x63over\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\x11\x63over_art_archive\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1d\x80\x5\x95\x12\0\0\0\0\0\0\0\x8c\vlocal_files\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1e\x80\x5\x95\x13\0\0\0\0\0\0\0\x8c\ffilerenaming\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0%\x80\x5\x95\x1a\0\0\0\0\0\0\0\x8c\x13\x66ilerenaming_compat\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0 \x80\x5\x95\x15\0\0\0\0\0\0\0\x8c\xe\x66ingerprinting\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\bcdlookup\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x19\x80\x5\x95\xe\0\0\0\0\0\0\0\x8c\aplugins\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1b\x80\x5\x95\x10\0\0\0\0\0\0\0\x8c\tscripting\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1b\x80\x5\x95\x10\0\0\0\0\0\0\0\x8c\tinterface\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\"\x80\x5\x95\x17\0\0\0\0\0\0\0\x8c\x10interface_colors\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0$\x80\x5\x95\x19\0\0\0\0\0\0\0\x8c\x12interface_top_tags\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\x11interface_toolbar\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\badvanced\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x19\x80\x5\x95\xe\0\0\0\0\0\0\0\x8c\anetwork\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1a\x80\x5\x95\xf\0\0\0\0\0\0\0\x8c\bmatching\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1d\x80\x5\x95\x12\0\0\0\0\0\0\0\x8c\vmaintenance\x94\x88\x86\x94.)
|
||||
plugins_list_sort_order=0
|
||||
plugins_list_sort_section=0
|
||||
plugins_list_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x3\xde\0\0\0\x3\x1\x1\0\0\0\0\0\0\x1\0\0\0\x2\0\0\0\x64\xff\xff\xff\xff\0\0\0\x81\0\0\0\x2\0\0\0\x3\0\0\x3\x39\0\0\0\x1\0\0\0\x1\0\0\0M\0\0\0\x1\0\0\0\x3\0\0\0X\0\0\0\x1\0\0\0\x3\0\0\x3\xe8\0\0\0\0\x64)
|
||||
profile_settings_tree_expanded_list=@Invalid()
|
||||
script_editor_show_documentation=false
|
||||
script_editor_wordwrap=false
|
||||
show_changes_first=false
|
||||
splitters_AlbumInfoDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_AlbumSearchDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_CAATypesSelectorDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_ClusterInfoDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_EditTagDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_FileInfoDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_MainWindow=@Variant(\0\0\0\b\0\0\0\x2\0\0\0\x36\0m\0\x61\0i\0n\0_\0w\0i\0n\0\x64\0o\0w\0_\0\x62\0o\0t\0t\0o\0m\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\xfb\0\0\x1\x1\0\xff\xff\xff\xff\x1\0\0\0\x2\0\x94.\0\0\0&\0m\0\x61\0i\0n\0_\0p\0\x61\0n\0\x65\0l\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x39\x80\x5\x95.\0\0\0\0\0\0\0\x96#\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x3\0\0\x1\xdf\0\0\x2\xae\0\0\x4\xce\0\xff\xff\xff\xff\x1\0\0\0\x1\0\x94.)
|
||||
splitters_OptionsDialog=@Variant(\0\0\0\b\0\0\0\x5\0\0\0\x34\0s\0\x63\0r\0i\0p\0t\0i\0n\0g\0_\0o\0p\0t\0i\0o\0n\0s\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\xdd\0\0\x3\r\0\xff\xff\xff\xff\x1\0\0\0\x1\0\x94.\0\0\0\x44\0r\0\x65\0n\0\x61\0m\0i\0n\0g\0_\0o\0p\0t\0i\0o\0n\0s\0_\0\x65\0x\0\x61\0m\0p\0l\0\x65\0s\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\x64\0\0\0\x64\x1\xff\xff\xff\xff\x1\0\0\0\x1\0\x94.\0\0\0.\0p\0r\0o\0\x66\0i\0l\0\x65\0_\0\x65\0\x64\0i\0t\0o\0r\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\0\0\0\x1\0\0\xff\xff\xff\xff\x1\0\0\0\x1\0\x94.\0\0\0\"\0p\0l\0u\0g\0i\0n\0s\0_\0\x63\0o\0n\0t\0\x61\0i\0n\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x2\x8e\0\0\0\x86\x1\0\0\0\x2\x1\0\0\0\x2\0\x94.\0\0\0\x1e\0\x64\0i\0\x61\0l\0o\0g\0_\0s\0p\0l\0i\0t\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\xf1\0\0\x2\x19\0\xff\xff\xff\xff\x1\0\0\0\x1\0\x94.)
|
||||
splitters_ScriptEditorDialog=@Variant(\0\0\0\b\0\0\0\x3\0\0\0H\0s\0p\0l\0i\0t\0t\0\x65\0r\0_\0\x62\0\x65\0t\0w\0\x65\0\x65\0n\0_\0\x65\0\x64\0i\0t\0o\0r\0_\0\x61\0n\0\x64\0_\0\x65\0x\0\x61\0m\0p\0l\0\x65\0s\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\xae\0\0\x1\x63\x1\xff\xff\xff\xff\x1\0\0\0\x2\0\x94.\0\0\0R\0s\0p\0l\0i\0t\0t\0\x65\0r\0_\0\x62\0\x65\0t\0w\0\x65\0\x65\0n\0_\0\x65\0\x64\0i\0t\0o\0r\0_\0\x61\0n\0\x64\0_\0\x64\0o\0\x63\0u\0m\0\x65\0n\0t\0\x61\0t\0i\0o\0n\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\x1\0\0\0\0\x64\x1\xff\xff\xff\xff\x1\0\0\0\x1\x1\x94.\0\0\0\x42\0s\0p\0l\0i\0t\0t\0\x65\0r\0_\0\x62\0\x65\0t\0w\0\x65\0\x65\0n\0_\0\x62\0\x65\0\x66\0o\0r\0\x65\0_\0\x61\0n\0\x64\0_\0\x61\0\x66\0t\0\x65\0r\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x35\x80\x5\x95*\0\0\0\0\0\0\0\x96\x1f\0\0\0\0\0\0\0\0\0\0\xff\0\0\0\x1\0\0\0\x2\0\0\0\xdc\0\0\x6\x82\x1\xff\xff\xff\xff\x1\0\0\0\x1\x1\x94.)
|
||||
splitters_ScriptingDocumentationDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_TrackInfoDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_TrackSearchDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
splitters_WinCompatDialog=@Variant(\0\0\0\b\0\0\0\0)
|
||||
tracksearchdialog_header_state=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\a\x1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x6\x97\0\0\0\b\0\x1\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\xff\xff\xff\xff\0\0\0\x84\0\0\0\0\0\0\0\b\0\0\0\xcc\0\0\0\x1\0\0\0\0\0\0\0\x44\0\0\0\x1\0\0\0\0\0\0\0\xd7\0\0\0\x1\0\0\0\0\0\0\0\xf8\0\0\0\x1\0\0\0\0\0\0\0L\0\0\0\x1\0\0\0\0\0\0\0\xa5\0\0\0\x1\0\0\0\0\0\0\0}\0\0\0\x1\0\0\0\0\0\0\x2J\0\0\0\x1\0\0\0\0\0\0\x3\xe8\0\0\0\0\x64)
|
||||
view_cover_art=true
|
||||
view_file_browser=false
|
||||
view_metadata_view=true
|
||||
view_toolbar=true
|
||||
window_maximized=true
|
||||
window_state=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\a\x80\0\0\x3\x88\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x2\0\0\0\x2\0\0\0\x2\0\0\0\x18\0m\0\x61\0i\0n\0_\0t\0o\0o\0l\0\x62\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x1c\0s\0\x65\0\x61\0r\0\x63\0h\0_\0t\0o\0o\0l\0\x62\0\x61\0r\x1\0\0\x4\x8b\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x3\0\0\0\x1\0\0\0\x1c\0p\0l\0\x61\0y\0\x65\0r\0_\0t\0o\0o\0l\0\x62\0\x61\0r\0\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
|
||||
|
||||
[profiles]
|
||||
user_profile_settings=@Variant(\0\0\0\b\0\0\0\x1\0\0\0H\0\x37\0\x34\0\x64\0\x36\0\x66\0\x62\0\x39\0\x30\0-\0\x30\0\x39\0\x37\0\x32\0-\0\x34\0\x37\0\x65\0\x36\0-\0\x39\0\x61\0\x32\0\x65\0-\0\x35\0\x66\0\x34\0\x37\0\x64\0\x32\0\x61\0\x39\0\x61\0\x30\0\x37\0\x34\0\0\0\b\0\0\0\0)
|
||||
user_profiles=@Variant(\0\0\0\t\0\0\0\x1\0\0\0\b\0\0\0\x4\0\0\0\n\0t\0i\0t\0l\0\x65\0\0\0\n\0\0\0\x10\0S\0\x65\0t\0t\0i\0n\0g\0s\0\0\0\x10\0p\0o\0s\0i\0t\0i\0o\0n\0\0\0\x2\0\0\0\0\0\0\0\x4\0i\0\x64\0\0\0\n\0\0\0H\0\x37\0\x34\0\x64\0\x36\0\x66\0\x62\0\x39\0\x30\0-\0\x30\0\x39\0\x37\0\x32\0-\0\x34\0\x37\0\x65\0\x36\0-\0\x39\0\x61\0\x32\0\x65\0-\0\x35\0\x66\0\x34\0\x37\0\x64\0\x32\0\x61\0\x39\0\x61\0\x30\0\x37\0\x34\0\0\0\xe\0\x65\0n\0\x61\0\x62\0l\0\x65\0\x64\0\0\0\x1\x1)
|
||||
|
||||
[setting]
|
||||
aac_save_ape=true
|
||||
ac3_save_ape=true
|
||||
acoustid_apikey=2pMCPE1Kio
|
||||
acoustid_fpcalc=/usr/bin/fpcalc
|
||||
add_synced_lyrics=false
|
||||
add_unsynced_lyrics=true
|
||||
analyze_new_files=false
|
||||
artist_locales=@Variant(\0\0\0\t\0\0\0\x1\0\0\0\n\0\0\0\x4\0\x65\0n)
|
||||
artists_genres=true
|
||||
ascii_filenames=false
|
||||
browser_integration=true
|
||||
browser_integration_localhost_only=true
|
||||
browser_integration_port=8000
|
||||
builtin_search=true
|
||||
ca_providers=@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1d\x80\x5\x95\x12\0\0\0\0\0\0\0\x8c\vLocal Files\x94\x88\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\x11\x43over Art Archive\x94\x89\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\"\x80\x5\x95\x17\0\0\0\0\0\0\0\x8c\x10UrlRelationships\x94\x89\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0!\x80\x5\x95\x16\0\0\0\0\0\0\0\x8c\xf\x43\x61\x61ReleaseGroup\x94\x89\x86\x94.)
|
||||
caa_approved_only=false
|
||||
caa_image_size=-1
|
||||
caa_image_types=@Variant(\0\0\0\t\0\0\0\x1\0\0\0\n\0\0\0\n\0\x66\0r\0o\0n\0t)
|
||||
caa_image_types_to_omit=matrix/runout, raw/unedited, watermark
|
||||
caa_restrict_image_types=true
|
||||
cd_lookup_device=/dev/cdrom
|
||||
check_for_plugin_updates=false
|
||||
check_for_updates=true
|
||||
clear_existing_tags=true
|
||||
cluster_lookup_threshold=0.7
|
||||
cluster_new_files=true
|
||||
completeness_ignore_data=false
|
||||
completeness_ignore_pregap=false
|
||||
completeness_ignore_silence=false
|
||||
completeness_ignore_videos=false
|
||||
convert_punctuation=false
|
||||
cover_image_filename=cover
|
||||
delete_empty_dirs=true
|
||||
dont_write_tags=false
|
||||
embed_only_one_front_image=true
|
||||
enable_ratings=false
|
||||
enable_tagger_scripts=true
|
||||
enabled_plugins=@Variant(\0\0\0\t\0\0\0\x1\0\0\0\n\0\0\0\x1a\0p\0i\0\x63\0\x61\0r\0\x64\0-\0s\0o\0l\0z\0\x65\0r)
|
||||
exported_lrc=true
|
||||
exported_lrc_filename=%filename%.lrc
|
||||
file_lookup_threshold=0.7
|
||||
file_renaming_scripts="@Variant(\0\0\0\b\0\0\0\x5\0\0\0H\0\x63\0\x63\0\x34\0\x62\0\x33\0\x63\0\x38\0\x62\0-\0\x66\0\x38\0\x63\0\x37\0-\0\x34\0\x34\0\x37\0\x65\0-\0\x39\0\x66\0\x63\0\x66\0-\0\x66\0\x37\0\x62\0\x65\0\x37\0\x33\0\x35\0\x30\0\x62\0\x61\0\x61\0\x31\0\0\0\b\0\0\0\t\0\0\0\xe\0v\0\x65\0r\0s\0i\0o\0n\0\0\0\n\0\0\0\x6\0\x31\0.\0\x30\0\0\0\n\0t\0i\0t\0l\0\x65\0\0\0\n\0\0\0N\0\x41\0r\0t\0i\0s\0t\0 \0S\0o\0r\0t\0i\0\x65\0r\0u\0n\0g\0 \0m\0i\0t\0 \0\x41\0n\0\x66\0\x61\0n\0g\0s\0\x62\0u\0\x63\0h\0s\0t\0\x61\0\x62\0\x65\0n\0\0\0.\0s\0\x63\0r\0i\0p\0t\0_\0l\0\x61\0n\0g\0u\0\x61\0g\0\x65\0_\0v\0\x65\0r\0s\0i\0o\0n\0\0\0\n\0\0\0\x6\0\x31\0.\0\x31\0\0\0\f\0s\0\x63\0r\0i\0p\0t\0\0\0\n\0\0\x1e\x9c\0$\0n\0o\0o\0p\0(\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0)\0\n\0$\0n\0o\0o\0p\0(\0\x42\0\x41\0S\0I\0S\0 \0V\0\x41\0R\0I\0\x41\0\x42\0L\0\x45\0N\0)\0\n\0$\0n\0o\0o\0p\0(\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0y\0\x65\0\x61\0r\0,\0\n\0$\0i\0\x66\0(\0$\0\x65\0q\0(\0%\0\x61\0l\0\x62\0u\0m\0\x61\0r\0t\0i\0s\0t\0%\0,\0V\0\x61\0r\0i\0o\0u\0s\0 \0\x41\0r\0t\0i\0s\0t\0s\0)\0,\0\n\0$\0i\0\x66\0(\0%\0_\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0_\0\x64\0\x61\0t\0\x65\0%\0,\0[\0$\0l\0\x65\0\x66\0t\0(\0%\0_\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0_\0\x64\0\x61\0t\0\x65\0%\0,\0\x34\0)\0]\0,\0)\0,\0\n\0$\0i\0\x66\0(\0$\0i\0\x66\0\x32\0(\0%\0o\0r\0i\0g\0i\0n\0\x61\0l\0\x64\0\x61\0t\0\x65\0%\0,\0%\0\x64\0\x61\0t\0\x65\0%\0)\0,\0[\0$\0l\0\x65\0\x66\0t\0(\0$\0i\0\x66\0\x32\0(\0%\0o\0r\0i\0g\0i\0n\0\x61\0l\0\x64\0\x61\0t\0\x65\0%\0,\0%\0\x64\0\x61\0t\0\x65\0%\0)\0,\0\x34\0)\0]\0,\0)\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0r\0\x65\0l\0\x63\0o\0m\0m\0\x65\0n\0t\0,\0$\0i\0\x66\0(\0%\0_\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0\x63\0o\0m\0m\0\x65\0n\0t\0%\0,\0[\0$\0t\0i\0t\0l\0\x65\0(\0%\0_\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0\x63\0o\0m\0m\0\x65\0n\0t\0%\0)\0]\0,\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x63\0o\0u\0n\0t\0r\0y\0,\0$\0i\0\x66\0(\0%\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0\x63\0o\0u\0n\0t\0r\0y\0%\0,\0[\0%\0r\0\x65\0l\0\x65\0\x61\0s\0\x65\0\x63\0o\0u\0n\0t\0r\0y\0%\0]\0,\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x63\0\x61\0t\0n\0o\0,\0$\0i\0\x66\0(\0%\0\x63\0\x61\0t\0\x61\0l\0o\0g\0n\0u\0m\0\x62\0\x65\0r\0%\0,\0[\0%\0\x63\0\x61\0t\0\x61\0l\0o\0g\0n\0u\0m\0\x62\0\x65\0r\0%\0]\0,\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x66\0o\0l\0\x64\0\x65\0r\0n\0\x61\0m\0\x65\0,\0\n\0%\0\x61\0l\0\x62\0u\0m\0%\0\n\0$\0i\0\x66\0(\0%\0_\0r\0\x65\0l\0\x63\0o\0m\0m\0\x65\0n\0t\0%\0,\0 \0%\0_\0r\0\x65\0l\0\x63\0o\0m\0m\0\x65\0n\0t\0%\0,\0)\0\n\0$\0i\0\x66\0(\0%\0_\0y\0\x65\0\x61\0r\0%\0,\0 \0%\0_\0y\0\x65\0\x61\0r\0%\0,\0)\0\n\0$\0i\0\x66\0(\0%\0_\0\x63\0o\0u\0n\0t\0r\0y\0%\0,\0 \0%\0_\0\x63\0o\0u\0n\0t\0r\0y\0%\0,\0)\0\n\0$\0i\0\x66\0(\0%\0_\0\x63\0\x61\0t\0n\0o\0%\0,\0 \0%\0_\0\x63\0\x61\0t\0n\0o\0%\0,\0)\0\n\0)\0\n\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x64\0i\0s\0\x63\0n\0u\0m\0,\0\n\0$\0n\0u\0m\0(\0%\0\x64\0i\0s\0\x63\0n\0u\0m\0\x62\0\x65\0r\0%\0,\0$\0i\0\x66\0(\0$\0g\0t\0(\0%\0t\0o\0t\0\x61\0l\0\x64\0i\0s\0\x63\0s\0%\0,\0\x39\0\x39\0)\0,\0\x33\0,\0\x32\0)\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0t\0r\0\x61\0\x63\0k\0n\0u\0m\0,\0\n\0$\0n\0u\0m\0(\0%\0t\0r\0\x61\0\x63\0k\0n\0u\0m\0\x62\0\x65\0r\0%\0,\0$\0i\0\x66\0(\0$\0g\0t\0(\0%\0t\0o\0t\0\x61\0l\0t\0r\0\x61\0\x63\0k\0s\0%\0,\0\x39\0\x39\0)\0,\0\x33\0,\0\x32\0)\0)\0)\0\n\0\n\0\n\0\n\0$\0n\0o\0o\0p\0(\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0)\0\n\0$\0n\0o\0o\0p\0(\0S\0O\0R\0T\0I\0\x45\0R\0U\0N\0G\0 \0\x41 \x13\0Z\0)\0\n\0$\0n\0o\0o\0p\0(\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0#\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0,\0$\0l\0o\0w\0\x65\0r\0(\0%\0\x61\0l\0\x62\0u\0m\0\x61\0r\0t\0i\0s\0t\0%\0)\0)\0\n\0\n\0$\0n\0o\0o\0p\0(\0U\0n\0i\0\x63\0o\0\x64\0\x65\0 \0N\0o\0r\0m\0\x61\0l\0i\0s\0i\0\x65\0r\0u\0n\0g\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0%\0_\0\x61\0\x61\0%\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0$\0r\0\x65\0p\0l\0\x61\0\x63\0\x65\0(\0%\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0%\0,\0\xe4\0,\0\x61\0)\0)\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0$\0r\0\x65\0p\0l\0\x61\0\x63\0\x65\0(\0%\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0%\0,\0\xf6\0,\0o\0)\0)\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0$\0r\0\x65\0p\0l\0\x61\0\x63\0\x65\0(\0%\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0%\0,\0\xfc\0,\0u\0)\0)\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0$\0r\0\x65\0p\0l\0\x61\0\x63\0\x65\0(\0%\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0%\0,\0\xdf\0,\0s\0s\0)\0)\0\n\0\n\0$\0s\0\x65\0t\0(\0_\0\x61\0\x61\0_\0\x63\0l\0\x65\0\x61\0n\0,\0$\0r\0\x65\0p\0l\0\x61\0\x63\0\x65\0(\Line truncated
|
||||
file_save_warning=false
|
||||
filebrowser_horizontal_autoscroll=true
|
||||
fingerprinting_system=acoustid
|
||||
fix_missing_seekpoints_flac=false
|
||||
folksonomy_tags=false
|
||||
fpcalc_threads=2
|
||||
genres_filter=-seen live\n-favorites\n-fixme\n-owned
|
||||
guess_tracknumber_and_title=true
|
||||
happidev_apikey="hk752-j0TbeIfHoMei09dnRYjp63QzuMfFA3gFrL "
|
||||
id3v23_join_with=/
|
||||
id3v2_encoding=utf-8
|
||||
ignore_existing_acoustid_fingerprints=false
|
||||
ignore_file_mbids=false
|
||||
ignore_hidden_files=false
|
||||
ignore_regex=
|
||||
ignore_track_duration_difference_under=2
|
||||
image_type_as_filename=false
|
||||
interface_colors_dark=@Variant(\0\0\0\b\0\0\0\n\0\0\0\"\0t\0\x61\0g\0s\0t\0\x61\0t\0u\0s\0_\0r\0\x65\0m\0o\0v\0\x65\0\x64\0\0\0\n\0\0\0\xe\0#\0\x66\0\x66\0\x30\0\x30\0\x30\0\x30\0\0\0\"\0t\0\x61\0g\0s\0t\0\x61\0t\0u\0s\0_\0\x63\0h\0\x61\0n\0g\0\x65\0\x64\0\0\0\n\0\0\0\xe\0#\0\x62\0\x38\0\x38\0\x36\0\x30\0\x62\0\0\0\x1e\0t\0\x61\0g\0s\0t\0\x61\0t\0u\0s\0_\0\x61\0\x64\0\x64\0\x65\0\x64\0\0\0\n\0\0\0\xe\0#\0\x30\0\x30\0\x38\0\x30\0\x30\0\x30\0\0\0\x16\0l\0o\0g\0_\0w\0\x61\0r\0n\0i\0n\0g\0\0\0\n\0\0\0\xe\0#\0\x66\0\x66\0\x38\0\x63\0\x30\0\x30\0\0\0\x10\0l\0o\0g\0_\0i\0n\0\x66\0o\0\0\0\n\0\0\0\xe\0#\0\x66\0\x66\0\x66\0\x66\0\x66\0\x66\0\0\0\x12\0l\0o\0g\0_\0\x65\0r\0r\0o\0r\0\0\0\n\0\0\0\xe\0#\0\x66\0\x66\0\x30\0\x30\0\x30\0\x30\0\0\0\x12\0l\0o\0g\0_\0\x64\0\x65\0\x62\0u\0g\0\0\0\n\0\0\0\xe\0#\0\x64\0\x64\0\x61\0\x30\0\x64\0\x64\0\0\0\x18\0\x65\0n\0t\0i\0t\0y\0_\0s\0\x61\0v\0\x65\0\x64\0\0\0\n\0\0\0\xe\0#\0\x30\0\x30\0\x61\0\x61\0\x30\0\x30\0\0\0\x1c\0\x65\0n\0t\0i\0t\0y\0_\0p\0\x65\0n\0\x64\0i\0n\0g\0\0\0\n\0\0\0\xe\0#\0\x38\0\x30\0\x38\0\x30\0\x38\0\x30\0\0\0\x18\0\x65\0n\0t\0i\0t\0y\0_\0\x65\0r\0r\0o\0r\0\0\0\n\0\0\0\xe\0#\0\x63\0\x38\0\x30\0\x30\0\x30\0\x30)
|
||||
itunes_compatible_grouping=false
|
||||
join_genres=
|
||||
list_of_scripts="@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\xba\x80\x5\x95\xaf\0\0\0\0\0\0\0(K\0\x8c\x10Multiple artists\x94\x88\x8c\x92# Multiple artists\n$setmulti(albumartists,%_albumartists%)\n$setmulti(albumartistssort,%_albumartists_sort%)\n$setmulti(artistssort,%_artists_sort%)\x94t\x94.)", "@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\xa3\x80\x5\x95\x98\0\0\0\0\0\0\0(K\x1\x8c\rAlbum Version\x94\x88\x8c~# Album Version\n$set(musicbrainz_albumcomment,%_releasecomment%)\n$if(%_recordingcomment%, $set(subtitle,%_recordingcomment%))\n\x94t\x94.)", "@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\xc8\x80\x5\x95\xbd\0\0\0\0\0\0\0(K\x2\x8c\x1aRelease and Original dates\x94\x88\x8c\x96# Release and Original dates\n$set(releasedate,%date%)\n$set(date,%_recording_firstreleasedate%)\n$set(originaldate,%originaldate%)\n$delete(originalyear)\x94t\x94.)", "@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\x2\x39\x80\x5\x95.\x2\0\0\0\0\0\0(K\x3\x8c\x12\x44\x65scription remove\x94\x89X\f\x2\0\0$if(\n$or(\n$eq($trim(%description%),\"Downloaded from music.binimum.org/tidal.squid.wtf\"),\n$eq($trim(%description%),\"https://github.com/afkarxyz/SpotiFLAC\"),\n$eq($trim(%description%),\" \")\n),\n$delete(description)\n)\n\n\n$if(\n$or(\n$eq($trim(%comment%),\"Rapidshare FUCK OFF !!!!!\"),\n$eq($trim(%comment%),\" \"),\n$eq($trim(%comment%),\" \")\n),\n$delete(comment)\n)\n\n\n$if(\n$or(\n$eq($trim(%comment:ID3v1%),\"Rapidshare FUCK OFF !!!!!\"),\n$eq($trim(%comment:ID3v1%),\" \"),\n$eq($trim(%comment:ID3v1%),\" \")\n),\n$delete(comment:ID3v1)\n)\n\x94t\x94.)", "@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\xa9\x80\x5\x95\x9e\0\0\0\0\0\0\0(K\x4\x8c\x13Save Spotify Lyrics\x94\x89\x8c~$set(_oldlyrics,$if2(%lyrics%,%unsyncedlyrics%))\n\n$if($and($eq(%lyrics%,),$ne(%_oldlyrics%,)),\n $set(lyrics,%_oldlyrics%)\n)\x94t\x94.)", @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x36\x80\x5\x95+\0\0\0\0\0\0\0(K\x5\x8c\rDelete Lyrics\x94\x89\x8c\x11$delete(%lyrics%)\x94t\x94.)
|
||||
load_image_behavior=replace
|
||||
local_cover_regex=^cover\\.(?:jpe?g|png)$
|
||||
max_genres=5
|
||||
metadatabox_top_tags=title, artist, album, tracknumber, ~length, date, lyrics
|
||||
min_genre_usage=90
|
||||
move_additional_files=true
|
||||
move_additional_files_pattern=*.jpg *.png *.JPG *.PNG *Zubeh\xf6r *Cover *zubeh\xf6r *cover *scans *covers *Artwork *Covers *scans *Scans
|
||||
move_files=true
|
||||
move_files_to=/srv/cifs/unRAID/Media/Musik/[0] Navidrome
|
||||
network_transfer_timeout_seconds=30
|
||||
never_replace_lrc=true
|
||||
never_replace_lyrics=true
|
||||
only_my_genres=false
|
||||
preferred_release_countries=XW, DE, XW, DE, XW, DE, XW, DE
|
||||
preferred_release_formats=Digital Media, CD, Digital Media, CD, Digital Media, CD, Digital Media, CD
|
||||
preserve_images=true
|
||||
preserve_timestamps=false
|
||||
preserved_tags=@Variant(\0\0\0\t\0\0\0\x1\0\0\0\n\0\0\0\f\0l\0y\0r\0i\0\x63\0s)
|
||||
proxy_password=
|
||||
proxy_server_host=
|
||||
proxy_server_port=80
|
||||
proxy_type=http
|
||||
proxy_username=
|
||||
query_limit=50
|
||||
quit_confirmation=true
|
||||
rating_user_email=users@musicbrainz.org
|
||||
recursively_add_files=true
|
||||
release_ars=true
|
||||
release_type_scores=@Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1f\x80\x5\x95\x14\0\0\0\0\0\0\0\x8c\x5\x41lbum\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0 \x80\x5\x95\x15\0\0\0\0\0\0\0\x8c\x6Single\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1c\x80\x5\x95\x11\0\0\0\0\0\0\0\x8c\x2\x45P\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1f\x80\x5\x95\x14\0\0\0\0\0\0\0\x8c\x5Other\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\tBroadcast\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0 \x80\x5\x95\x15\0\0\0\0\0\0\0\x8c\x6\x44J-mix\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1e\x80\x5\x95\x13\0\0\0\0\0\0\0\x8c\x4\x44\x65mo\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0)\x80\x5\x95\x1e\0\0\0\0\0\0\0\x8c\xf\x46ield recording\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\tAudiobook\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0%\x80\x5\x95\x1a\0\0\0\0\0\0\0\x8c\vAudio drama\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0#\x80\x5\x95\x18\0\0\0\0\0\0\0\x8c\tInterview\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0%\x80\x5\x95\x1a\0\0\0\0\0\0\0\x8c\vCompilation\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1e\x80\x5\x95\x13\0\0\0\0\0\0\0\x8c\x4Live\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0(\x80\x5\x95\x1d\0\0\0\0\0\0\0\x8c\xeMixtape/Street\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0\x1f\x80\x5\x95\x14\0\0\0\0\0\0\0\x8c\x5Remix\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0$\x80\x5\x95\x19\0\0\0\0\0\0\0\x8c\nSoundtrack\x94G?\xe0\0\0\0\0\0\0\x86\x94.), @Variant(\0\0\0\x7f\0\0\0\xePyQt_PyObject\0\0\0\0$\x80\x5\x95\x19\0\0\0\0\0\0\0\x8c\nSpokenword\x94G?\xe0\0\0\0\0\0\0\x86\x94.)
|
||||
remove_ape_from_aac=false
|
||||
remove_ape_from_ac3=false
|
||||
remove_ape_from_mp3=false
|
||||
remove_id3_from_flac=false
|
||||
remove_wave_riff_info=false
|
||||
rename_files=true
|
||||
replace_dir_separator=-
|
||||
replace_spaces_with_underscores=false
|
||||
save_acoustid_fingerprints=true
|
||||
save_images_overwrite=true
|
||||
save_images_to_files=true
|
||||
save_images_to_tags=true
|
||||
save_only_one_front_image=true
|
||||
script_exceptions=@Invalid()
|
||||
selected_file_naming_script_id=cc4b3c8b-f8c7-447e-9fcf-f7be7350baa1
|
||||
server_host=musicbrainz.org
|
||||
server_port=443
|
||||
show_menu_icons=true
|
||||
show_new_user_dialog=false
|
||||
standardize_artists=true
|
||||
standardize_instruments=true
|
||||
starting_directory=false
|
||||
starting_directory_path=/home/thorsten
|
||||
submit_ratings=true
|
||||
toolbar_layout=add_directory_action, add_files_action, separator, cluster_action, separator, autotag_action, analyze_action, browser_lookup_action, separator, save_action, view_info_action, remove_action, separator, cd_lookup_action, separator, submit_acoustid_action
|
||||
toolbar_multiselect=false
|
||||
toolbar_show_labels=true
|
||||
track_ars=false
|
||||
track_matching_threshold=0.4
|
||||
translate_artist_names=false
|
||||
translate_artist_names_script_exception=false
|
||||
ui_language=
|
||||
ui_theme=default
|
||||
update_check_days=7
|
||||
update_level=0
|
||||
use_adv_search_syntax=false
|
||||
use_genres=true
|
||||
use_proxy=false
|
||||
use_server_for_submission=false
|
||||
va_name=Various Artists
|
||||
wave_riff_info_encoding=windows-1252
|
||||
win_compat_replacements=@Variant(\0\0\0\b\0\0\0\a\0\0\0\x2\0|\0\0\0\n\0\0\0\x2\0_\0\0\0\x2\0?\0\0\0\n\0\0\0\x2\0_\0\0\0\x2\0>\0\0\0\n\0\0\0\x2\0_\0\0\0\x2\0<\0\0\0\n\0\0\0\x2\0_\0\0\0\x2\0:\0\0\0\n\0\0\0\x2\0-\0\0\0\x2\0*\0\0\0\n\0\0\0\x2\0_\0\0\0\x2\0\"\0\0\0\n\0\0\0\x2\0_)
|
||||
windows_compatibility=true
|
||||
windows_long_paths=false
|
||||
write_id3v1=true
|
||||
write_id3v23=false
|
||||
write_wave_riff_info=true
|
||||
@@ -0,0 +1 @@
|
||||
~/.config/MusicBrainz/Picard.ini
|
||||
@@ -0,0 +1,33 @@
|
||||
## Description remove
|
||||
|
||||
|
||||
```
|
||||
$if(
|
||||
$or(
|
||||
$eq($trim(%description%),"Downloaded from music.binimum.org/tidal.squid.wtf"),
|
||||
$eq($trim(%description%),"https://github.com/afkarxyz/SpotiFLAC"),
|
||||
$eq($trim(%description%)," ")
|
||||
),
|
||||
$delete(description)
|
||||
)
|
||||
|
||||
|
||||
$if(
|
||||
$or(
|
||||
$eq($trim(%comment%),"Rapidshare FUCK OFF !!!!!"),
|
||||
$eq($trim(%comment%)," "),
|
||||
$eq($trim(%comment%)," ")
|
||||
),
|
||||
$delete(comment)
|
||||
)
|
||||
|
||||
|
||||
$if(
|
||||
$or(
|
||||
$eq($trim(%comment:ID3v1%),"Rapidshare FUCK OFF !!!!!"),
|
||||
$eq($trim(%comment:ID3v1%)," "),
|
||||
$eq($trim(%comment:ID3v1%)," ")
|
||||
),
|
||||
$delete(comment:ID3v1)
|
||||
)
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
## Navidrome
|
||||
|
||||
### Picard specific tips
|
||||
|
||||
https://www.navidrome.org/docs/usage/library/tagging/#picard-specific-tips
|
||||
|
||||
```
|
||||
# Multiple artists
|
||||
$setmulti(albumartists,%_albumartists%)
|
||||
$setmulti(albumartistssort,%_albumartists_sort%)
|
||||
$setmulti(artistssort,%_artists_sort%)
|
||||
```
|
||||
|
||||
```
|
||||
# Album Version
|
||||
$set(musicbrainz_albumcomment,%_releasecomment%)
|
||||
$if(%_recordingcomment%, $set(subtitle,%_recordingcomment%))
|
||||
```
|
||||
|
||||
```
|
||||
# Release and Original dates
|
||||
$set(releasedate,%date%)
|
||||
$set(date,%_recording_firstreleasedate%)
|
||||
$set(originaldate,%originaldate%)
|
||||
$delete(originalyear)
|
||||
```
|
||||
@@ -0,0 +1,206 @@
|
||||
# Music Sync Script (Unraid)
|
||||
|
||||
## Zweck
|
||||
Synchronisiert neue Musikdateien aus `incoming` in zwei Zielordner.
|
||||
Dateien werden nur verarbeitet, wenn sie vollständig geschrieben sind.
|
||||
|
||||
---
|
||||
|
||||
## Ablauf
|
||||
incoming → ready → DEST1 + DEST2 → delete
|
||||
|
||||
---
|
||||
|
||||
## Warum incoming → ready?
|
||||
|
||||
Das Script verwendet zwei Verzeichnisse, um einen sauberen und sicheren Verarbeitungszustand zu gewährleisten.
|
||||
|
||||
### Problem ohne Trennung
|
||||
|
||||
Wenn direkt aus `incoming` synchronisiert wird:
|
||||
|
||||
- Dateien können noch geschrieben werden (z. B. durch Picard)
|
||||
- `rsync` kopiert ggf. unvollständige Dateien
|
||||
- bei mehreren Durchläufen entstehen Inkonsistenzen zwischen den Zielen
|
||||
|
||||
---
|
||||
|
||||
### Lösung: Staging mit `ready`
|
||||
|
||||
Der Ablauf ist bewusst zweistufig:
|
||||
|
||||
incoming (unsicher) → ready (stabil) → Sync
|
||||
|
||||
#### incoming
|
||||
- hier schreibt Picard
|
||||
- Dateien können noch im Zugriff sein
|
||||
- kein Sync von hier
|
||||
|
||||
#### ready
|
||||
- Dateien werden erst verschoben, wenn sie alt genug sind
|
||||
- `mv` innerhalb desselben Filesystems ist atomar
|
||||
- Datei ist danach garantiert vollständig
|
||||
|
||||
👉 Ergebnis:
|
||||
Das Script arbeitet nur mit fertigen, stabilen Dateien.
|
||||
|
||||
---
|
||||
|
||||
## Wichtiger Hinweis zu "atomar"
|
||||
|
||||
Ein `mv` ist nur dann atomar, wenn sich Quelle und Ziel im selben Filesystem befinden.
|
||||
|
||||
In diesem Setup:
|
||||
|
||||
```
|
||||
INCOMING="/mnt/user/Cache/Picard/incoming"
|
||||
READY="/mnt/user/Cache/Picard/ready"
|
||||
```
|
||||
|
||||
liegen beide Pfade im selben Share → gleicher Storage → atomarer Move.
|
||||
|
||||
Wichtig:
|
||||
- Es ist egal, wo Picard läuft (Docker, anderer Host, etc.)
|
||||
- Entscheidend ist nur, wohin geschrieben wird
|
||||
|
||||
Nicht atomar wäre z. B.:
|
||||
|
||||
```
|
||||
/mnt/user/... → /mnt/diskX/...
|
||||
```
|
||||
|
||||
Dann würde `mv` intern kopieren + löschen.
|
||||
|
||||
---
|
||||
|
||||
## Lockfile
|
||||
|
||||
```
|
||||
/mnt/user/Cache/Picard/sync.lock
|
||||
```
|
||||
|
||||
### Zweck
|
||||
- verhindert parallele Ausführung
|
||||
- schützt vor doppelten Operationen
|
||||
|
||||
### Problemfall
|
||||
Wenn das Script abbricht, bleibt das Lockfile bestehen und blockiert weitere Runs.
|
||||
|
||||
### Lösung
|
||||
|
||||
```
|
||||
rm /mnt/user/Cache/Picard/sync.lock
|
||||
```
|
||||
|
||||
Nur ausführen, wenn sicher kein Script mehr läuft.
|
||||
|
||||
---
|
||||
|
||||
## CHOWN (Dateirechte / CIFS Problem)
|
||||
|
||||
Nach dem Kopieren werden Dateien und Ordner explizit gesetzt auf:
|
||||
|
||||
```
|
||||
CHOWN_USER="thorsten"
|
||||
CHOWN_GROUP="users"
|
||||
```
|
||||
|
||||
### Warum ist das nötig?
|
||||
|
||||
Unraid + CIFS/Samba verhält sich so:
|
||||
|
||||
- Dateien werden oft als `root` oder `nobody` angelegt
|
||||
- Netzwerkzugriff über CIFS hat dann **keine Löschrechte**
|
||||
- selbst wenn Lesen funktioniert
|
||||
|
||||
👉 Typisches Symptom:
|
||||
Datei kann geöffnet, aber nicht gelöscht werden
|
||||
|
||||
---
|
||||
|
||||
### Lösung im Script
|
||||
|
||||
Nach erfolgreichem Sync:
|
||||
|
||||
- wird jede Datei gechowned
|
||||
- zugehörige Ordner werden ebenfalls angepasst
|
||||
- Ordner aber nur **einmal pro Lauf** (Performance)
|
||||
|
||||
👉 Ergebnis:
|
||||
- Dateien gehören deinem User
|
||||
- CIFS Zugriff funktioniert korrekt
|
||||
- kein manuelles `chown -R` mehr nötig
|
||||
|
||||
---
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
- verarbeitet nur Dateien älter als 1 Minute
|
||||
- atomarer Move (incoming → ready)
|
||||
- Sync zu zwei Zielen per rsync
|
||||
- Löschen nur bei Erfolg beider Syncs
|
||||
- fehlgeschlagene Dateien bleiben erhalten
|
||||
- Lockfile verhindert parallele Ausführung
|
||||
- Dry-Run Modus vorhanden
|
||||
- Logging + Konsolenausgabe
|
||||
- Pfade tolerant gegenüber trailing `/`
|
||||
- Zielpfade müssen existieren (sonst Abbruch)
|
||||
- Ownership wird gesetzt (`chown`)
|
||||
- Ordner werden nur einmal pro Lauf angepasst
|
||||
|
||||
---
|
||||
|
||||
## Konfiguration
|
||||
|
||||
```
|
||||
INCOMING="/mnt/user/Cache/Picard/incoming"
|
||||
READY="/mnt/user/Cache/Picard/ready"
|
||||
|
||||
DEST1="/mnt/user/Cache/Syncthing/..."
|
||||
DEST2="/mnt/user/Media/Musik/..."
|
||||
|
||||
LOG="/mnt/user/Cache/Picard/sync.log"
|
||||
LOCKFILE="/mnt/user/Cache/Picard/sync.lock"
|
||||
|
||||
DRY_RUN=false
|
||||
|
||||
CHOWN_USER="thorsten"
|
||||
CHOWN_GROUP="users"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dry Run
|
||||
|
||||
```
|
||||
DRY_RUN=true
|
||||
```
|
||||
|
||||
- keine Änderungen am Dateisystem
|
||||
- rsync läuft mit --dry-run
|
||||
- Aktionen werden geloggt
|
||||
|
||||
---
|
||||
|
||||
## Cron Beispiel
|
||||
|
||||
```
|
||||
0 */6 * * *
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Script beendet sich sofort, wenn keine Dateien vorhanden sind
|
||||
- `ready/` wird nur bei Bedarf erstellt und kann wieder verschwinden
|
||||
- Rechteproblem bei CIFS wird durch chown gelöst
|
||||
|
||||
---
|
||||
|
||||
## Debug
|
||||
|
||||
```
|
||||
cat /mnt/user/Cache/Picard/sync.log
|
||||
ls /mnt/user/Cache/Picard
|
||||
```
|
||||
@@ -0,0 +1,221 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ----------------------------------------
|
||||
# CONFIG
|
||||
# ----------------------------------------
|
||||
INCOMING="/mnt/user/Cache/Picard/incoming"
|
||||
READY="/mnt/user/Cache/Picard/ready"
|
||||
|
||||
DEST1="/mnt/user/Cache/Syncthing/Julian/Musik/Thorsten -> Julian"
|
||||
DEST2="/mnt/user/Media/Musik/[0] Navidrome"
|
||||
|
||||
LOG="/mnt/user/Cache/Picard/sync.log"
|
||||
LOCKFILE="/mnt/user/Cache/Picard/sync.lock"
|
||||
|
||||
LOG_LINES=5000
|
||||
|
||||
DRY_RUN=false
|
||||
|
||||
CHOWN_USER="thorsten"
|
||||
CHOWN_GROUP="users"
|
||||
|
||||
# ----------------------------------------
|
||||
# NORMALIZE PATHS
|
||||
# ----------------------------------------
|
||||
normalize_path() {
|
||||
local p="$1"
|
||||
[[ "$p" != "/" ]] && p="${p%/}"
|
||||
echo "$p"
|
||||
}
|
||||
|
||||
INCOMING="$(normalize_path "$INCOMING")"
|
||||
READY="$(normalize_path "$READY")"
|
||||
DEST1="$(normalize_path "$DEST1")"
|
||||
DEST2="$(normalize_path "$DEST2")"
|
||||
|
||||
# ----------------------------------------
|
||||
# TRACKING
|
||||
# ----------------------------------------
|
||||
declare -A CHANGED_DIRS_DEST1
|
||||
declare -A CHANGED_DIRS_DEST2
|
||||
|
||||
# ----------------------------------------
|
||||
# FUNCTIONS
|
||||
# ----------------------------------------
|
||||
log() {
|
||||
MSG="$(date '+%Y-%m-%d %H:%M:%S') | $1"
|
||||
echo "$MSG"
|
||||
echo "$MSG" >> "$LOG"
|
||||
}
|
||||
|
||||
rotate_log() {
|
||||
if [ -f "$LOG" ]; then
|
||||
tail -n "$LOG_LINES" "$LOG" > "${LOG}.tmp" && mv "${LOG}.tmp" "$LOG"
|
||||
fi
|
||||
}
|
||||
|
||||
run_cmd() {
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
log "[DRY-RUN] $*"
|
||||
else
|
||||
"$@"
|
||||
fi
|
||||
}
|
||||
|
||||
rsync_cmd() {
|
||||
if [ "$DRY_RUN" = true ]; then
|
||||
rsync -a --dry-run "$@"
|
||||
return 0
|
||||
else
|
||||
rsync -a "$@"
|
||||
return $?
|
||||
fi
|
||||
}
|
||||
|
||||
# ----------------------------------------
|
||||
# FIX OWNERSHIP TREE
|
||||
# ----------------------------------------
|
||||
fix_tree() {
|
||||
local DIR="$1"
|
||||
local ROOT="$2"
|
||||
|
||||
while [[ "$DIR" == "$ROOT"* ]]; do
|
||||
run_cmd chown "$CHOWN_USER:$CHOWN_GROUP" "$DIR"
|
||||
[[ "$DIR" == "$ROOT" ]] && break
|
||||
DIR="$(dirname "$DIR")"
|
||||
done
|
||||
}
|
||||
|
||||
# ----------------------------------------
|
||||
# VERIFY DESTINATIONS
|
||||
# ----------------------------------------
|
||||
for DEST in "$DEST1" "$DEST2"; do
|
||||
if [ ! -d "$DEST" ]; then
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') | ERROR: Destination not found -> $DEST"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# ----------------------------------------
|
||||
# LOCKFILE
|
||||
# ----------------------------------------
|
||||
if [ -f "$LOCKFILE" ]; then
|
||||
echo "Lockfile exists -> $LOCKFILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
trap "rm -f '$LOCKFILE'" EXIT
|
||||
touch "$LOCKFILE"
|
||||
|
||||
# ----------------------------------------
|
||||
# QUICK EXIT
|
||||
# ----------------------------------------
|
||||
if ! find "$INCOMING" -type f -mmin +1 -print -quit | grep -q .; then
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') | No files to process -> exit"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# ----------------------------------------
|
||||
# START
|
||||
# ----------------------------------------
|
||||
rotate_log
|
||||
log "========================================"
|
||||
log "START RUN (DRY_RUN=$DRY_RUN)"
|
||||
log "========================================"
|
||||
|
||||
CHANGED=false
|
||||
|
||||
# ----------------------------------------
|
||||
# 1. INCOMING → READY
|
||||
# ----------------------------------------
|
||||
log "---- MOVE: INCOMING → READY ----"
|
||||
|
||||
while read -r FILE; do
|
||||
[ -f "$FILE" ] || continue
|
||||
|
||||
REL="${FILE#"$INCOMING"/}"
|
||||
TARGET="$READY/$REL"
|
||||
|
||||
mkdir -p "$READY/$(dirname "$REL")"
|
||||
|
||||
log "MOVE -> $REL"
|
||||
run_cmd mv "$FILE" "$TARGET"
|
||||
|
||||
done < <(find "$INCOMING" -type f -mmin +1)
|
||||
|
||||
# ----------------------------------------
|
||||
# 2. READY → DESTS
|
||||
# ----------------------------------------
|
||||
log "---- SYNC: READY → DESTINATIONS ----"
|
||||
log "DEST1: $DEST1"
|
||||
log "DEST2: $DEST2"
|
||||
|
||||
while read -r FILE; do
|
||||
|
||||
[ -f "$FILE" ] || continue
|
||||
|
||||
REL="${FILE#"$READY"/}"
|
||||
|
||||
DEST1_FILE="$DEST1/$REL"
|
||||
DEST2_FILE="$DEST2/$REL"
|
||||
|
||||
DIR1="$(dirname "$DEST1_FILE")"
|
||||
DIR2="$(dirname "$DEST2_FILE")"
|
||||
|
||||
mkdir -p "$DIR1"
|
||||
mkdir -p "$DIR2"
|
||||
|
||||
log "SYNC -> $REL"
|
||||
|
||||
rsync_cmd "$FILE" "$DEST1_FILE"
|
||||
STATUS1=$?
|
||||
|
||||
rsync_cmd "$FILE" "$DEST2_FILE"
|
||||
STATUS2=$?
|
||||
|
||||
if [[ $STATUS1 -eq 0 && $STATUS2 -eq 0 ]]; then
|
||||
CHANGED=true
|
||||
|
||||
CHANGED_DIRS_DEST1["$DIR1"]=1
|
||||
CHANGED_DIRS_DEST2["$DIR2"]=1
|
||||
|
||||
log "OK -> delete $REL"
|
||||
run_cmd rm "$FILE"
|
||||
else
|
||||
log "ERROR -> $REL (dest1=$STATUS1 dest2=$STATUS2)"
|
||||
fi
|
||||
|
||||
done < <(find "$READY" -type f 2>/dev/null)
|
||||
|
||||
# ----------------------------------------
|
||||
# 3. FIX OWNERSHIP (SMART TREE)
|
||||
# ----------------------------------------
|
||||
log "CHANGED=$CHANGED"
|
||||
|
||||
if [ "$CHANGED" = true ]; then
|
||||
log "FIX OWNERSHIP (tree mode)"
|
||||
|
||||
for DIR in "${!CHANGED_DIRS_DEST1[@]}"; do
|
||||
log "FIX DEST1 -> $DIR"
|
||||
fix_tree "$DIR" "$DEST1"
|
||||
done
|
||||
|
||||
for DIR in "${!CHANGED_DIRS_DEST2[@]}"; do
|
||||
log "FIX DEST2 -> $DIR"
|
||||
fix_tree "$DIR" "$DEST2"
|
||||
done
|
||||
fi
|
||||
|
||||
# ----------------------------------------
|
||||
# CLEANUP
|
||||
# ----------------------------------------
|
||||
if [ "$DRY_RUN" != true ]; then
|
||||
find "$INCOMING" -mindepth 1 -type d -empty -delete
|
||||
find "$READY" -mindepth 1 -type d -empty -delete 2>/dev/null
|
||||
else
|
||||
log "[DRY-RUN] Skipping cleanup"
|
||||
fi
|
||||
|
||||
log "========================================"
|
||||
log "END RUN"
|
||||
log "========================================"
|
||||
Reference in new issue
Block a user