# VGMDB Doujin Subfolders — Organiser by Publisher

> **Status:** ⚠️ Quarantined
> **Category:** File Organization
> **Language:** Python 3
> **Script file:** `doujin-subfolder-sort-run-quarantined.py`

> ⚠️ **QUARANTINED** — This script makes irreversible file system changes. Run only in a test directory first. Do not run on your live collection without a backup. Use Dry-run mode to preview changes before committing.

## Purpose

Organises doujin album folders into publisher-named subfolders by reading the `VGMDB_PUBLISHER` FLAC tag from each album. For example, an album tagged with `VGMDB_PUBLISHER=ZYTOKINE` would be moved from the library root into a `ZYTOKINE/` subfolder. Includes dry-run and revert modes.

## Requirements

### Dependencies

```bash
pip install mutagen colorama
```

`colorama` is optional — coloured console output is disabled gracefully if it is not installed. `mutagen` is required.

## Input

| Item | Description | Example |
|------|-------------|---------|
| Root folder path | Entered interactively at launch; must contain album folders at the top level | `X:\Doujin` |
| `VGMDB_PUBLISHER` FLAC tag | Tag present in `.flac` files inside each album folder | `ZYTOKINE` |
| `move_log.json` | Required for Revert mode; created automatically by Move mode | Auto-generated |

## Output

| Item | Description |
|------|-------------|
| Publisher subfolders | Created inside the root folder; named after the publisher |
| Moved album folders | Each album folder moved into its publisher subfolder |
| `move_log.json` | JSON log of all moves (source → destination); used by Revert |
| `skipped_log.json` | JSON log of albums that were skipped (no tag, or destination already existed) |
| `test/` directory (Dry-run only) | Preview structure with placeholder `.txt` files; no albums are moved |

## Usage

```bash
python doujin-subfolder-sort-run-quarantined.py
```

On launch, the script prompts for the root folder path and then the operating mode:

```
Enter the root folder path (e.g. X:\Music): X:\Doujin

Select a mode:
  1 - Move albums into publisher subfolders
  2 - Dry run (preview structure under a 'test' subfolder)
  3 - Revert previous moves
```

## Examples

```bash
# Example 1 — Dry run first (ALWAYS do this before a live move)
python doujin-subfolder-sort-run-quarantined.py
# Root path: X:\Doujin
# Mode: 2
# Inspect the test/ folder to verify the proposed structure

# Example 2 — Live move (only after reviewing the dry run)
python doujin-subfolder-sort-run-quarantined.py
# Root path: X:\Doujin
# Mode: 1

# Example 3 — Revert a previous live move
python doujin-subfolder-sort-run-quarantined.py
# Root path: X:\Doujin
# Mode: 3
```

### Mode details

| Mode | What it does |
|------|-------------|
| **Move (1)** | Physically moves album folders into publisher subfolders. Appends to `move_log.json`. |
| **Dry-run (2)** | Creates a `test/` subfolder with the proposed publisher structure and placeholder `.txt` files. No albums are moved. |
| **Revert (3)** | Reads `move_log.json` and moves all albums back to their original locations. Removes empty publisher folders after reverting. |

## Notes

- **DESTRUCTIVE:** Move mode uses `shutil.move()` to physically relocate folders. This is not easily undoable outside of Revert mode. Always run a Dry-run first and keep a backup.
- The `VGMDB_PUBLISHER` tag is read from all `.flac` files in the album folder, including disc subfolders. If multiple different publisher values are found within the same album, the script warns about the inconsistency and uses the alphabetically first value.
- If the publisher name contains characters that are illegal in Windows filenames (`\ / : * ? " < > |`), those characters are stripped before creating the subfolder. A warning is printed when this happens.
- Albums whose FLAC files have no `VGMDB_PUBLISHER` tag are skipped and recorded in `skipped_log.json`.
- If the destination path already exists (another album with the same publisher was already moved there), the move is skipped.
- Revert reads `move_log.json` from the **current working directory**, not the root folder you enter at the prompt.
- The `move_log.json` is overwritten on each Revert completion (failed entries remain in the log).

## Related Scripts

- [vgmdb-url-rename-combo-python](vgmdb-url-rename-combo-python.md) — renames folders and creates VGMdb `.url` shortcuts (non-destructive)
