Metadata-Version: 2.4
Name: mediafinder
Version: 0.11.0
Summary: Media file finder and player
Project-URL: Homepage, https://github.com/aplzr/mf
Project-URL: Issues, https://github.com/aplzr/mf/issues
Author-email: ap <arnepelzerprivat@gmail.com>
License: MIT License
        
        Copyright (c) 2025-present The mediafinder developers
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE-MIT
Keywords: cli,filesystem,finder,media,player,video
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: System :: Filesystems
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: guessit>=3.8.0
Requires-Dist: imdbinfo>=0.6.3
Requires-Dist: packaging>=25.0
Requires-Dist: patool>=4.0.1
Requires-Dist: rich>=14.2.0
Requires-Dist: tomlkit>=0.13.3
Requires-Dist: typer>=0.19.2
Provides-Extra: dev
Requires-Dist: anybadge>=1.10.0; extra == 'dev'
Requires-Dist: mypy>=1.19.1; extra == 'dev'
Requires-Dist: prek>=0.2.23; extra == 'dev'
Requires-Dist: pytest-cov>=5.0.0; extra == 'dev'
Requires-Dist: pytest>=8.3.0; extra == 'dev'
Requires-Dist: ruff>=0.14.3; extra == 'dev'
Requires-Dist: rust-just>=1.45.0; extra == 'dev'
Description-Content-Type: text/markdown

# mf - Media File Finder

