{"id":39134583,"url":"https://github.com/kliatsko/librarylint","last_synced_at":"2026-04-23T05:06:00.572Z","repository":{"id":213991729,"uuid":"735428706","full_name":"kliatsko/librarylint","owner":"kliatsko","description":"Automates the tedious parts of managing a media library — from extracting and renaming downloads to fetching metadata, artwork, trailers, and subtitles. Supports Kodi/Plex/Jellyfin naming conventions with TMDB and TVDB integration.","archived":false,"fork":false,"pushed_at":"2026-04-21T13:06:11.000Z","size":3767,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-21T14:43:09.178Z","etag":null,"topics":["jellyfin","kodi","media","media-library","media-library-management","media-organization","plex","powershell","tmdb","tvdb"],"latest_commit_sha":null,"homepage":"","language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kliatsko.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-12-24T22:34:38.000Z","updated_at":"2026-04-21T12:53:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"51a13720-c90d-4757-b7c7-77d0cf35b0d4","html_url":"https://github.com/kliatsko/librarylint","commit_stats":null,"previous_names":["kliatsko/mediacleaner","kliatsko/librarylint"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/kliatsko/librarylint","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kliatsko%2Flibrarylint","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kliatsko%2Flibrarylint/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kliatsko%2Flibrarylint/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kliatsko%2Flibrarylint/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kliatsko","download_url":"https://codeload.github.com/kliatsko/librarylint/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kliatsko%2Flibrarylint/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32166681,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T02:19:40.750Z","status":"ssl_error","status_checked_at":"2026-04-23T02:17:55.737Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jellyfin","kodi","media","media-library","media-library-management","media-organization","plex","powershell","tmdb","tvdb"],"created_at":"2026-01-17T21:23:10.968Z","updated_at":"2026-04-23T05:06:00.563Z","avatar_url":"https://github.com/kliatsko.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.png\" alt=\"LibraryLint\" width=\"200\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eLibraryLint\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\nA modular toolkit for media library organization, cleanup, and management.\u003cbr\u003e\nDesigned for managing movie and TV show collections with support for Kodi/Plex/Jellyfin-compatible naming and metadata.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/PowerShell-7+-blue.svg\" alt=\"PowerShell\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Windows-10+-green.svg\" alt=\"Windows\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Version-5.6.3-orange.svg\" alt=\"Version\"\u003e\n\u003c/p\u003e\n\n\u003e **New to LibraryLint?** Check out the [Getting Started Guide](GETTING_STARTED.md) for setup instructions.\n\n## Features\n\n### Core Functionality\n- **Dry-run mode** - Preview all changes before applying them\n- **Comprehensive logging** - All operations logged with timestamps\n- **Progress tracking** - Visual progress indicators with ETA for long operations\n- **Auto-updater** - Check for new versions from GitHub\n- **First-run setup wizard** - Guided configuration on first launch\n- **Automatic dependency installation** - Installs 7-Zip, FFmpeg, yt-dlp via winget\n\n### Movie Processing\n- Extract archives (.rar, .zip, .7z, .tar, .gz, .bz2)\n- Remove unnecessary files (samples, proofs, screenshots)\n- Process trailers (move to `_Trailers` folder or delete)\n- Process subtitles (keep preferred language, delete others)\n- Create individual folders for loose video files\n- Clean folder names by removing quality/codec/release tags\n- Format movie years with parentheses (`Movie 2024` → `Movie (2024)`)\n- Generate Kodi-compatible NFO files with TMDB metadata\n- Download artwork (poster, fanart, clearlogo, clearart)\n- Auto-move processed movies from inbox to main library\n\n### TV Show Processing\n- Extract all archives\n- Parse episode info (S01E01, 1x01, multi-episode S01E01-E03)\n- Organize episodes into Season folders\n- Rename episodes to standard format\n- Detect missing episodes (gap detection)\n- Remove empty folders\n- Generate NFO files with TVDB metadata (tvshow.nfo + episode NFOs)\n- Download artwork (poster, fanart, season posters, actor images)\n- Auto-move processed shows from inbox to main library (with season merging)\n\n### Advanced Features\n- **Duplicate Detection** - Find duplicates using file hashing and quality scoring\n- **TMDB Integration** - Fetch movie metadata from The Movie Database\n- **TVDB Integration** - Fetch TV show metadata from TheTVDB\n- **Fanart.tv Integration** - Extended artwork (clearlogo, banner, clearart, extrafanart)\n- **Codec Analysis** - Analyze video codecs and generate FFmpeg transcode scripts\n- **Health Check** - Validate library for issues (empty folders, missing files, etc.)\n- **MediaInfo Integration** - Accurate codec detection from file headers\n- **Export Reports** - Generate CSV, HTML, and JSON library reports\n- **Undo/Rollback** - Manifest-based rollback of changes\n- **Configuration Files** - Save/load settings to JSON\n- **Radarr Integration** - Re-acquisition utility, import verification for SFTP pruning\n- **TMDB ID Deduplication** - Detect duplicates by metadata, not just folder name\n- **NFO-only Refresh** - Regenerate NFOs without re-downloading artwork/trailers\n\n### Sync \u0026 Backup Modules\n- **SFTP Sync** - Download new files from seedbox/remote server (requires WinSCP)\n- **Mirror Backup** - Robocopy-based mirroring to external drives with ETA\n- **Integrated Workflow** - Sync → Process → Transfer → Mirror\n\n## Requirements\n\n- Windows 10 or later\n- PowerShell 7 or later\n- 7-Zip (automatically installed if not present)\n\n### Optional Dependencies\n| Tool | Purpose | Install |\n|------|---------|---------|\n| [MediaInfo](https://mediaarea.net/en/MediaInfo) | Accurate codec detection | `winget install MediaArea.MediaInfo` |\n| [FFmpeg](https://ffmpeg.org/) | Video transcoding | `winget install ffmpeg` |\n| [yt-dlp](https://github.com/yt-dlp/yt-dlp) | Trailer downloads | `winget install yt-dlp` |\n| [WinSCP](https://winscp.net/) | SFTP sync module | `winget install WinSCP` |\n\n### Optional API Keys (Free)\n| Service | Purpose | Get Key |\n|---------|---------|---------|\n| TMDB | Movie metadata \u0026 posters | [themoviedb.org](https://www.themoviedb.org/settings/api) |\n| TVDB | TV show metadata \u0026 artwork | [thetvdb.com](https://thetvdb.com/api-information) |\n| Fanart.tv | Clearlogos, banners, clearart | [fanart.tv](https://fanart.tv/get-an-api-key/) |\n| Subdl | Subtitle downloads | [subdl.com](https://subdl.com/panel/api) |\n\n## Installation\n\n### Option 1: Double-click launcher\n1. Download or clone the repository\n2. Double-click `Run-LibraryLint.bat`\n\n### Option 2: PowerShell\n```powershell\ngit clone https://github.com/kliatsko/librarylint.git\ncd librarylint\n.\\LibraryLint.ps1\n```\n\n### Option 3: First-time setup\nRun with `-Setup` to launch the configuration wizard:\n```powershell\n.\\LibraryLint.ps1 -Setup\n```\n\n## Usage\n\n### Interactive Mode\nSimply run the script and follow the prompts:\n```powershell\n.\\LibraryLint.ps1\n```\n\n### With Verbose Output\n```powershell\n.\\LibraryLint.ps1 -Verbose\n```\n\n### With Custom Config File\n```powershell\n.\\LibraryLint.ps1 -ConfigFile \"C:\\path\\to\\config.json\"\n```\n\n### Check for Updates\n```powershell\n.\\LibraryLint.ps1 -Update\n```\n\n## Main Menu Options\n\n| Option | Description |\n|--------|-------------|\n| **New Content** ||\n| 1 | **Process New Movies** - Full movie cleanup, metadata, and organization |\n| 2 | **Process New TV Shows** - Organize episodes into season folders |\n| 3 | **Process All** - Run both movies and TV shows in sequence |\n| **Library Maintenance** ||\n| 4 | **Fix \u0026 Repair** - Fix folder names, refresh metadata, find duplicates |\n| 5 | **Enhancements** - Download trailers, subtitles, artwork |\n| 6 | **Utilities** - SFTP sync, mirror backup, export reports, undo |\n| **Other** ||\n| 7 | **Settings** - Configure paths, API keys, preferences |\n| ? | **Help** - Interactive help menu |\n| 0 | **Exit** |\n\n## Supported Formats\n\n### Video\n`.mp4`, `.mkv`, `.avi`, `.mov`, `.wmv`, `.flv`, `.m4v`\n\n### Subtitles\n`.srt`, `.sub`, `.idx`, `.ass`, `.ssa`, `.vtt`\n\n### Archives\n`.rar`, `.zip`, `.7z`, `.tar`, `.gz`, `.bz2`\n\n## Configuration\n\nSettings are stored in `%LOCALAPPDATA%\\LibraryLint\\LibraryLint.config.json`\n\nKey configuration options:\n- `DryRun` - Preview mode (no changes made)\n- `KeepSubtitles` - Keep subtitle files\n- `KeepTrailers` - Move trailers to `_Trailers` folder\n- `PreferredSubtitleLanguages` - Languages to keep (default: English)\n- `GenerateNFO` - Auto-generate Kodi NFO files\n- `TMDBApiKey` - Your TMDB API key\n- `DownloadTrailers` - Download movie trailers from YouTube\n- `TrailerQuality` - Trailer quality: 1080p, 720p, or 480p\n- `DownloadSubtitles` - Download subtitles from Subdl.com\n- `SubtitleLanguage` - Subtitle language code (default: en)\n- `RetryCount` - Number of retries for failed operations\n- `EnableUndo` - Enable undo manifest creation\n\n## Trailer Downloads (Optional)\n\nLibraryLint can automatically download movie trailers from YouTube and save them in Kodi-compatible format.\n\n### Setup\n\n1. **Install yt-dlp** (choose one method):\n   ```powershell\n   # Using winget (recommended)\n   winget install yt-dlp\n\n   # Using pip\n   pip install yt-dlp\n\n   # Manual download\n   # Download yt-dlp.exe from https://github.com/yt-dlp/yt-dlp/releases\n   # Place it in your PATH or C:\\Program Files\\yt-dlp\\\n   ```\n\n2. **Run LibraryLint** - If yt-dlp is detected, you'll be prompted:\n   ```\n   Download movie trailers from YouTube? (Y/N) [N]\n   ```\n\n3. **Trailers are saved as** `MovieTitle-trailer.mp4` in each movie folder\n\n### Configuration\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `DownloadTrailers` | `false` | Enable/disable trailer downloads |\n| `TrailerQuality` | `720p` | Video quality: 1080p, 720p, or 480p |\n\n### Storage Estimates\n\n| Quality | Per Trailer | 100 Movies | 500 Movies |\n|---------|-------------|------------|------------|\n| 1080p | 50-150 MB | 5-15 GB | 25-75 GB |\n| 720p | 20-60 MB | 2-6 GB | 10-30 GB |\n| 480p | 10-30 MB | 1-3 GB | 5-15 GB |\n\n## Subtitle Downloads (Optional)\n\nLibraryLint can automatically download subtitles from [Subdl.com](https://subdl.com) and save them in Kodi-compatible format.\n\n### How It Works\n\n1. **Uses IMDB ID** - Searches by IMDB ID first (from TMDB metadata) for accurate matches\n2. **Fallback to title** - If no IMDB match, searches by movie title and year\n3. **Skips existing** - Won't download if subtitle already exists in the folder\n4. **Rate limited** - Respects Subdl.com's 1 request/second rate limit\n\n### Setup\n\n1. **Get a free API key** at [https://subdl.com/panel/api](https://subdl.com/panel/api)\n   - Create a free account on Subdl.com\n   - Go to your panel and generate an API key\n\n2. **Run LibraryLint** - You'll be prompted for your API key the first time\n\n3. **Subtitles are saved as** `MovieTitle.en.srt` in each movie folder\n\n### Configuration\n\n| Option | Default | Description |\n|--------|---------|-------------|\n| `DownloadSubtitles` | `false` | Enable/disable subtitle downloads |\n| `SubtitleLanguage` | `en` | Language code (en, es, fr, de, it, pt, etc.) |\n| `SubdlApiKey` | `null` | Your Subdl.com API key |\n\n### Supported Languages\n\nCommon language codes: `en` (English), `es` (Spanish), `fr` (French), `de` (German), `it` (Italian), `pt` (Portuguese), `ru` (Russian), `ja` (Japanese), `ko` (Korean), `zh` (Chinese)\n\n### Storage\n\nSubtitles are very small - typically 50-150 KB each. A library of 500 movies would only use ~25-75 MB for subtitles.\n\n## File Locations\n\n| File Type | Location |\n|-----------|----------|\n| Logs | `%LOCALAPPDATA%\\LibraryLint\\Logs\\` |\n| Config | `%LOCALAPPDATA%\\LibraryLint\\LibraryLint.config.json` |\n| Undo Manifests | `%LOCALAPPDATA%\\LibraryLint\\Undo\\` |\n\n## Modules\n\nLibraryLint includes optional modules for sync and backup workflows. These are loaded automatically if present in the `modules/` folder.\n\n### SFTP Sync (`modules/Sync.psm1`)\n\nDownloads new files from a remote SFTP server (seedbox, NAS, etc.) with tracking to avoid re-downloading.\n\n**Features:**\n- Recursive scanning of remote directories\n- Automatic file categorization (Movies vs TV Shows based on size and naming)\n- Download tracking to skip already-synced files\n- Optional deletion of files after download\n- Separate sync and prune paths (download from one location, clean up another)\n- Radarr-verified pruning (only delete files that Radarr has imported)\n- Dry-run and list-only modes\n\n**Requirements:** [WinSCP](https://winscp.net/) with .NET assembly (`winget install WinSCP`)\n\n**Configuration:**\n```json\n{\n  \"SFTPHost\": \"your-server.com\",\n  \"SFTPPort\": 22,\n  \"SFTPUsername\": \"username\",\n  \"SFTPPassword\": \"password\",\n  \"SFTPRemotePaths\": [\"/downloads\"],\n  \"SFTPPrunePaths\": [],\n  \"SFTPDeleteAfterDownload\": false\n}\n```\n\n### Mirror Backup (`modules/Mirror.psm1`)\n\nMirrors media folders to a backup drive using robocopy with `/MIR` flag for exact synchronization.\n\n**Features:**\n- Multi-threaded copying (8 threads by default)\n- Progress tracking with file counts and ETA\n- Detailed summary of copied/skipped/deleted files\n- Dry-run mode for preview\n\n**Configuration:**\n```json\n{\n  \"MirrorSourceDrive\": \"G:\",\n  \"MirrorDestDrive\": \"F:\",\n  \"MirrorFolders\": [\"Movies\", \"Shows\"]\n}\n```\n\n### Quality Analysis (`modules/Quality.psm1`)\n\nScores video files by resolution, codec, source, and audio quality. Identifies files needing transcoding.\n\n**Features:**\n- Quality scoring (resolution, codec, source, audio, HDR)\n- Codec analysis with centralized caching\n- FFmpeg transcode script generation\n- Force rescan option to bypass cache\n\n### Subtitles (`modules/Subtitles.psm1`)\n\nManages subtitle files — detection, downloading, renaming, and timing correction.\n\n**Features:**\n- Language detection and filtering\n- Subtitle downloading via Subdl API\n- Timing correction with ffsubsync\n- Orphaned subtitle cleanup\n\n### TMDB/TVDB (`modules/TMDB.psm1`)\n\nAPI client for metadata lookups from The Movie Database and TheTVDB.\n\n**Features:**\n- TMDB movie search with Jaccard similarity scoring\n- TVDB show/episode lookup with cached tokens\n- Year tolerance and title normalization\n- Collection and set information\n\n## Quality Scoring\n\nWhen detecting duplicates, files are scored based on:\n- **Resolution**: 2160p (100) \u003e 1080p (80) \u003e 720p (60) \u003e 480p (40)\n- **Source**: BluRay (50) \u003e WEB-DL (40) \u003e WEBRip (35) \u003e HDRip (30)\n- **Codec**: x265/HEVC (30) \u003e x264 (20) \u003e XviD (10)\n- **Audio**: Atmos (25) \u003e DTS-HD (20) \u003e TrueHD (20) \u003e DTS (15) \u003e AC3 (10)\n- **HDR**: +20 bonus points\n\n## Screenshots\n\n### Processing Summary\n```\n╔══════════════════════════════════════════════════════════════════╗\n║                      PROCESSING SUMMARY                         ║\n╠══════════════════════════════════════════════════════════════════╣\n║  Duration:              00:02:34                                ║\n║  Files Deleted:         47                                      ║\n║  Space Reclaimed:       2.3 GB                                  ║\n║  Archives Extracted:    12                                      ║\n║  Folders Created:       8                                       ║\n║  Folders Renamed:       23                                      ║\n╚══════════════════════════════════════════════════════════════════╝\n```\n\n## Contributing\n\nThanks for your interest in contributing!\n\nLibraryLint is a personal project that I maintain in my spare time, so please keep the following in mind.\n\nSetting Expectations\nThis is a passion project, not a full-time endeavor. Response times on issues and pull requests will vary — sometimes I'll get back to you in a day, sometimes it might take a few weeks. I appreciate your patience.\n\nI'm also selective about scope. LibraryLint is intentionally a lightweight, run-it-when-you-want-it toolkit. Feature requests that would push it toward becoming a background service or duplicating what Radarr/Sonarr already do well will likely be declined. That's not a reflection on the quality of the idea — it's about keeping the project focused and maintainable.\n\nHow to Contribute\n\nReporting Bugs\n\nBefore opening an issue, please:\nMake sure you're running the latest version (.\\LibraryLint.ps1 -Update)\n\nCheck existing issues to avoid duplicates\nInclude your PowerShell version ($PSVersionTable.PSVersion), Windows version, and the relevant log output from %LOCALAPPDATA%\\LibraryLint\\Logs\\\n\nIf possible, describe the steps to reproduce the issue\n\nSuggesting Features\n\nOpen an issue with the \"enhancement\" label. A good feature request includes:\n\nA clear description of the problem you're trying to solve\nWhy existing functionality doesn't cover it\nWhether you'd be willing to implement it yourself\n\nSubmitting Pull Requests\nFork the repo and create a branch from main\nTest your changes with -DryRun mode before submitting\nKeep PRs focused — one feature or fix per PR\nUpdate the README if your change adds or modifies user-facing functionality\nInclude a brief description of what the PR does and why\n\nCode Style\nFollow existing PowerShell conventions used throughout the project\nUse meaningful variable and function names\nAdd comments for non-obvious logic\nTest with both -DryRun and live runs before submitting\n\nWhat I'm Most Interested In\nBug fixes and edge case handling\nImprovements to parsing logic (folder names, episode patterns)\nBetter error handling and user-facing messages\nDocumentation improvements\nWhat's Probably Out of Scope\nCross-platform support (this is a Windows/PowerShell tool by design)\nBackground service or daemon mode\nIntegration with download clients (that's Radarr/Sonarr territory)\nGUI or web interface\n\nLicense\nBy contributing, you agree that your contributions will be licensed under the MIT License.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Author\n\n**Nick Kliatsko**\n\n## Acknowledgments\n\n- [7-Zip](https://www.7-zip.org/) for archive extraction\n- [MediaInfo](https://mediaarea.net/en/MediaInfo) for codec detection\n- [The Movie Database (TMDB)](https://www.themoviedb.org/) for movie metadata\n- [TheTVDB](https://thetvdb.com/) for TV show metadata\n- [Fanart.tv](https://fanart.tv/) for extended artwork\n- [Subdl.com](https://subdl.com) for subtitle downloads\n- [WinSCP](https://winscp.net/) for SFTP transfers\n- [yt-dlp](https://github.com/yt-dlp/yt-dlp) for trailer downloads\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkliatsko%2Flibrarylint","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkliatsko%2Flibrarylint","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkliatsko%2Flibrarylint/lists"}