Automate your
Plex library.
Rename, organize, and clean TV shows and movies after every download. Embeds subtitles, tags audio languages, and removes the torrent โ automatically.
.!qB downloads, and the organizer index are preserved. Everything
else (subtitles, NFOs, artwork, sample files) is deleted after processing.
Back up important data before running.
What it does
Plex Organizer is a Python utility triggered after a torrent finishes downloading. Given a download directory, it runs a sequential pipeline:
Embeds any external subtitle files into the video container
Fetches missing subtitles from online providers
Syncs subtitle timing to the audio track
Tags audio streams with the correct ISO 639-2 language code
Cleans up unwanted files, folders, and samples
Renames & moves files into a clean Plex layout
Indexes processed files so future runs skip already-organized content
Removes the completed torrent from qBittorrent
Quick start
Install as root (required for file operations):
sudo pipx install git+https://github.com/Toomas633/Plex-Organizer.git
sudo pipx ensurepath
Run manually:
sudo plex-organizer /mnt/media
Automated via qBittorrent "Run external program on torrent finished":
sudo plex-organizer "%D" "%I"
See the Installation guide for full details.
Key features
Smart renaming
TV โ Show S01E01 1080p.mkv
Movie โ
Title (2024) 1080p.mkv
Subtitle pipeline
Embed โ Fetch โ Sync, fully automated from external files to online providers.
Audio tagging
Detects language via faster-whisper and writes ISO 639-2 tags
into the container.
Quality detection
Parses filename tag or falls back to probing the video stream height via
ffprobe.
Plex-safe
Skips and never modifies Plex-managed content inside
Plex Versions/.
Indexing
Per-library index skips already-processed files for fast incremental runs.
qBittorrent
Removes the torrent via Web API after successful processing.
Management menu
--manage flag for logs, config migration, index generation,
and more.
Directory transformation
Before โ raw torrent download
/mnt/media/
โโโ movies/
โ โโโ Venom.2018.BluRay.x264-YTS.mp4
โ โโโ 1917 (2019) [1080p] [BluRay]/
โ โ โโโ Subs/
โ โ โโโ English.srt
โ โ โโโ Spanish.srt
โ โโโ random_file.txt
โโโ tv/
โโโ Black Bird/
โ โโโ S01E01.mp4
โ โโโ unwanted_file.txt
โโโ Loki/
โโโ S01E01.mp4
After โ clean Plex layout
/mnt/media/
โโโ movies/
โ โโโ 1917 (2019)/
โ โ โโโ 1917 (2019) 1080p.mp4
โ โโโ Venom (2018)/
โ โโโ Venom (2018).mp4
โโโ tv/
โโโ Black Bird/
โ โโโ Season 1/
โ โโโ Black Bird S01E01.mp4
โโโ Loki/
โโโ Season 1/
โโโ Loki S01E01.mp4
Requirements
- Python 3.10+
-
Root privileges โ the organizer must be run as
root(sudo)
ffmpeg and ffprobe are bundled automatically via
static-ffmpeg
โ no separate install needed.
sudo plex-organizer --manage to access logs,
migrate config, generate indexes, and more.
Installation
Requirements
- Python 3.10+
- pipx โ recommended installer (isolates dependencies)
-
Root privileges โ the organizer must run as
rootto move and rename media files
ffmpeg and ffprobe are bundled automatically via
static-ffmpeg
โ no separate install needed.
Install
Install directly from GitHub. Because the organizer requires root, install it
into root's environment so the plex-organizer command is
available on root's PATH:
sudo apt install pipx # if pipx is not already installed
sudo pipx install git+https://github.com/Toomas633/Plex-Organizer.git
sudo pipx ensurepath
sudo pipx ensurepath adds pipx's binary directory to root's
PATH. You may need to restart the shell session or run
source ~/.bashrc for the change to take effect.
Verify the install:
sudo plex-organizer --help
Update
sudo pipx upgrade plex-organizer
Data directory
By default, config.ini, log files, and the lock file are stored
at:
/root/.config/plex-organizer/
You can override this with the PLEX_ORGANIZER_DIR environment
variable, or by running the organizer from a directory that already contains a
config.ini.
First run
On the first run, config.ini is automatically created with all
default values. You can review and edit it before running again:
sudo plex-organizer /mnt/media # creates config.ini and exits cleanly
cat /root/.config/plex-organizer/config.ini
See the Configuration page for all available options.
Interactive management menu
After installation, the management menu is available for maintenance tasks:
sudo plex-organizer --manage
| Option | Description |
|---|---|
| 1 | View data directory path |
| 2 | View log files |
| 3 | Migrate config from an older version |
| 4 | Generate/rebuild library indexes |
| 5 | Kill a running organizer process |
| 6 | Custom pipeline run |
| 7 | Migrate TV indexes (v5 โ v6 format) |
| 8 | Edit configuration |
Migrating from v5.0
Version 6.0 changed the install method. The old git clone +
run.sh approach is no longer supported.
| v5.0 (old) | v6.0+ (new) | |
|---|---|---|
| Install | git clone + run.sh |
pipx install โฆ |
| Update | ./update.sh |
pipx upgrade plex-organizer |
| Run | sudo bash run.sh <dir> |
sudo plex-organizer <dir> |
| Config | Repo directory | /root/.config/plex-organizer/ |
Migration steps
-
Install pipx (if not already installed):
sudo apt install pipx sudo pipx ensurepath -
Install Plex Organizer:
sudo pipx install git+https://github.com/Toomas633/Plex-Organizer.git -
Move your existing config:
mkdir -p /root/.config/plex-organizer cp /path/to/old/Plex-Organizer/config.ini /root/.config/plex-organizer/ -
Migrate TV indexes to the new per-library format:
sudo plex-organizer --manage # choose option 7 -
Update your qBittorrent automation command:
sudo plex-organizer "%D" "%I" -
Remove the old clone once everything is working:
rm -rf /path/to/old/Plex-Organizer
Configuration
All configuration is managed through config.ini, which is
auto-created on first run and automatically maintained on every startup โ
missing options are added and unknown options are removed.
Config file location
| Location | Description |
|---|---|
/root/.config/plex-organizer/config.ini |
Default (when running as root) |
$PLEX_ORGANIZER_DIR/config.ini |
Override via environment variable |
./config.ini |
Current directory, if a config.ini already exists there
|
[qBittorrent]
Controls torrent removal after processing. Torrent removal is best-effort โ failures are logged and processing continues.
| Option | Default | Description |
|---|---|---|
host |
http://localhost:8081 |
Base URL for the qBittorrent Web API |
username |
(empty) | Web API username |
password |
(empty) | Web API password |
[Settings]
Core organizer behaviour.
| Option | Default | Description |
|---|---|---|
delete_duplicates |
false |
When true, deletes the source file if the destination
already exists
|
include_quality |
true |
Appends quality tag (e.g. 1080p) to renamed files. Falls
back to probing video stream height via ffprobe when no
quality tag is found in the filename
|
capitalize |
true |
Title-cases show and movie names |
cpu_threads |
4 |
Maximum CPU threads used for processing steps |
Quality labels
When include_quality is enabled and no tag is found in the
filename, ffprobe measures the video height and maps it:
| Height | Label |
|---|---|
| โฅ 2160 | 2160p |
| โฅ 1440 | 1440p |
| โฅ 1080 | 1080p |
| โฅ 720 | 720p |
| < 720 | 480p |
[Logging]
| Option | Default | Description |
|---|---|---|
enable_logging |
true |
Writes errors to a log file |
log_file |
plex_organizer.log |
Log file name |
clear_log |
false |
Clears the log file at the start of each run |
timestamped_log_files |
false |
Saves timestamped logs into a logs/ subfolder instead of a
single file
|
level |
INFO |
Log level โ INFO or DEBUG |
[Audio]
Controls automatic audio stream language tagging using AI-based detection.
| Option | Default | Description |
|---|---|---|
enable_audio_tagging |
true |
Detects missing audio track languages and writes ISO 639-2 tags into the container |
whisper_model_size |
tiny |
faster-whisper model size. Larger models are more accurate
but slower (tiny, base, small,
medium, large)
|
How it works:
ffprobeenumerates audio streams in the video file.-
For streams with a missing or
und/unknownlanguage tag, a short WAV sample is extracted withffmpeg. -
faster-whisperinfers the spoken language from the sample. -
The ISO 639-2 tag (e.g.
eng,spa) is written back into the container via anffmpeg -c copyremux.
[Subtitles]
Controls the full subtitle pipeline: embedding external subs, fetching from online providers, and syncing timing.
| Option | Default | Description |
|---|---|---|
enable_subtitle_embedding |
true |
Embeds external .srt/.ass files found
alongside the video (including Subs/ subfolders) into the
container before cleanup
|
analyze_embedded_subtitles |
true |
Also analyzes already-embedded subtitle streams for missing/unknown language or SDH tags and writes detected metadata back |
fetch_subtitles |
eng |
Comma-separated ISO 639-2 language codes to fetch (e.g.
eng, est). Leave empty to disable
|
subtitle_providers |
opensubtitles, podnapisi, gestdown, tvsubtitles |
Comma-separated list of subtitle providers to use for fetching |
sync_subtitles |
true |
Synchronizes embedded subtitle timing to the audio track after all other subtitle operations |
Subtitle pipeline order
1. embed_subtitles โ embed external .srt/.ass files found on disk
2. fetch_subtitles โ download missing languages from online providers
3. sync_subtitles โ align subtitle timing to audio track
4. cleanup โ remove subtitle files/folders from disk
mov_text, WebVTT)
are synced. Bitmap formats (PGS, DVB, VobSub) are left unchanged by
ffsubsync.
Full example config.ini
[qBittorrent]
host = http://localhost:8081
username = admin
password = adminadmin
[Settings]
delete_duplicates = false
include_quality = true
capitalize = true
cpu_threads = 4
[Logging]
enable_logging = true
log_file = plex_organizer.log
clear_log = false
timestamped_log_files = false
level = INFO
[Audio]
enable_audio_tagging = true
whisper_model_size = tiny
[Subtitles]
enable_subtitle_embedding = true
analyze_embedded_subtitles = true
fetch_subtitles = eng
subtitle_providers = opensubtitles, podnapisi, gestdown, tvsubtitles
sync_subtitles = true
Usage
Syntax
sudo plex-organizer <start_directory> [torrent_hash]
| Argument | Required | Description |
|---|---|---|
<start_directory> |
Yes |
The directory to process โ either a folder containing
tv/ and/or movies/ subfolders, or a single
torrent save path
|
[torrent_hash] |
No | Torrent hash for automatic removal from qBittorrent after processing. Omit for manual runs or to skip removal |
sudo plex-organizer "%D" "%I"
Start directory modes
The organizer supports two modes, detected automatically from the path:
Main folder mode
The start directory contains tv/ and/or
movies/ subfolders:
/mnt/media/
โโโ tv/
โ โโโ ...
โโโ movies/
โโโ ...
sudo plex-organizer /mnt/media
In this mode, the organizer processes all unindexed content under both
tv/ and movies/. TV show names are derived from the
subdirectory name inside tv/.
Single folder mode
The start directory is the torrent save path โ its path must
contain tv or movies as a path component:
/mnt/media/movies/Venom.2018.BluRay.x264-YTS/
/mnt/media/tv/Black.Bird.S01/
sudo plex-organizer /mnt/media/movies/Venom.2018.BluRay.x264-YTS
This is the recommended mode for qBittorrent automation (use %D).
Only the specific download folder is processed rather than the entire library.
Unrecognized directories
If the path does not contain tv or movies and is not
a main folder, the organizer
exits immediately without modifying any files. The torrent is
removed if a hash was provided.
Manual running
Run the full pipeline on your media library:
sudo plex-organizer /mnt/media
Test run on a specific folder (no torrent removal):
sudo plex-organizer /mnt/media/movies/SomeMovie.2024.1080p
Automated running with qBittorrent
In qBittorrent, go to Tools โ Options โ Downloads and set the "Run external program on torrent finished" field:
sudo plex-organizer "%D" "%I"
| qBittorrent variable | Description |
|---|---|
%D |
Torrent save path (the download directory) |
%I |
Torrent hash (for automatic removal after processing) |
%D (torrent save path) is recommended over a static path
like /mnt/media because it targets only the newly finished
torrent rather than re-scanning the entire library on every completion.
Rename formats
TV shows
Show Name SxxExx.ext
Show Name SxxExx Quality.ext โ when include_quality = true
Examples:
Breaking Bad S05E14.mkvBreaking Bad S05E14 1080p.mkv
Files are moved to:
tv/<Show Name>/Season <x>/<Show Name> SxxExx [Quality].ext
Movies
Name (Year).ext
Name (Year) Quality.ext โ when include_quality = true
Examples:
Dune (2021).mkvDune (2021) 2160p.mkv
Files are moved to:
movies/<Name (Year)>/<Name (Year)> [Quality].ext
What gets deleted
Kept:
-
Video files:
.mkv,.mp4(and.!qBin-progress downloads) - The organizer index file:
.plex_organizer.index
Deleted:
-
Any file not matching the above (
.srt,.nfo,.txt,.jpg, artwork, etc.) - Any file with
samplein its name -
Folders:
Subs/,Subtitles/,Extras/,Sample/,Samples/,Featurettes/, poster/artwork folders,Plex Versions/
Plex Versions/) are
never modified. The organizer detects and skips them
automatically.
Indexing
The organizer keeps a per-library index file
(.plex_organizer.index) to skip already-processed files on future
runs:
- Movies: index stored in the movies root
-
TV shows: index stored in the TV root (
tv/)
Only files already in the final renamed layout are marked as indexed. Raw/unprocessed filenames are never added to the index.
To rebuild or generate indexes manually:
sudo plex-organizer --manage # option 4
Flags
| Flag | Description |
|---|---|
--manage |
Open the interactive management menu |
--help |
Show usage information |
Features
File renaming
Plex Organizer renames media files to a consistent, Plex-friendly format, correctly capitalizing names and optionally appending quality tags.
TV shows
Show Name SxxExx.ext
Show Name SxxExx Quality.ext โ include_quality = true
-
Season and episode numbers are zero-padded to two digits
(
S01E01) -
Show name is derived from the parent folder name (single-folder mode) or the
tv/<Show>/path (main-folder mode) - Files land in
tv/<Show Name>/Season <x>/
Movies
Name (Year).ext
Name (Year) Quality.ext โ include_quality = true
- Year is extracted from the filename
- Files land in
movies/<Name (Year)>/ - The subfolder never includes quality โ only the filename does
Quality detection fallback
When include_quality = true but the filename contains no quality
tag, the organizer probes the video stream height via ffprobe and
maps it to the nearest standard label:
| Stream height | Label |
|---|---|
| โฅ 2160 px | 2160p |
| โฅ 1440 px | 1440p |
| โฅ 1080 px | 1080p |
| โฅ 720 px | 720p |
| < 720 px | 480p |
Subtitle pipeline
Three separate stages handle subtitles, in order:
1. Subtitle embedding
Enabled by [Subtitles] enable_subtitle_embedding = true.
-
Discovers external subtitle files (
.srt,.ass,.ssa,.vtt, etc.) in the video folder and anySubs/orSubtitles/subfolder -
Detects the subtitle language (ISO 639-2) using
langdetect - Detects SDH (subtitles for the deaf and hard of hearing) from naming conventions
- Embeds subtitles into the video container via
ffmpeg
When analyze_embedded_subtitles = true (default),
already-embedded subtitle streams with missing or unknown language tags are
also analyzed and re-tagged.
2. Subtitle fetching
Enabled by [Subtitles] fetch_subtitles = eng (or other language
codes).
- Only runs for languages not already present as embedded subtitle streams
- Searches free online providers: OpenSubtitles, Podnapisi, Gestdown, TVsubtitles
-
Downloads the best-matching SRT, embeds it via
ffmpeg, then removes the temp file - Best-effort โ provider failures are logged and processing continues
3. Subtitle syncing
Enabled by [Subtitles] sync_subtitles = true.
- Runs after embedding and fetching
-
Extracts each text-based subtitle stream (SRT, ASS/SSA,
mov_text, WebVTT) to a temp file -
Uses
ffsubsyncto align timing to the video's audio track - Compares synced output to the original via SHA-256 โ only remuxes if timing actually changed
- Bitmap formats (PGS, DVB, VobSub) are left unchanged
Audio language tagging
Enabled by [Audio] enable_audio_tagging = true.
Many downloaded videos have audio streams with no language tag, or an
incorrect und (undefined) tag. Plex relies on these tags for the
audio track selection menu and "original language" feature.
How it works:
ffprobeenumerates all audio streams-
For streams with a missing or
und/unknowntag, a short WAV sample is extracted - faster-whisper runs speech-to-text language detection on the sample
-
The detected ISO 639-2 code (e.g.
eng,spa,est) is written back into the container via anffmpeg -c copyremux
The Whisper model size is configurable via
[Audio] whisper_model_size. The default tiny model
is fast and sufficient for most cases.
Aggressive cleanup
Cleanup runs before renaming and moving. It is intentionally aggressive so your Plex library stays clean.
What is kept
- Video files:
.mkv,.mp4 - In-progress downloads:
.!qB - Organizer index:
.plex_organizer.index
What is deleted
| Type | Examples |
|---|---|
| All non-video files |
.srt, .nfo, .txt,
.jpg, .png, NFO files
|
| Sample files | Any file with sample in its name |
| Unwanted folders |
Subs/, Subtitles/, Extras/,
Sample/, Featurettes/
|
| Artwork folders |
Posters/, Fanart/, behind-the-scenes folders
|
| Plex managed |
Plex Versions/ (detected and skipped,
never modified)
|
Subs/ and external .srt files are embedded into the
container before being removed from disk.
Per-library indexing
After processing, successfully renamed files are added to a
.plex_organizer.index JSON file stored in the library root:
-
Movies index โ
movies/.plex_organizer.index - TV index โ
tv/.plex_organizer.index
On future runs, indexed filenames are skipped immediately, making incremental runs fast regardless of library size.
Rules
- Only files already in the final renamed layout are indexed
- Raw/unprocessed names are never added to the index (prevents skipping files that need processing)
- The index file itself is protected from cleanup deletion
qBittorrent integration
When a torrent hash is provided as the second argument, Plex Organizer calls the qBittorrent Web API to remove the torrent (without deleting files) after successful processing.
- Authenticates via
POST /api/v2/auth/login -
Removes the torrent via
POST /api/v2/torrents/deletewithdeleteFiles=false - Best-effort: authentication or removal failures are logged; the rest of the pipeline is unaffected
-
Configure host and credentials under
[qBittorrent]inconfig.ini
Plex Version safety
The organizer never modifies paths inside
Plex Versions/ subfolders. These contain Plex's on-the-fly
transcoded or optimized versions, and touching them would corrupt your
library. Detection is automatic.
Single-instance locking
A file-based advisory lock prevents two instances from running simultaneously on the same data directory. If a second invocation detects the lock, it exits immediately. The lock is released automatically when the process ends.
To kill a stuck instance:
sudo plex-organizer --manage # option 5
Frequently Asked Questions
General
Does Plex Organizer delete my files?
Cleanup is intentional and aggressive. Only video files
(.mkv, .mp4), in-progress
.!qB downloads, and .plex_organizer.index files
are kept. Everything else โ subtitle files, NFOs, artwork, text files,
sample files โ is deleted.
Subtitle files are embedded into the video container
before cleanup runs (when
enable_subtitle_embedding = true), so they are preserved
inside the container.
Back up any files you want to keep before running the organizer on a new library.
Does it require root?
Yes. The organizer requires root privileges to move and rename files
across mount points. Always run with sudo.
Can I run it without qBittorrent?
Yes. The torrent hash argument is optional. Omit it to skip torrent removal:
sudo plex-organizer /mnt/media
What happens if the organizer crashes mid-run?
Files that were already moved and indexed remain safe. The organizer uses a single-instance lock and a per-library index, so a subsequent run will skip already-processed files and resume from where it left off. Partially processed files may need to be re-run manually.
Will it re-process files I've already organized?
No. Once a file is in the final renamed layout (e.g.
Black Bird S01E01.mp4 inside
tv/Black Bird/Season 1/), it is added to the index and
skipped on future runs.
Installation
Where is `plex-organizer` after installing?
The command is installed into root's pipx environment. After running
sudo pipx ensurepath, it should be available as
sudo plex-organizer. If not, check that
/root/.local/bin is on root's PATH.
How do I uninstall?
sudo pipx uninstall plex-organizer
Configuration
Where is config.ini?
Default location: /root/.config/plex-organizer/config.ini
You can override this with the PLEX_ORGANIZER_DIR environment
variable.
I added a custom option to config.ini and it disappeared.
The config is auto-managed: unknown options inside known sections are removed on startup. Only options listed in the Configuration reference are preserved.
How do I disable subtitle fetching?
Set fetch_subtitles to an empty value:
[Subtitles]
fetch_subtitles =
How do I disable the subtitle pipeline entirely?
[Subtitles]
enable_subtitle_embedding = false
fetch_subtitles =
sync_subtitles = false
Subtitle pipeline
External subtitles are being deleted โ how do I keep them?
Enable subtitle embedding before cleanup runs:
[Subtitles]
enable_subtitle_embedding = true
External subtitle files are embedded into the video container and then
removed from disk. They are preserved inside the .mkv/.mp4
file itself.
Subtitle syncing is too slow.
Subtitle syncing uses ffsubsync, which processes the entire
audio track. You can disable it:
[Subtitles]
sync_subtitles = false
What subtitle formats are supported for syncing?
Only text-based streams: SRT, ASS/SSA, mov_text, and WebVTT.
Bitmap formats (PGS, DVB, VobSub) are left unchanged.
Indexing
How do I force re-processing of already-indexed files?
Delete the index file(s) and run again:
rm /mnt/media/movies/.plex_organizer.index
rm /mnt/media/tv/.plex_organizer.index
sudo plex-organizer /mnt/media
How do I generate an index for an existing library without re-processing?
Use the management menu:
sudo plex-organizer --manage # option 4
This scans the library and adds all already-organized files to the index without moving or renaming anything.
I upgraded from an older version and TV files are being re-processed.
Older versions stored one index per show
(tv/<Show>/.plex_organizer.index). Migrate them to the
new root index:
sudo plex-organizer --manage # option 7
This merges all per-show index files into a single
tv/.plex_organizer.index and removes the old files.
Migrating from v5.0 to v6.0
What changed between v5.0 and v6.0?
| v5.0 (old) | v6.0+ (new) | |
|---|---|---|
| Install | git clone + run.sh |
pipx install git+โฆ |
| Update | ./update.sh |
pipx upgrade plex-organizer |
| Run | sudo bash run.sh <dir> [hash] |
sudo plex-organizer <dir> [hash] |
| Kill | โ | sudo plex-organizer --manage โ option 5 |
| Config location | Repo directory | /root/.config/plex-organizer/ |
See the full migration steps on the Installation page.
Changelog
Release history for Plex Organizer. Full diffs and download links are available on the GitHub Releases page .
-
Advisory lock fix โ The single-instance lock now keeps
the file handle open for the lifetime of the process, preventing the
advisory
flockfrom being released prematurely. - Quieter index reads โ Removed spurious error log when an index file does not yet exist; a missing index is a normal first-run condition.
-
Test script portability โ
test.shnow detects the installedplex-organizercommand instead of relying on a hard-coded Python script path. - Validation checklist โ Added a post-change validation rule requiring SonarCloud scan, pylint, and pytest to pass before considering a task complete.
Breaking changes:
-
New install method โ Plex Organizer is now installed
via
pipxinstead of cloning the repo and running shell scripts. See Migration from v5.0. -
Reworked index structure โ TV indexes are now stored in
the TV library root (
tv/) instead of per-show directories. Migration tool available viaplex-organizer --manageโ option 7.
New features:
- Subtitle fetching โ Searches OpenSubtitles, Podnapisi, Gestdown, and TVsubtitles for missing subtitles and embeds them.
-
Subtitle syncing โ Aligns embedded subtitle timing to
the audio track using
ffsubsync. -
Analyze embedded subtitles toggle โ New
analyze_embedded_subtitlesoption. -
Interactive management menu โ
plex-organizer --manageprovides a menu-driven helper. -
Quality detection fallback โ Probes video stream height
via
ffprobewhen no quality tag is found in the filename.
Improvements:
-
Full
pytest+pytest-covtest suite mirroring the source package layout. - CI pipeline โ SonarCloud analysis, pylint, and pytest run automatically on push.
-
Packaged via
pyproject.tomlwith declared dependencies. - Restructured codebase into focused modules.
- Per-library indexing โ Keeps track of processed files to speed up future runs on large libraries.
- Improved debug logging entries.
- Documentation updates and devcontainer config refactoring.
-
Authentication flow โ Implemented a
requests.Session-based authentication for the qBittorrent Web API. -
Added
username/passwordoptions to the[qBittorrent]config section. - More debug logging lines.
-
Log level option โ Added
levelto[Logging]supportingINFOandDEBUG. - Single-instance lock โ File-based lock prevents multiple instances from running simultaneously.
-
Temp file guard โ Added
is_script_temp_file()utility to skip internal temp files.
- Timestamped log directories โ Log directory is now created automatically when timestamped logs are enabled.
- Dev Container enhancements: runtime detection of NVIDIA, Intel, AMD, and Qualcomm GPU drivers.
- Documentation updates and core codebase refactoring.
- Audio language detection and tagging โ Detects and writes ISO 639-2 audio stream language tags.
- Subtitle embedding โ Embeds external subtitle files into the video container.
- Added VS Code Dev Container support.
-
Added support for using
%D(torrent save path) instead of requiring the full root directory. - Added title-case capitalization for show/movie names.
-
Added more configuration options to
config.ini, including enhanced logging. - Fixed file deletion bug and other minor fixes.
Early releases establishing the core renaming, moving, and cleanup pipeline.