initial commit
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
# Plex Library — Folder-Based Location Management via SQLite
|
||||
|
||||
When Plex groups compilation/VA folders together as "Various Artists" or cross-contaminates album metadata, the fix is to add each subfolder as an **individual library location** instead of a single parent folder.
|
||||
|
||||
## The Problem
|
||||
|
||||
Plex treats a library's root folder as one namespace. If you have:
|
||||
```
|
||||
/Music/English/
|
||||
├── Best of HipHop (2000-2026)/ ← compilation
|
||||
├── Drake/ ← proper album
|
||||
├── Green Day/ ← proper album
|
||||
└── Today's Top Hits/ ← compilation
|
||||
```
|
||||
|
||||
With `respectTags=false`, Plex uses folder names as album titles — compilation folders are fine but tagged albums get wrong metadata.
|
||||
|
||||
With `respectTags=true`, Plex uses embedded tags — tagged albums are correct, but compilation folders (which often have tracks with different "Album" tags from different sources) get grouped as "Various Artists" and cross-contaminated.
|
||||
|
||||
## The Fix: Individual Locations
|
||||
|
||||
Add each subfolder as a separate library location. This makes Plex treat each folder as its own namespace — no cross-contamination.
|
||||
|
||||
### Step 1: Check Current Locations
|
||||
|
||||
```bash
|
||||
curl -s "http://192.168.50.98:32400/library/sections?X-Plex-Token=<TOKEN>" | grep -o '<Location[^>]*>'
|
||||
```
|
||||
|
||||
Or via Python:
|
||||
```python
|
||||
import urllib.request, xml.etree.ElementTree as ET
|
||||
|
||||
tree = ET.parse('/path/to/Preferences.xml')
|
||||
token = tree.getroot().get('PlexOnlineToken')
|
||||
|
||||
url = f"http://localhost:32400/library/sections?X-Plex-Token={token}"
|
||||
with urllib.request.urlopen(url) as resp:
|
||||
print(resp.read().decode())
|
||||
```
|
||||
|
||||
**Pitfall:** Bash mangles tokens with special characters. Use Python for all Plex API calls.
|
||||
|
||||
### Step 2: List Subfolders
|
||||
|
||||
```bash
|
||||
ls -1 /mnt/seagate8tb/Music/English/
|
||||
```
|
||||
|
||||
### Step 3: Add Each Subfolder as Location
|
||||
|
||||
Plex API for adding music library locations is unreliable (404s, auth issues). Use direct SQLite:
|
||||
|
||||
```python
|
||||
import sqlite3
|
||||
|
||||
db = "/home/ray/docker/plex/config/Library/Application Support/Plex Media Server/Plug-in Support/Databases/com.plexapp.plugins.library.db"
|
||||
conn = sqlite3.connect(db)
|
||||
|
||||
base = "/mnt/seagate8tb/Music/English"
|
||||
folders = ["Best of HipHop (2000-2026)", "Drake", "Green Day", ...]
|
||||
|
||||
for folder in folders:
|
||||
path = f"{base}/{folder}"
|
||||
conn.execute(
|
||||
"INSERT INTO section_locations (library_section_id, root_path) VALUES (?, ?)",
|
||||
(1, path) # 1 = library section ID
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
```
|
||||
|
||||
### Step 4: Remove Parent Location
|
||||
|
||||
```python
|
||||
conn.execute("DELETE FROM section_locations WHERE id=<parent_location_id>")
|
||||
conn.commit()
|
||||
```
|
||||
|
||||
### Step 5: Restart and Scan
|
||||
|
||||
```bash
|
||||
docker compose restart plex
|
||||
```
|
||||
|
||||
Then trigger a scan (Python, not bash):
|
||||
```python
|
||||
url = f"http://localhost:32400/library/sections/1/refresh?X-Plex-Token={token}"
|
||||
urllib.request.urlopen(url)
|
||||
```
|
||||
|
||||
### Step 6: Verify
|
||||
|
||||
```bash
|
||||
# Check if scan is running
|
||||
grep -i "scan\|refresh" '/path/to/Plex Media Server.log' | tail -5
|
||||
|
||||
# Check scanner processes
|
||||
ps aux | grep "Plex Media Scanner" | grep -v grep
|
||||
```
|
||||
|
||||
## DB Schema Reference
|
||||
|
||||
```sql
|
||||
-- section_locations table
|
||||
CREATE TABLE section_locations (
|
||||
id INTEGER PRIMARY KEY,
|
||||
library_section_id INTEGER,
|
||||
root_path VARCHAR(255),
|
||||
available BOOLEAN DEFAULT 't',
|
||||
scanned_at INTEGER,
|
||||
created_at INTEGER,
|
||||
updated_at INTEGER
|
||||
);
|
||||
```
|
||||
|
||||
## Tags vs Folder Names Tradeoff
|
||||
|
||||
- `respectTags=true` — proper albums show correctly; compilations need the individual-location fix
|
||||
- `respectTags=false` — compilations show correctly as folder names; tagged albums get wrong metadata
|
||||
|
||||
With the individual-location fix, `respectTags=true` works for both cases.
|
||||
Reference in New Issue
Block a user