feat: Add OpenScreen for directory input and validation

feat: Introduce poster rendering views with multiple engines

feat: Implement ASCII art poster renderer using PIL

feat: Create base class for poster renderers

feat: Add RichPixels renderer for high-quality terminal image display

feat: Implement Viu terminal image viewer renderer

feat: Add ProposedFilenameView for generating standardized filenames

feat: Create RenameConfirmScreen for renaming files with confirmation

feat: Implement SettingsScreen for configuring application settings

feat: Add custom PosterWidget for rendering poster images
This commit is contained in:
sha
2026-04-11 22:09:29 +03:00
parent 8274cb4e9f
commit 2e652ae58a
110 changed files with 193 additions and 214 deletions
+1 -1
View File
@@ -8,4 +8,4 @@ wheels/
# Virtual environments
.venv
# Test-generated files
renamer/test/datasets/sample_mediafiles/
src/test/datasets/sample_mediafiles/
+1 -1
View File
@@ -1,6 +1,6 @@
{
"python.testing.pytestArgs": [
"renamer"
"src"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true
+32 -32
View File
@@ -1,11 +1,11 @@
# Renamer Engineering Guide
# moma Engineering Guide
**Version**: 0.7.0-dev
**Last Updated**: 2026-01-01
**Python**: 3.11+
**Status**: Active Development
This is the comprehensive technical reference for the Renamer project. It contains all architectural information, implementation details, development workflows, and AI assistant instructions.
This is the comprehensive technical reference for the moma project. It contains all architectural information, implementation details, development workflows, and AI assistant instructions.
---
@@ -26,7 +26,7 @@ This is the comprehensive technical reference for the Renamer project. It contai
### Purpose
Renamer is a sophisticated Terminal User Interface (TUI) application for managing, viewing metadata, and renaming media files. Built with Python and the Textual framework.
moma is a sophisticated Terminal User Interface (TUI) application for managing, viewing metadata, and renaming media files. Built with Python and the Textual framework.
**Dual-Mode Operation**:
- **Technical Mode**: Detailed technical metadata (video tracks, audio streams, codecs, bitrates)
@@ -37,7 +37,7 @@ Renamer is a sophisticated Terminal User Interface (TUI) application for managin
- **Version**: 0.7.0-dev (in development)
- **Python**: 3.11+
- **License**: Not specified
- **Repository**: `/home/sha/bin/renamer`
- **Repository**: `/Users/sha/Developer/sha.dev/moma`
### Technology Stack
@@ -118,9 +118,9 @@ Renamer is a sophisticated Terminal User Interface (TUI) application for managin
## Core Components
### 1. Main Application (`renamer/app.py`)
### 1. Main Application (`src/app.py`)
**Class**: `RenamerApp(App)`
**Class**: `MomaApp(App)`
**Responsibilities**:
- TUI layout management (split view: file tree + details panel)
@@ -134,7 +134,7 @@ Renamer is a sophisticated Terminal User Interface (TUI) application for managin
- Dual-mode support (technical/catalog)
- Real-time metadata display
### 2. Service Layer (`renamer/services/`)
### 2. Service Layer (`src/services/`)
#### FileTreeService (`file_tree_service.py`)
- Directory scanning and validation
@@ -166,7 +166,7 @@ Renamer is a sophisticated Terminal User Interface (TUI) application for managin
- Callback-based rename with success/error handlers
- Markup tag stripping
### 3. Extractor System (`renamer/extractors/`)
### 3. Extractor System (`src/extractors/`)
#### Base Protocol (`base.py`)
```python
@@ -232,7 +232,7 @@ year = extractor.get("year", source="Filename") # Force specific source
- Returns None or empty collections
- Safe final fallback in extractor chain
### 4. Formatter System (`renamer/formatters/`)
### 4. Formatter System (`src/formatters/`)
#### Base Classes (`base.py`)
- `Formatter`: Base ABC with abstract `format()` method
@@ -271,7 +271,7 @@ result = FormatterApplier.apply_formatters(1024, formatters)
- **SpecialInfoFormatter**: Edition/source formatting
- **TextFormatter**: Text styling utilities
### 5. Utility Modules (`renamer/utils/`)
### 5. Utility Modules (`src/utils/`)
#### PatternExtractor (`pattern_utils.py`)
**Centralized regex pattern matching**:
@@ -320,7 +320,7 @@ langs = extractor.extract_from_brackets("[2xUKR_ENG]")
3. Closest height match
4. Non-standard quality indicator detection
### 6. Constants (`renamer/constants/`)
### 6. Constants (`src/constants/`)
**Modular organization** (8 files):
@@ -335,12 +335,12 @@ langs = extractor.extract_from_brackets("[2xUKR_ENG]")
**Backward Compatibility**: All constants exported via `__init__.py`
### 7. Cache Subsystem (`renamer/cache/`)
### 7. Cache Subsystem (`src/cache/`)
**Unified, modular architecture**:
```
renamer/cache/
src/cache/
├── __init__.py # Exports and convenience functions
├── core.py # Core Cache class (thread-safe with RLock)
├── types.py # CacheEntry, CacheStats TypedDicts
@@ -386,16 +386,16 @@ Access via Ctrl+P:
- Safe for concurrent extractor access
- Memory cache synchronized with file cache
### 8. UI Screens (`renamer/screens.py`)
### 8. UI Screens (`src/screens.py`)
1. **OpenScreen**: Directory selection dialog with validation
2. **HelpScreen**: Comprehensive help with key bindings
3. **RenameConfirmScreen**: File rename confirmation with error handling
4. **SettingsScreen**: Settings configuration interface
### 9. Settings System (`renamer/settings.py`)
### 9. Settings System (`src/settings.py`)
**Configuration**: `~/.config/renamer/config.json`
**Configuration**: `~/.config/moma/config.json`
**Options**:
```json
@@ -420,30 +420,30 @@ Automatic save/load with defaults.
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and sync
cd /home/sha/bin/renamer
cd /Users/sha/Developer/sha.dev/moma
uv sync
# Install dev dependencies
uv sync --extra dev
# Run from source
uv run python renamer/main.py [directory]
uv run python src/main.py [directory]
```
### Development Commands
```bash
# Run installed version
uv run renamer [directory]
uv run moma [directory]
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --cov=renamer
uv run pytest --cov=src
# Type checking
uv run mypy renamer/extractors/default_extractor.py
uv run mypy src/extractors/default_extractor.py
# Version management
uv run bump-version # Increment patch version
@@ -460,7 +460,7 @@ uv tool install .
```bash
# Enable formatter logging
FORMATTER_LOG=1 uv run renamer /path/to/directory
FORMATTER_LOG=1 uv run moma /path/to/directory
# Creates formatter.log with detailed call traces
```
@@ -471,7 +471,7 @@ FORMATTER_LOG=1 uv run renamer /path/to/directory
### Test Organization
```
renamer/test/
src/test/
├── datasets/ # Test data
│ ├── filenames/
│ │ ├── filename_patterns.json # 46 test cases
@@ -504,7 +504,7 @@ renamer/test/
```bash
# Generate 46 test files from filename_patterns.json
uv run python renamer/test/fill_sample_mediafiles.py
uv run python src/test/fill_sample_mediafiles.py
```
### Test Fixtures
@@ -524,13 +524,13 @@ file_path = get_test_file_path("movie.mkv")
uv run pytest
# Specific test file
uv run pytest renamer/test/test_services.py
uv run pytest src/test/test_services.py
# With verbose output
uv run pytest -xvs
# With coverage
uv run pytest --cov=renamer --cov-report=html
uv run pytest --cov=src --cov-report=html
```
---
@@ -765,7 +765,7 @@ uv run release # Bump + sync + build
### Release Checklist
- [ ] All tests passing: `uv run pytest`
- [ ] Type checking passes: `uv run mypy renamer/`
- [ ] Type checking passes: `uv run mypy src/`
- [ ] Documentation updated (CHANGELOG.md, README.md)
- [ ] Version bumped in `pyproject.toml`
- [ ] Dependencies synced: `uv sync`
@@ -777,8 +777,8 @@ uv run release # Bump + sync + build
```
dist/
├── renamer-0.7.0-py3-none-any.whl # Wheel distribution
└── renamer-0.7.0.tar.gz # Source distribution
├── moma-0.7.0-py3-none-any.whl # Wheel distribution
└── moma-0.7.0.tar.gz # Source distribution
```
---
@@ -788,7 +788,7 @@ dist/
### TMDB API
**Configuration**:
- API key stored in `renamer/secrets.py`
- API key stored in `src/secrets.py`
- Base URL: `https://api.themoviedb.org/3/`
- Image base URL for poster downloads
@@ -801,7 +801,7 @@ dist/
**Caching**:
- API responses cached for 6 hours
- Posters cached for 30 days
- Cache location: `~/.cache/renamer/tmdb/`, `~/.cache/renamer/posters/`
- Cache location: `~/.cache/moma/tmdb/`, `~/.cache/moma/posters/`
---
@@ -941,4 +941,4 @@ Title (Year) [Resolution Source Edition].ext
**Last Updated**: 2026-01-01
**Maintainer**: sha
**For**: AI Assistants and Developers
**Repository**: `/home/sha/bin/renamer`
**Repository**: `/Users/sha/Developer/sha.dev/moma`
+3 -3
View File
@@ -1,6 +1,6 @@
# Changelog
All notable changes to the Renamer project are documented in this file.
All notable changes to the moma project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
@@ -114,7 +114,7 @@ This development version represents a significant refactoring effort focused on
- Dataset loaders in `conftest.py`
#### Changed
- **Test Organization**: Consolidated test data into `renamer/test/datasets/`
- **Test Organization**: Consolidated test data into `src/test/datasets/`
- **Total Tests**: 560 tests (1 skipped), all passing
---
@@ -141,7 +141,7 @@ This development version represents a significant refactoring effort focused on
#### Cache System
- **Cache key format changed**: Old cache files are invalid
- **Migration**: Users should clear cache: `rm -rf ~/.cache/renamer/`
- **Migration**: Users should clear cache: `rm -rf ~/.cache/moma/`
- **Impact**: No data loss, just cache miss on first run after upgrade
#### Dependencies
+1 -1
View File
@@ -22,7 +22,7 @@ Please read **[ENGINEERING_GUIDE.md](ENGINEERING_GUIDE.md)** for complete projec
```bash
uv sync --extra dev # Setup
uv run pytest # Test
uv run renamer [dir] # Run
uv run moma [dir] # Run
```
## Essential Principles
+10 -10
View File
@@ -5,7 +5,7 @@
> **📘 For complete development documentation, see [ENGINEERING_GUIDE.md](ENGINEERING_GUIDE.md)**
Quick reference for developers working on the Renamer project.
Quick reference for developers working on the moma project.
---
@@ -16,7 +16,7 @@ Quick reference for developers working on the Renamer project.
curl -LsSf https://astral.sh/uv/install.sh | sh
# Clone and setup
cd /home/sha/bin/renamer
cd /Users/sha/Developer/sha.dev/moma
uv sync --extra dev
```
@@ -26,16 +26,16 @@ uv sync --extra dev
```bash
# Run from source
uv run renamer [directory]
uv run moma [directory]
# Run tests
uv run pytest
# Run with coverage
uv run pytest --cov=renamer
uv run pytest --cov=src
# Type check
uv run mypy renamer/
uv run mypy src/
# Version bump
uv run bump-version
@@ -53,13 +53,13 @@ uv build
```bash
# Enable detailed logging
FORMATTER_LOG=1 uv run renamer /path/to/directory
FORMATTER_LOG=1 uv run moma /path/to/directory
# Check logs
cat formatter.log
# Clear cache
rm -rf ~/.cache/renamer/
rm -rf ~/.cache/moma/
```
---
@@ -71,13 +71,13 @@ rm -rf ~/.cache/renamer/
uv run pytest
# Specific file
uv run pytest renamer/test/test_services.py
uv run pytest src/test/test_services.py
# Verbose
uv run pytest -xvs
# Generate sample files
uv run python renamer/test/fill_sample_mediafiles.py
uv run python src/test/fill_sample_mediafiles.py
```
See [ENGINEERING_GUIDE.md - Testing Strategy](ENGINEERING_GUIDE.md#testing-strategy)
@@ -97,7 +97,7 @@ uv run release
uv tool install .
# 4. Manual testing
uv run renamer /path/to/test/media
uv run moma /path/to/test/media
```
See [ENGINEERING_GUIDE.md - Release Process](ENGINEERING_GUIDE.md#release-process)
+18 -18
View File
@@ -1,6 +1,6 @@
# Installation Guide for Renamer
# Installation Guide for moma
Renamer is a terminal-based media file renamer and metadata viewer built with Python and Textual.
moma is a terminal-based media file renamer and metadata viewer built with Python and Textual.
## Prerequisites
@@ -11,7 +11,7 @@ Renamer is a terminal-based media file renamer and metadata viewer built with Py
### Method 1: UV Tool Install (Recommended)
This is the easiest way to install and use Renamer globally on your system.
This is the easiest way to install and use moma globally on your system.
#### Install UV (if not already installed)
```bash
@@ -22,22 +22,22 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
powershell -c "irm https://astral.sh/uv/install.sh | iex"
```
#### Install Renamer
#### Install moma
```bash
# One-command install from remote wheel
uv tool install https://git.shadoll.dev/sha/renamer/raw/branch/main/dist/renamer-0.2.4-py3-none-any.whl
uv tool install https://github.com/shadoll/moma/raw/branch/main/dist/moma-0.2.4-py3-none-any.whl
# Or from local wheel (if downloaded)
uv tool install dist/renamer-0.2.4-py3-none-any.whl
uv tool install dist/moma-0.2.4-py3-none-any.whl
# Or from PyPI (when published)
uv tool install renamer
uv tool install moma
```
#### Usage
```bash
renamer # Scan current directory
renamer /path/to/directory # Scan specific directory
moma # Scan current directory
moma /path/to/directory # Scan specific directory
```
### Method 2: pip Install from Wheel
@@ -46,10 +46,10 @@ If you have the wheel file, you can install it with pip.
```bash
# Install the wheel
pip install dist/renamer-0.2.0-py3-none-any.whl
pip install dist/moma-0.2.0-py3-none-any.whl
# Or install globally (may require sudo)
sudo pip install dist/renamer-0.2.0-py3-none-any.whl
sudo pip install dist/moma-0.2.0-py3-none-any.whl
```
### Method 3: Development Installation
@@ -59,7 +59,7 @@ For development or if you want to run from source:
#### Clone and Setup
```bash
git clone <repository-url>
cd renamer
cd moma
# Install dependencies
uv sync
@@ -120,12 +120,12 @@ python3 main.py /path/to/directory
After installation, verify it works:
```bash
renamer --help
moma --help
# or
python3 main.py --help
```
You should see the help text for the Renamer application.
You should see the help text for the moma application.
## Troubleshooting
@@ -158,17 +158,17 @@ If you encounter issues:
### UV Tool Uninstall
```bash
uv tool uninstall renamer
uv tool uninstall moma
```
### pip Uninstall
```bash
pip uninstall renamer
pip uninstall moma
```
### Development Uninstall
```bash
uv tool uninstall renamer
uv tool uninstall moma
# Remove the cloned directory if desired
```</content>
<parameter name="filePath">/home/sha/bin/renamer/INSTALL.md
<parameter name="filePath">/Users/sha/Developer/sha.dev/moma/INSTALL.md
+7 -8
View File
@@ -27,8 +27,8 @@ A powerful Terminal User Interface (TUI) for managing media collections. View de
# Install UV
curl -LsSf https://astral.sh/uv/install.sh | sh
# Install Renamer
cd /path/to/renamer
# Install moma
cd /Users/sha/Developer/sha.dev/moma
uv sync
uv tool install .
```
@@ -39,10 +39,9 @@ See [INSTALL.md](INSTALL.md) for detailed installation instructions.
```bash
# Scan current directory
renamer
moma
# Scan specific directory
renamer /path/to/media
moma /path/to/media
```
---
@@ -97,7 +96,7 @@ Toggle with `m` key.
## Configuration
**Location**: `~/.config/renamer/config.json`
**Location**: `~/.config/moma/config.json`
```json
{
@@ -124,7 +123,7 @@ Access via `Ctrl+S` or edit file directly.
## Project Structure
```
renamer/
src/
├── app.py # Main TUI application
├── services/ # Business logic
├── extractors/ # Metadata extraction
@@ -148,7 +147,7 @@ uv sync --extra dev
uv run pytest
# Run from source
uv run renamer [directory]
uv run moma [directory]
```
See [DEVELOP.md](DEVELOP.md) for development documentation.
@@ -1,11 +1,11 @@
# Renamer - Refactoring Roadmap
# moma - Refactoring Roadmap
**Version**: 0.7.0-dev
**Last Updated**: 2026-01-01
> **📋 For completed work, see [CHANGELOG.md](CHANGELOG.md)**
This document tracks the future refactoring plan for Renamer v0.7.0+.
This document tracks the future refactoring plan for moma v0.7.0+.
---
@@ -71,7 +71,7 @@ class ProposedNameFormatter:
- No coupling to extractor instance
**Files to Modify**:
- `renamer/formatters/proposed_name_formatter.py`
- `src/formatters/proposed_name_formatter.py`
- Update all usages in `app.py`, `screens.py`, etc.
---
@@ -79,33 +79,33 @@ class ProposedNameFormatter:
#### 3.6.2 Clean Up Decorators Directory
**Status**: NOT STARTED
**Current Issue**: `renamer/decorators/` directory contains legacy `caching.py` file that's no longer used. All cache decorators were moved to `renamer/cache/decorators.py` in Phase 1.
**Current Issue**: `src/decorators/` directory contains legacy `caching.py` file that's no longer used. All cache decorators were moved to `src/cache/decorators.py` in Phase 1.
**Current Structure**:
```
renamer/decorators/
src/decorators/
├── caching.py # ⚠️ LEGACY - Remove
└── __init__.py # Import from renamer.cache
└── __init__.py # Import from src.cache
```
**Actions**:
1. **Verify no direct imports** of `renamer.decorators.caching`
2. **Remove `caching.py`** - All functionality now in `renamer/cache/decorators.py`
3. **Keep `__init__.py`** for backward compatibility (imports from `renamer.cache`)
4. **Update any direct imports** to use `from renamer.cache import cached_method`
1. **Verify no direct imports** of `src.decorators.caching`
2. **Remove `caching.py`** - All functionality now in `src/cache/decorators.py`
3. **Keep `__init__.py`** for backward compatibility (imports from `src.cache`)
4. **Update any direct imports** to use `from src.cache import cached_method`
**Verification**:
```bash
# Check for direct imports of old caching module
grep -r "from renamer.decorators.caching" renamer/
grep -r "import renamer.decorators.caching" renamer/
grep -r "from src.decorators.caching" src/
grep -r "import src.decorators.caching" src/
# Should only find imports from __init__.py that re-export from renamer.cache
# Should only find imports from __init__.py that re-export from src.cache
```
**Benefits**:
- Removes dead code
- Clarifies that all caching is in `renamer/cache/`
- Clarifies that all caching is in `src/cache/`
- Maintains backward compatibility via `__init__.py`
---
@@ -142,7 +142,7 @@ grep -r "import renamer.decorators.caching" renamer/
- `proposed_name_formatter.py`
- All specialized formatters
#### 4.3 Integrate RenamerApp with Services
#### 4.3 Integrate MomaApp with Services
- Refactor `app.py` to use service layer
- Replace direct extractor calls with `MetadataService`
- Replace direct file operations with `RenameService`
@@ -357,7 +357,7 @@ grep -r "import renamer.decorators.caching" renamer/
### Phase 4 Complete When:
- [ ] All extractors implement Protocol
- [ ] All formatters use base classes
- [ ] RenamerApp uses services exclusively
- [ ] MomaApp uses services exclusively
- [ ] No direct business logic in UI
- [ ] All tests passing
- [ ] No performance regression
+2 -2
View File
@@ -1,4 +1,4 @@
# Renamer - Future Tasks
# moma - Future Tasks
**Version**: 0.7.0-dev
**Last Updated**: 2026-01-01
@@ -18,7 +18,7 @@ This file tracks future feature enhancements and improvements.
- [ ] **Phase 4: Refactor to New Architecture**
- Refactor existing extractors to use Protocol
- Refactor existing formatters to use base classes
- Integrate RenamerApp with services
- Integrate MomaApp with services
- Update all imports and dependencies
- See [REFACTORING_PROGRESS.md](REFACTORING_PROGRESS.md) for details
+5 -5
View File
@@ -1,5 +1,5 @@
[project]
name = "renamer"
name = "moma"
version = "0.8.11"
description = "Terminal-based media file renamer and metadata viewer"
readme = "README.md"
@@ -21,16 +21,16 @@ dev = [
]
[project.scripts]
renamer = "renamer.main:main"
bump-version = "renamer.bump:main"
release = "renamer.release:main"
moma = "src.main:main"
bump-version = "src.bump:main"
release = "src.release:main"
[tool.uv]
package = true
[tool.pytest.ini_options]
addopts = "--strict-markers"
testpaths = ["renamer/test"]
testpaths = ["src/test"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
-7
View File
@@ -1,7 +0,0 @@
# Renamer package
from .app import RenamerApp
from .extractors.extractor import MediaExtractor
from .views import MediaPanelView, ProposedFilenameView
__all__ = ['RenamerApp', 'MediaExtractor', 'MediaPanelView', 'ProposedFilenameView']
-2
View File
@@ -1,2 +0,0 @@
TMDB_API_KEY="19af49e6d33ad124b3c3dfbf1114b714"
TMDB_ACCESS_TOKEN="eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiIxOWFmNDllNmQzM2FkMTI0YjNjM2RmYmYxMTE0YjcxNCIsIm5iZiI6MTQxNDMzODgxOS4zODMwMDAxLCJzdWIiOiI1NDRkMTkwM2MzYTM2ODcyZTAwMDI3ZmIiLCJzY29wZXMiOlsiYXBpX3JlYWQiXSwidmVyc2lvbiI6MX0.O4xnCs8Z7PJ_BQS6ZdU9yvvZ38Z8EsBBmjrYqvIY0aQ"
+7
View File
@@ -0,0 +1,7 @@
# moma package
from .app import MomaApp
from .extractors.extractor import MediaExtractor
from .views import MediaPanelView, ProposedFilenameView
__all__ = ['MomaApp', 'MediaExtractor', 'MediaPanelView', 'ProposedFilenameView']
+1 -1
View File
@@ -79,7 +79,7 @@ class AppCommandProvider(Provider):
)
class RenamerApp(App):
class MomaApp(App):
CSS = """
/* Default technical mode: 2 columns */
#left {
View File
+3 -3
View File
@@ -1,4 +1,4 @@
"""Unified caching subsystem for Renamer.
"""Unified caching subsystem for moma.
This module provides a flexible caching system with:
- Multiple cache key generation strategies
@@ -9,7 +9,7 @@ This module provides a flexible caching system with:
Usage Examples:
# Using decorators
from renamer.cache import cached, cached_api
from src.cache import cached, cached_api
class MyExtractor:
def __init__(self, file_path, cache, settings):
@@ -28,7 +28,7 @@ Usage Examples:
return api_call(movie_id)
# Using cache manager
from renamer.cache import Cache, CacheManager
from src.cache import Cache, CacheManager
cache = Cache()
manager = CacheManager(cache)
+2 -2
View File
@@ -30,7 +30,7 @@ class Cache:
"""Initialize cache with optional custom directory (only once).
Args:
cache_dir: Optional cache directory path. Defaults to ~/.cache/renamer/
cache_dir: Optional cache directory path. Defaults to ~/.cache/moma/
"""
# Only initialize once
if self._initialized:
@@ -38,7 +38,7 @@ class Cache:
# Always use the default cache dir to avoid creating cache in scan dir
if cache_dir is None:
cache_dir = Path.home() / ".cache" / "renamer"
cache_dir = Path.home() / ".cache" / "moma"
self.cache_dir = cache_dir
self.cache_dir.mkdir(parents=True, exist_ok=True)
self._memory_cache: Dict[str, Dict[str, Any]] = {} # In-memory cache for faster access
View File
@@ -1,4 +1,4 @@
"""Constants package for Renamer.
"""Constants package for moma.
This package contains constants split into logical modules:
- media_constants.py: Media type definitions (MEDIA_TYPES)
@@ -1,5 +1,5 @@
from .text_formatter import TextFormatter
from renamer.views.posters import AsciiPosterRenderer, ViuPosterRenderer, RichPixelsPosterRenderer
from src.views.posters import AsciiPosterRenderer, ViuPosterRenderer, RichPixelsPosterRenderer
from typing import Union
import os
@@ -1,4 +1,4 @@
"""Singleton logging configuration for the renamer application.
"""Singleton logging configuration for the moma application.
This module provides centralized logging configuration that is initialized
once and used throughout the application.
+3 -3
View File
@@ -1,12 +1,12 @@
import argparse
from renamer.app import RenamerApp
from src.app import MomaApp
def main():
parser = argparse.ArgumentParser(description="Media file renamer")
parser = argparse.ArgumentParser(description="moma - media file manager")
parser.add_argument("directory", nargs="?", default=".", help="Directory to scan")
args = parser.parse_args()
app = RenamerApp(args.directory)
app = MomaApp(args.directory)
app.run()
@@ -1,4 +1,4 @@
"""Services package - business logic layer for the Renamer application.
"""Services package - business logic layer for the moma application.
This package contains service classes that encapsulate business logic and
coordinate between different components. Services provide a clean separation
@@ -15,7 +15,7 @@ import re
from pathlib import Path
from typing import Optional, List, Dict, Tuple
from renamer.extractors.extractor import MediaExtractor
from src.extractors.extractor import MediaExtractor
logger = logging.getLogger(__name__)
@@ -9,7 +9,7 @@ from pathlib import Path
from typing import Optional, Callable
from rich.markup import escape
from renamer.constants import MEDIA_TYPES
from src.constants import MEDIA_TYPES
logger = logging.getLogger(__name__)
@@ -13,12 +13,12 @@ from typing import Optional, Callable
from concurrent.futures import ThreadPoolExecutor, Future
from threading import Lock
from renamer.cache import Cache
from renamer.settings import Settings
from renamer.extractors.extractor import MediaExtractor
from renamer.views import MediaPanelView, ProposedFilenameView
from renamer.formatters.catalog_formatter import CatalogFormatter
from renamer.formatters.text_formatter import TextFormatter
from src.cache import Cache
from src.settings import Settings
from src.extractors.extractor import MediaExtractor
from src.views import MediaPanelView, ProposedFilenameView
from src.formatters.catalog_formatter import CatalogFormatter
from src.formatters.text_formatter import TextFormatter
logger = logging.getLogger(__name__)
@@ -13,8 +13,8 @@ import re
from pathlib import Path
from typing import Optional, Callable
from renamer.extractors.extractor import MediaExtractor
from renamer.views import ProposedFilenameView
from src.extractors.extractor import MediaExtractor
from src.views import ProposedFilenameView
logger = logging.getLogger(__name__)
+1 -1
View File
@@ -37,7 +37,7 @@ class Settings:
return
if config_dir is None:
config_dir = Path.home() / ".config" / "renamer"
config_dir = Path.home() / ".config" / "moma"
self.config_dir = config_dir
self.config_file = self.config_dir / "config.json"
self._settings = self.DEFAULTS.copy()
@@ -1,6 +1,6 @@
# Test Datasets
This directory contains organized test data for the Renamer test suite.
This directory contains organized test data for the Moma test suite.
## Directory Structure
@@ -17,7 +17,7 @@ datasets/
```
**Note**: The `sample_mediafiles/` directory is generated by running `fill_sample_mediafiles.py`
and is excluded from git. Run `uv run python renamer/test/fill_sample_mediafiles.py` to create these files.
and is excluded from git. Run `uv run python src/test/fill_sample_mediafiles.py` to create these files.
## Dataset Files
@@ -157,7 +157,7 @@ from pathlib import Path
def load_dataset(dataset_name):
"""Load a dataset file from datasets directory."""
from renamer.test.conftest import load_dataset
from src.test.conftest import load_dataset
return load_dataset(dataset_name)
# Load filename patterns
@@ -173,7 +173,7 @@ frame_tests = load_dataset("frame_class_tests")
```python
import pytest
from pathlib import Path
from renamer.extractors.filename_extractor import FilenameExtractor
from src.extractors.filename_extractor import FilenameExtractor
# Load test cases at module level
def load_test_cases():
@@ -224,7 +224,7 @@ def test_cyrillic_titles(load_filename_patterns):
### Using Sample Files
```python
from renamer.test.conftest import get_test_file_path
from src.test.conftest import get_test_file_path
# Get path to a sample file from the dataset
sample_file = get_test_file_path("Movie Title (2020) BDRip [1080p,ukr,eng].mkv")
@@ -242,12 +242,12 @@ These files are generated automatically and should not be committed to git.
**Generate files:**
```bash
# From project root
uv run python renamer/test/fill_sample_mediafiles.py
uv run python src/test/fill_sample_mediafiles.py
```
**Output:**
```
Creating sample media files in: /path/to/renamer/test/datasets/sample_mediafiles
Creating sample media files in: /path/to/src/test/datasets/sample_mediafiles
Test cases in dataset: 46
✅ Created: Movie Title (2020) BDRip [1080p,ukr,eng].mkv
@@ -848,24 +848,6 @@
"category": "edge_cases",
"description": "No year present"
},
{
"testname": "edge-multipart-001",
"filename": "Золотє теля.pt1.(1968).[SD,ukr].avi",
"expected": {
"order": "1",
"title": "Золотє теля",
"year": "1968",
"source": null,
"frame_class": null,
"hdr": null,
"movie_db": null,
"special_info": null,
"audio_langs": "rus",
"extension": "avi"
},
"category": "edge_cases",
"description": "Multi-part film (pt1)"
},
{
"testname": "edge-remastered-001",
"filename": "Apple 1984 (1984) [Remastered] [2160p,eng] [imdbid-tt4227346].mkv",
@@ -3,7 +3,7 @@
Script to generate empty media test files from filename_patterns.json dataset.
Usage:
uv run python renamer/test/fill_sample_mediafiles.py
uv run python src/test/fill_sample_mediafiles.py
This script:
1. Creates the sample_mediafiles directory if it doesn't exist
@@ -90,7 +90,7 @@ def create_sample_mediafiles():
print("✅ Sample media files generation complete!")
print()
print("Next steps:")
print("1. Add 'renamer/test/datasets/sample_mediafiles/' to .gitignore")
print("1. Add 'src/test/datasets/sample_mediafiles/' to .gitignore")
print("2. Run tests to verify files are accessible")
return True
@@ -2,7 +2,7 @@
import pytest
from pathlib import Path
from renamer.cache import (
from src.cache import (
Cache,
CacheManager,
cached,
@@ -239,13 +239,13 @@ class TestCachePackageImports:
"""Test cache package import paths."""
def test_import_cache_from_package(self):
"""Test importing Cache from renamer.cache package."""
from renamer.cache import Cache as PackageCache
"""Test importing Cache from src.cache package."""
from src.cache import Cache as PackageCache
assert PackageCache is not None
def test_import_decorators_from_cache(self):
"""Test importing decorators from renamer.cache."""
from renamer.cache import cached_method, cached, cached_api, cached_property
"""Test importing decorators from src.cache."""
from src.cache import cached_method, cached, cached_api, cached_property
assert cached_method is not None
assert cached is not None
assert cached_api is not None
@@ -253,7 +253,7 @@ class TestCachePackageImports:
def test_create_cache_convenience_function(self):
"""Test the create_cache convenience function."""
from renamer.cache import create_cache
from src.cache import create_cache
cache, manager = create_cache()
assert cache is not None
assert manager is not None
@@ -1,7 +1,7 @@
"""Tests for formatter decorators."""
import pytest
from renamer.formatters import (
from src.formatters import (
date_decorators,
special_info_decorators,
text_decorators,
@@ -1,6 +1,6 @@
import pytest
from pathlib import Path
from renamer.extractors.fileinfo_extractor import FileInfoExtractor
from src.extractors.fileinfo_extractor import FileInfoExtractor
class TestFileInfoExtractor:
@@ -7,7 +7,7 @@ import json
from pathlib import Path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from renamer.extractors.filename_extractor import FilenameExtractor
from src.extractors.filename_extractor import FilenameExtractor
def test_detection():
# Load test cases from new dataset location
@@ -4,7 +4,7 @@ Tests for base formatter classes and concrete formatter implementations.
"""
import pytest
from renamer.formatters import (
from src.formatters import (
Formatter,
DataFormatter,
MarkupFormatter,
@@ -1,7 +1,7 @@
import pytest
from pathlib import Path
from unittest.mock import MagicMock
from renamer.extractors.mediainfo_extractor import MediaInfoExtractor
from src.extractors.mediainfo_extractor import MediaInfoExtractor
import json
@@ -8,7 +8,7 @@ import sys
import os
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
from renamer.extractors.mediainfo_extractor import MediaInfoExtractor
from src.extractors.mediainfo_extractor import MediaInfoExtractor
from pathlib import Path
# Load test cases from dataset using context manager
@@ -1,7 +1,7 @@
import pytest
import json
from pathlib import Path
from renamer.extractors.metadata_extractor import MetadataExtractor
from src.extractors.metadata_extractor import MetadataExtractor
class TestMetadataExtractor:
@@ -2,7 +2,7 @@
import pytest
from pathlib import Path
from renamer.views import ProposedFilenameView
from src.views import ProposedFilenameView
class TestProposedFilenameView:
@@ -9,9 +9,9 @@ from unittest.mock import Mock, MagicMock, patch
import tempfile
import os
from renamer.services import FileTreeService, MetadataService, RenameService
from renamer.cache import Cache
from renamer.settings import Settings
from src.services import FileTreeService, MetadataService, RenameService
from src.cache import Cache
from src.settings import Settings
class TestFileTreeService:
@@ -4,7 +4,7 @@ Tests for LanguageCodeExtractor, PatternExtractor, and FrameClassMatcher.
"""
import pytest
from renamer.utils import LanguageCodeExtractor, PatternExtractor, FrameClassMatcher
from src.utils import LanguageCodeExtractor, PatternExtractor, FrameClassMatcher
class TestLanguageCodeExtractor:
@@ -1,4 +1,4 @@
"""Utils package - shared utility functions for the Renamer application.
"""Utils package - shared utility functions for the moma application.
This package contains utility modules that provide common functionality
used across multiple parts of the application. This eliminates code
@@ -7,7 +7,7 @@ This module provides centralized logic for determining frame class
import logging
from typing import Optional
from renamer.constants import FRAME_CLASSES
from src.constants import FRAME_CLASSES
logger = logging.getLogger(__name__)
@@ -9,7 +9,7 @@ import re
from typing import Optional, Dict
from datetime import datetime
from renamer.constants import MOVIE_DB_DICT
from src.constants import MOVIE_DB_DICT
logger = logging.getLogger(__name__)
@@ -7,12 +7,12 @@ class HelpScreen(Screen):
def compose(self):
try:
from importlib.metadata import version
app_version = version("renamer")
app_version = version("moma")
except Exception:
app_version = "unknown"
help_text = f"""
Media File Renamer v{app_version}
moma v{app_version}
A powerful tool for analyzing and renaming media files with intelligent metadata extraction.

Some files were not shown because too many files have changed in this diff Show More