Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Makefile for labelarr

# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
GOMOD=$(GOCMD) mod
BINARY_NAME=labelarr
BINARY_PATH=./cmd/labelarr

# Build the application
.PHONY: build
build:
$(GOBUILD) -o $(BINARY_NAME) $(BINARY_PATH)

# Run tests
.PHONY: test
test:
$(GOTEST) -v ./...

# Run tests with coverage
.PHONY: test-coverage
test-coverage:
$(GOTEST) -v -cover ./...

# Run tests with coverage report
.PHONY: test-coverage-html
test-coverage-html:
$(GOTEST) -v -coverprofile=coverage.out ./...
$(GOCMD) tool cover -html=coverage.out -o coverage.html
@echo "Coverage report generated: coverage.html"

# Run benchmarks
.PHONY: benchmark
benchmark:
$(GOTEST) -bench=. -benchmem ./...

# Clean build artifacts
.PHONY: clean
clean:
$(GOCLEAN)
rm -f $(BINARY_NAME)
rm -f coverage.out coverage.html

# Download dependencies
.PHONY: deps
deps:
$(GOMOD) download
$(GOMOD) tidy

# Run linter (requires golangci-lint to be installed)
.PHONY: lint
lint:
golangci-lint run

# Run the application
.PHONY: run
run: build
./$(BINARY_NAME)

# Build for multiple platforms
.PHONY: build-all
build-all:
GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_NAME)-linux-amd64 $(BINARY_PATH)
GOOS=windows GOARCH=amd64 $(GOBUILD) -o $(BINARY_NAME)-windows-amd64.exe $(BINARY_PATH)
GOOS=darwin GOARCH=amd64 $(GOBUILD) -o $(BINARY_NAME)-darwin-amd64 $(BINARY_PATH)

# Help target
.PHONY: help
help:
@echo "Available targets:"
@echo " build - Build the application"
@echo " test - Run all tests"
@echo " test-coverage - Run tests with coverage"
@echo " test-coverage-html - Generate HTML coverage report"
@echo " benchmark - Run benchmark tests"
@echo " clean - Clean build artifacts"
@echo " deps - Download and tidy dependencies"
@echo " lint - Run linter"
@echo " run - Build and run the application"
@echo " build-all - Build for multiple platforms"
@echo " help - Show this help message"
96 changes: 76 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,35 +150,59 @@ services:
The application can find TMDb IDs from multiple sources and supports flexible formats:

- **Plex Metadata**: Standard TMDb agent IDs
- **File Paths**: `{tmdb-12345}` in filenames or directory names
- **Flexible Formats**: The TMDb ID can be detected in a variety of patterns, not just `{tmdb-12345}`. Supported patterns include:
- `{tmdb-12345}` (curly braces, anywhere in the folder or file name)
- `[tmdb-12345]` (square brackets)
- `(tmdb-12345)` (parentheses)
- `tmdb-12345` (standalone, with or without delimiters)
- Case-insensitive: `TMDB-12345`, `Tmdb-12345`, etc.
- The TMDb ID can appear in either the directory or file name, and can be surrounded by spaces or other characters.
- **Delimiters**: The TMDb ID pattern supports all common delimiters (such as `:`, `;`, `-`, `_`, etc.) between `tmdb` and the ID. For example:
- `tmdb:15448`
- `tmdb;15448`
- `tmdb-15448`
- `tmdb_15448`
- `tmdb: 15448`, `tmdb- 15448`, etc.
- These can appear in any of the supported bracket/brace/parenthesis formats or standalone.
- The pattern will **not** match `tmdb15448` (no separator).

Example file paths:
- **File Paths**: Flexible TMDb ID detection in filenames or directory names

### ✅ **Supported Patterns** (Case-Insensitive)

The TMDb ID detection is very flexible and supports various formats:

**Direct Concatenation:**

- `/movies/The Matrix (1999) tmdb603/file.mkv`
- `/movies/Inception (2010) TMDB27205/file.mkv`
- `/movies/Avatar (2009) Tmdb19995/file.mkv`

**With Separators:**

- `/movies/Interstellar (2014) tmdb:157336/file.mkv`
- `/movies/The Dark Knight (2008) tmdb-155/file.mkv`
- `/movies/Pulp Fiction (1994) tmdb_680/file.mkv`
- `/movies/Fight Club (1999) tmdb=550/file.mkv`
- `/movies/The Shawshank Redemption (1994) tmdb 278/file.mkv`