<!-- Local badges generated by CI into static/: coverage (anybadge from coverage.xml line-rate), python minimum version (MIN+ from requires-python) -->
![Python Versions](./static/badge_python.svg)
![Tests](https://img.shields.io/github/actions/workflow/status/aplzr/mf/ci.yml?branch=main&label=tests)
![Coverage](./static/badge_coverage.svg)
[![PyPI release](https://img.shields.io/pypi/v/mediafinder)](https://pypi.org/project/mediafinder/)
![Style](./static/badge_style.svg)

A cross-platform command-line tool for finding and playing video files in large collections

![](static/demo_mf.svg)

## Features

- **🔍 Fast file search** - Uses vendored `fd` binary with automatic fallback to Python scanning
- **🎯 Flexible pattern matching** - Glob-based search patterns with automatic wildcard wrapping
- **🚀 Quick access to search results** - Access found files by index number
- **📋 Search results as playlists** - Play through search results in order
- **💾 Caching of library metadata** - Cache library metadata for fast file lookups in network storage
- **📁 Multi-path scanning** - Search across multiple configured directories simultaneously
- **🕒 Latest additions** - Find newest files by modification time
- **🎬 Media player integration** - Launch files directly in VLC or mpv
- **📦 RAR archive support** - Automatically extract and play video files from RAR archives
- **🌐 IMDB lookup** - Automatically open IMDB pages for media files
- **⚙️ Flexible configuration** - TOML-based config with extension filtering and path management
- **📜 Scriptable output** - Plain text output mode for easy piping and scripting
- **🖥️ Cross-platform** - Works on Windows, Linux, and macOS

## Installation
Install with [uv](https://docs.astral.sh/uv/):

```
uv tool install mediafinder
```

## Quick Start

> [!NOTE]
> If `mf` is shadowed by another command on your system (e.g., Metafont), use `mediafinder` instead — it's already installed and works exactly the same way.

1. **Configure search paths** where your media files are located:

```bash
mf config set search_paths "/path/to/movies" "/path/to/tv-shows"
```

2. **Optional: Activate library caching**

If your collection is stored on the network, activate caching for fast file searches:

```bash
mf config set cache_library true
```

3. **Find media files** matching a filename pattern:

```bash
mf find "batman" # Finds files containing "batman"
mf find "*.mp4" # Finds all MP4 files
mf find "2023" # Finds files from 2023
```

4. **Play a file** from search results:

```bash
mf play 1 # Play first result
mf play next # Search results as playlist: play next result
mf play list # Send current search results to video player as a playlist
mf play # Play random file
```

5. **Find latest additions**:
```bash
mf new # Show 20 newest files
mf new 50 # Show 50 newest files
```

## Core Commands

- `mf find [pattern]` - Search for media files matching the glob pattern (supports `--plain`/`-p` for scriptable output)
- `mf new [n]` - Show latest additions (default: 20 files, supports `--plain`/`-p` for scriptable output)
- `mf play [index]` - Play a file by index, or random file if no index given
- `mf imdb <index>` - Open IMDB page for a media file
- `mf filepath <index>` - Print full path of a search result
- `mf version` - Print version information or run version check
- `mf cleanup` - Reset `mediafinder` by deleting all configuration and cache files
- `mf stats` - Show library statistics
- `mf last` - Show last search result index with the last played file highlighted
- `mf config` - Configure `mf`
- `mf cache` - Manage library cache (rebuild, show location, clear)
- `mf` or `mf --help` - Print help





## Scripting and Automation

The `find`, `new`, and `last` commands support plain text output for easy scripting and piping.

### Automatic Plain Mode (TTY Detection)

Plain mode is **automatically enabled** when output is piped or redirected - no flags needed:

```bash
# Automatically outputs plain text
mf find batman | head -5
mf new 10 | grep 1080p
mf last > results.txt

# Find and play first result
vlc "$(mf find batman | head -1)"

# Count search results
mf find 2023 | wc -l

# Process multiple files
mf find "*.mkv" | while read -r file; do
    echo "Processing: $file"
done
```

Interactive terminal usage displays rich formatted output, while piped/redirected commands automatically get plain text.

### Explicit Plain Mode

Use `--plain` or `-p` when you want plain output **directly in your terminal** without piping:

```bash
# View plain paths in terminal (useful for copying paths, etc.)
mf find batman --plain
mf new 5 -p
```

## Library Statistics
Use the `mf stats` command to print various statistics that describe your collection:

![](static/stats_example.png)

## RAR Archive Support

**On-demand extraction**: `mf` can extract and play video files from RAR archives. When you play a RAR file, it's automatically extracted to a temporary directory.

**Requirements**: Requires one of these extraction tools installed:
- `unrar` (official UnRAR utility)
- `unar` (The Unarchiver command-line tool)
- `7z` (7-Zip)
- `bsdtar` (libarchive with RAR support)
- WinRAR (Windows)

**Example usage**:
```bash
mf find "*.rar"      # Find RAR archives
mf play 1            # Automatically extracts and plays the video
```

**Note**: The `mf play list` command (playing multiple files as a playlist) is not supported for RAR archives. Play individual RAR files by index instead.

## Last search results

- `mf last` / `mf last show`- Show indexed results from the last file search (supports `--plain`/`-p` for scriptable output)
- `mf last file` - Print search result file location
- `mf last clear` - Clear last search results

Cached indices remain valid until you run another `find` or `new` command that overwrites the last search.

## Cache Management

**Configuration:**

- `mf config set cache_library <true/false>` - Turn library caching on or off
- `mf config set library_cache_interval <interval>` - Set auto-rebuild interval in seconds (default 86400 (1 day), 0 to disable)

**Manual control:**

- `mf cache rebuild` - Trigger a library cache rebuild
- `mf cache file` - Print cache location
- `mf cache clear` - Clear the cache
- `mf stats` - Show library statistics

## Configuration Management
`mf` can be configured directly on the command line:

- `mf config set <key> <values>` - Set configuration values
- `mf config add <key> <values>` - Add values to list settings
- `mf config remove <key> <values>` - Remove values from list settings
- `mf config get <key>` - Get configuration value
- `mf config list` - Show the current configuration
- `mf config edit` - Edit config file in default editor
- `mf config file` - Print config file location
- `mf config settings` - Print a table of all available settings

### Search Paths
Add multiple paths of a (scattered) collection:

```bash
mf config set search_paths "/movies" "/tv-shows" "/documentaries"
```

### Media Extensions
Control which file types are considered media files:

```
mf config set media_extensions ".mp4" ".mkv" ".avi" ".mov" ".wmv" ".rar"
```

By default, common video formats and `.rar` archives are included.

### Automatic wildcard wrapping
Toggle whether search patterns should be wrapped with wildcards automatically:

```bash
# Wraps search patterns with '*' if no wildcards (* ? [ ]) present.
# 'mf find batman' searches for files matching *batman*.
mf config set auto_wildcards true

# Does not wrap search patterns.
# 'mf find batman' searches for files exactly named batman.
mf config set auto_wildcards false
```

### Parallel search
Toggle whether file searches should be parallelized over search paths:

```bash
# Runs file searches concurrently over all paths defined in search_paths (potentially faster).
mf config set parallel_search true

# Runs file searches sequentially over all paths defined in search_paths. Use this if
# your search paths are on the same mechanical (but not solid state) hard drive to avoid
# disk thrashing.
mf config set parallel_search false
```

### Other Settings

- `video_player` (str): Video player to use (`vlc`, `mpv`, or `auto`). Default is `auto`, which prefers VLC with automatic fallback to mpv.
- `fullscreen_playback` (bool): If true, `mf play` launches the video player in fullscreen mode.
- `prefer_fd` (bool): Use the bundled `fd` scanner when possible. Automatically ignored for mtime-sorted searches (`mf new`) which always use the Python scanner.
- `display_paths` (bool): Turn filepath display in search results on or off.

### Editing the Config

`mf config edit` resolves an editor in this order:
1. `$VISUAL` or `$EDITOR`
2. Windows: Notepad++ if present else Notepad
3. POSIX: first available of `nano`, `vim`, `vi`

If no editor is found, it prints the path so you can edit manually.

### Input Normalization

- Boolean values accept: `true`, `false`, `yes`, `no`, `y`, `n`, `on`, `off`, `1`, `0` (case-insensitive; synonyms normalized to true/false).
- Media extensions are normalized to lowercase with a leading dot (`mkv` → `.mkv`).
- Paths are stored as absolute POSIX-style strings.

## Search Patterns

- Use quotes around patterns with wildcards to prevent shell expansion
- Patterns without wildcards are automatically wrapped: `batman` becomes `*batman*`
- Automatic wildcard wrapping only happens if the pattern contains none of: `* ? [ ]`.
- Examples:
  - `mf find "*.mp4"` - All MP4 files
  - `mf find batman` - Files containing "batman"
  - `mf find "*2023*1080p*"` - 2023 releases in 1080p
  - `mf find "s01e??"` - Season 1 episodes




## Integration Features

- **Video Player Integration**: Automatically launches VLC or mpv media player with configurable preference
- **IMDB Lookup**: Uses filename parsing to find matching IMDB entries
- **Smart Caching**: Search results are cached for quick index-based access
- **Cross-platform paths**: Handles Windows and Unix path conventions
- **Random Playback**: `mf play` (without index) randomly selects a file by scanning all configured paths (not just the last cached search).

## Performance

- Uses bundled `fd` binary for fast file scanning when possible
- Automatic fallback to Python scanning if `fd` unavailable
- Parallel scanning across multiple search paths

### Benchmarking `fd` vs pure python file scanning
- All tests with [`hyperfine`](https://github.com/sharkdp/hyperfine) and warm caches: `hyperfine --warmup 3 --runs 10 "mf find test"`.
- Media collection on two separate, mechanical USB drives in a file server on the local network, served via SMB for Windows and NFS for Linux clients, 16.3 TiB / 3540 files total.
- Tested on the file server itself with local file access as well as on a Linux and a Windows desktop with network file access.
- `mf find` can use both the `fd` scanner as well as the pure python one. First run was with the default setting `prefer_fd = true`. After that I switched to the python scanner via `mf config set prefer_fd false` and tested again.

| Platform | Pure Python (ms) | `fd` Scanner (ms) | Improvement |
|:---------|------------------:|----------------:|------------:|
| **Linux Server (local file access)** | 697.9 ± 17.1 | 443.5 ± 2.6 | **36% faster** |
| **Linux Desktop (NFS)** | 1,618.0 ± 28.0 | 478.2 ± 21.2 | **70% faster** |
| **Windows Desktop (SMB)** | 2,371.0 ± 90.0 | 1,601.0 ± 94.0 | **32% faster** |

- The `fd` scanner provides 32-70% performance improvement for search operations over pure python file scanning.


## Requirements

- Python 3.10+
- VLC or mpv media player (for `play` command)
- Internet connection (for IMDB lookup)
- **Optional**: RAR extraction tool (`unrar`, `unar`, `7z`, `bsdtar`, or WinRAR) for playing archived media files


## License

This project is licensed under the MIT License - see the [LICENSE-MIT](LICENSE-MIT) file for details.

### Third-Party Software

This package includes the [`fd`](https://github.com/sharkdp/fd) file finder binary, which is dual-licensed under **MIT OR Apache-2.0**.
Copyright (c) 2017-present the fd developers.

- MIT License: See `src/mf/bin/LICENSE-fd-MIT`
- Apache License 2.0: See `src/mf/bin/LICENSE-fd-APACHE`