**With Brackets/Braces:**

- `/movies/Goodfellas (1990) {tmdb634}/file.mkv`
- `/movies/Forrest Gump (1994) [tmdb-13]/file.mkv`
- `/movies/The Godfather (1972) (tmdb:238)/file.mkv`
- `/movies/Taxi Driver (1976) {tmdb=103}/file.mkv`
- `/movies/Casablanca (1942) (tmdb 289)/file.mkv`

**Mixed Examples:**

- `/movies/Citizen Kane (1941) something tmdb: 15678 extra/file.mkv`
- `/movies/Vertigo (1958) {tmdb=194884}/file.mkv`
- `/movies/Psycho (1960) [ tmdb-539 ]/file.mkv`

### ❌ **Will NOT Match**

- `mytmdb12345` (preceded by alphanumeric characters)
- `tmdb12345abc` (followed by alphanumeric characters)
- `tmdb` (no digits following)

### 📁 **Example File Paths**

```
/movies/The Matrix (1999) [tmdb-603]/The Matrix.mkv
/movies/Inception (2010) (tmdb:27205)/Inception.mkv
/movies/Avatar (2009) tmdb;19995/Avatar.mkv
/movies/Avatar (2009) tmdb19995/Avatar.mkv
/movies/Interstellar (2014) TMDB_157336/Interstellar.mkv
/movies/Edge Case - {tmdb-12345}/file.mkv
/movies/Edge Case - {tmdb=12345}/file.mkv
/movies/Colon: [tmdb:54321]/file.mkv
/movies/Semicolon; (tmdb;67890)/file.mkv
/movies/Underscore_tmdb_11111/file.mkv
/movies/ExtraSuffix tmdb-22222_extra/file.mkv
/movies/Direct tmdb194884 format/file.mkv
```

</details>
Expand Down Expand Up @@ -523,6 +547,38 @@ If you have an existing movie library without TMDb IDs in file paths:

**⚠️ Note**: Large libraries may take time to rename. Consider doing this in batches during low-usage periods.

### 📺 Sonarr Users: Renaming Existing Folders to Include TMDb ID

If you're using Sonarr to manage your TV show collection and want to apply new folder naming that includes TMDb IDs, here's how to rename existing folders:

#### **🔄 Apply the New Folder Names**

To actually rename existing folders:

1. **Go to the Series tab**

2. **Click the Mass Editor** (three sliders icon)

3. **Select the shows** you want to rename

4. **At the bottom, click "Edit"**

5. **In the popup:**
- Set the **Root Folder** to the same one it's already using (e.g., `/mnt/user/TV`)
- Click **"Save"**

6. **Sonarr will interpret this as a move** and apply the new folder naming format without physically moving the files—just renaming the folders.

#### **Example Result**

After applying the new naming format, your TV show folders will include TMDb IDs:

```
/tv/Batman [tmdb-2287]/Season 3/Batman - S03E17 - The Joke's on Catwoman Bluray-1080p [tmdb-2287].mkv
```

**💡 Pro Tip**: This method works for renaming folders without actually moving files, making it safe and efficient for large TV libraries.

</details>

<details id="local-development">
Expand Down
6 changes: 4 additions & 2 deletions internal/media/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,8 +498,10 @@ func (p *Processor) extractTVShowTMDbID(item MediaItem) string {

// ExtractTMDbIDFromPath extracts TMDb ID from file path using regex
func ExtractTMDbIDFromPath(filePath string) string {
// Updated regex pattern to match {tmdb-123456} anywhere in the path
re := regexp.MustCompile(`\{tmdb-(\d+)\}`)
// Flexible regex pattern to match tmdb followed by digits with separators around the whole pattern
// Matches: tmdb123, tmdb:123, {tmdb-456}, [tmdb=789], tmdb_012, etc.
// Requires word boundaries or separators around the tmdb+digits pattern
re := regexp.MustCompile(`(?i)(?:^|[^a-zA-Z0-9])tmdb[^a-zA-Z0-9]*(\d+)(?:[^a-zA-Z0-9]|$)`)
matches := re.FindStringSubmatch(filePath)
if len(matches) > 1 {
return matches[1]
Expand Down
Loading