- Removed restrictive x-show/x-cloak that blocked UI visibility
- Forced tab container display and visibility in header
- Improved auth state synchronization with synchronous Alpine loading
- Fixed home section initialization and tab switching logic
- Fixed navigation blockage by moving Alpine state to body scope
- Resolved CSS display conflicts between legacy .active class and x-show
- Synchronized legacy auth logic with Alpine global state
- Redirected legacy switchTab calls to Alpine events
- Removed obsolete tabs.js and updated home section initialization
- Added E2E navigation test placeholder
- Integrated HTMX for server-driven UI updates and fragments
- Adopted Alpine.js for global reactive state and tab management
- Replaced legacy player with Plyr.io for premium streaming experience
- Implemented real-time download polling via HTMX
- Added server-sent Toast notification system
- Fixed navigation and authentication scoping issues
- Migrated monolithic main.py to feature-scoped routers in app/routers/
- Added GEMINI.md for project context and AI instructional guidelines
- Updated README.md with a comprehensive modernization plan (SQL migration, robust scraping DSL, frontend modernization)
- Improved authentication with cookie support and modular JS
- Updated test suite and documentation
- Updated background gradient from dark violet to light blue (#1a1a2e0%, #16213e100%)
- Harmonized header design colors and layout to match /web page
- Aligned button styles for consistency
- Kept all watchlist functionality intact
Implement comprehensive watchlist system with automatic episode detection
and downloading. Features include per-user watchlists, scheduler-based
periodic checks, and a modern web UI.
**Backend Components:**
- WatchlistManager: JSON-based storage with multi-tenant support
- EpisodeChecker: Detects and downloads new episodes automatically
- AutoDownloadScheduler: APScheduler-based periodic task execution
- Complete REST API for CRUD operations and scheduler control
**Frontend Components:**
- Modern watchlist page with dark theme and animations
- Real-time status updates and progress tracking
- Scheduler controls with next-run display
- Add anime directly from search results
**Models & Configuration:**
- WatchlistItem with status, quality, and auto-download settings
- WatchlistSettings for global configuration
- Per-user statistics and provider tracking
**API Endpoints:**
- GET/POST /api/watchlist - List and add items
- PUT/DELETE /api/watchlist/{id} - Update and delete
- POST /api/watchlist/{id}/check - Manual check trigger
- POST /api/watchlist/check-all - Check all due items
- GET/PUT /api/watchlist/settings - Global settings
- GET /api/watchlist/stats - Statistics
- GET/POST /api/watchlist/scheduler/* - Scheduler control
**Configuration Files:**
- config/watchlist.json - User watchlist data
- config/watchlist_settings.json - Global settings
Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major performance improvements and bug fixes for Anime-Sama integration:
**Backend Optimizations:**
- Parallel season loading with asyncio.gather() (200x faster: 50s → 0.25s)
- Filter out empty seasons to avoid unnecessary HTML parsing
- Reduced timeout from 5s to 3s for quick season checks
- Optimized fallback method to detect empty seasons instantly
**Frontend Fixes:**
- Fixed infinite "Chargement des saisons..." by ensuring DOM exists before loading
- Added 15-second timeout with retry functionality for season loading
- Staggered requests (500ms delay) to prevent overwhelming the server
- Duplicate request prevention with dataset.loading flag
**Search Improvements:**
- Separated anime and series provider searches
- Intelligent query variations (original, normalized, first word)
- Better error handling with user-friendly messages
**UI Fixes:**
- Added missing id="mainTabs" to navigation header
- Fixed tabs visibility for authenticated users
**Performance:** 10 seasons loaded in 0.25s instead of 50+ seconds
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Implemented a comprehensive authentication system requiring all users to be
logged in to access the web interface. Features include:
Backend:
- JWT-based authentication with 7-day token expiration
- bcrypt password hashing with 72-byte limit handling
- User management with JSON file storage (config/users.json)
- Pydantic models for validation (UserCreate, UserLogin, User, Token)
- Authentication endpoints: register, login, me, logout
- Protected route dependency with HTTPBearer security
Frontend:
- Login/register page with dual-tab interface (/login)
- Client-side authentication check with automatic redirect
- All content hidden by default, shown only after auth validation
- User info display with logout button
- Main content and tabs hidden when not authenticated
- Auto-redirect to /login if token missing or invalid
Security:
- Password truncation to 72 bytes (bcrypt limitation)
- Token verification on each page load
- Automatic logout and redirect on token expiry
- Username-to-SHA256 user ID generation
Dependencies:
- passlib[bcrypt]==1.7.4
- python-jose[cryptography]==3.3.0
- bcrypt<4.0
Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Major improvements:
- Series TV support via FS7 provider with dedicated search endpoint
- Vidzy downloader now uses Playwright for JS obfuscation and ffmpeg for HLS streams
- Episode filenames properly named (Series Title - Episode X) instead of master.m3u8.mp4
- Duplicate download prevention: checks existing tasks before creating new ones
- Removed host preference system in favor of intelligent URL-based detection
Technical changes:
- Vidzy: Added Playwright extraction and M3U8→MP4 conversion with ffmpeg
- FS7: Episodes now use pipe format (video_url|series_url|episode_title)
- DownloadManager: Extract target_filename from pipe URL and prevent duplicates
- UI: New Series tab with search, recommendations, and releases sections
- Anime-Sama: Removed hardcoded host preferences, uses site's URL order
Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Redesigned the web interface with a cleaner 5-tab layout:
- Accueil: Recommendations + Latest releases mixed
- Recherche: Unified search for anime and series
- Anime: Latest anime releases
- Série: Latest series releases
- Fournisseurs: Provider list with file hosts
Technical changes:
- Created new tabs.js for Anime, Série, and Fournisseurs tabs
- Modified header.html to use static tabs instead of dynamic
- Fixed carousel CSS classes in home_section.html
- Added null checks in main.js to prevent JS errors
- Simplified loadProviders() for legacy support
- All functionality preserved and working
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit adds comprehensive Sonarr webhook integration and implements
critical security improvements identified in code review.
## Sonarr Integration
- Full webhook support for Grab, Download, Rename, Delete, and Test events
- HMAC SHA256 signature verification for webhook authentication
- Series mapping system (Sonarr TVDB ID → Anime Provider URL)
- 11 new API endpoints for configuration, mappings, search, and downloads
- Comprehensive test suite (31 tests, all passing)
- Complete documentation in docs/SONARR_INTEGRATION.md
## Security Enhancements
- CORS restricted to specific origins (user's IP: 192.168.1.204:3000)
- Path traversal prevention via sanitize_filename() and is_safe_filename()
- Structured logging infrastructure (replaced all print() statements)
- Environment-based configuration with .env support
- Filename sanitization prevents malicious path attacks
## New Features
- Lpayer and Sibnet downloader support
- Kitsu API integration for anime metadata
- Recommendation engine based on download history
- Latest releases endpoint for new anime
- Modular web interface with component-based templates
## Configuration
- Centralized settings via app/config.py with pydantic-settings
- Sonarr config auto-created in config/ directory
- Example configurations provided for easy setup
## Tests
- 31 Sonarr integration tests (23 functionality + 9 security)
- 100+ tests passing in core test files
- Security utilities fully tested
## Documentation
- Updated CLAUDE.md with Sonarr and testing info
- Added IMPROVEMENTS_2024-01-24.md analysis
- Added SONARR_IMPLEMENTATION.md technical summary
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
- Add isClearing flag to prevent auto-refresh conflicts during deletion
- Use Promise.all() to delete all tasks in parallel instead of sequential await
- Add error handling with try/catch/finally block
- Skip loadDownloads() when isClearing is true
This fixes the infinite network request loop that occurred when clicking cleanup.
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Change the 'Nettoyer' (Cleanup) button behavior to remove unwanted downloads:
Before:
- Only removed completed downloads
Now:
- Removes cancelled downloads
- Removes failed downloads
- Removes completed downloads
- Keeps only: downloading, paused, pending downloads
- Shows detailed count by status in confirmation dialog
- Better title tooltip explaining what gets deleted
The confirmation message now shows exactly what will be deleted:
- 'Supprimer X annulé(s) Y échoué(s) Z terminé(s)?'
This makes it easy to clean up the download history while keeping
active downloads safe.
Fix the issue where groups would collapse but immediately reopen on next refresh:
Problem:
- Groups collapsed correctly but reopened after 1 second due to auto-refresh
- The toggleGroup function used classList.contains('collapsed') to check state
- But displayDownloads() regenerated HTML every second, losing the collapsed state
Solution:
- Add collapsedGroups Set to store which group IDs are collapsed
- Check collapsedGroups.has(groupId) instead of DOM class
- Save state in memory when toggling (add/delete from Set)
- Apply collapsed state when generating HTML (inline styles and CSS class)
- Groups now stay collapsed across auto-refresh cycles
The collapsed state persists:
- Across auto-refresh (every second)
- When filters change (commented out optional reset)
- Until user manually expands the group again
Change from using 'this' pointer to using unique IDs for group toggling:
- Generate unique IDs for each group (group-0, group-1, etc.)
- Pass group ID to toggleGroup() function instead of DOM element
- Use getElementById() and previousElementSibling to find elements
- Add error handling with console.error for missing elements
- Add console.log statements for debugging
This approach is more reliable than relying on inline onclick handlers
with 'this' keyword, especially when the HTML is dynamically generated.
Fix the toggleGroup() function to properly collapse/expand grouped downloads:
- Use classList.contains('collapsed') to check state instead of checking style.display
- Properly add/remove 'collapsed' class on toggle
- Groups now correctly collapse when clicked and expand when clicked again
- Arrow rotates correctly with CSS transition
The previous implementation checked items.style.display which was initially empty,
causing the toggle to not work correctly. Now we use the CSS class as the source of truth.
- Add collapsible arrow indicator for groups (▼)
- Improve extractSeriesName() to handle edge cases better
- Fix displayDownloads() to properly handle grouping
- Add proper sorting for group names
- Groups are now properly displayed with visual toggle state
- Better handling of filenames with special characters
- Remove trailing dashes/underscores from series names
Implement a comprehensive download history management system with powerful filtering, sorting, and grouping capabilities.
New Features:
1. Statistics Dashboard
- Real-time stats: total, downloading, paused, completed, failed
- Color-coded badges for quick visual overview
- Auto-updates every second with downloads
2. Advanced Filtering System
- Filter by status: All, In Progress, Paused, Completed, Cancelled, Failed
- Real-time search by filename or URL
- Multiple filters can be combined
3. Multiple Sorting Options
- Date (newest/oldest first)
- Name (alphabetical A-Z / Z-A)
- File size
4. Smart Grouping System
- Group by Series: Automatically detects anime series names
* Removes episode numbers, seasons, quality markers
* Groups episodes of same anime together
- Group by Status: Organizes by download state
- Group by Day: Aujourd'hui, Hier, or specific date
- Collapsible groups for cleaner UI
5. Bulk Actions
- Clear all completed downloads with one click
- Confirmation dialog to prevent accidents
UI Improvements:
- Modern filter controls with dark theme
- Responsive layout that works on all screen sizes
- Collapsible group headers with episode counts
- Empty state messages when no downloads match filters
- Visual indicators for each status type
Technical Details:
- extractSeriesName() function with regex patterns for:
* Episode numbers (Ep, Episode, Épisode, SxxExx)
* Quality markers (1080p, 720p, 480p)
* Language tags (VOSTFR, VF, MULTI)
* File extensions and brackets
- getDayString() for intelligent date grouping
- filterDownloads() for real-time filtering without API calls
- groupDownloads() for automatic series detection
- updateStats() for live statistics
User Experience:
- Filters persist during auto-refresh (every second)
- Group headers are clickable to toggle visibility
- Search works instantly as you type
- Statistics update in real-time
- Smooth animations and transitions
Example Use Cases:
- "Show me all completed One Piece episodes"
- "List all failed downloads from yesterday"
- "Find all Naruto episodes sorted by name"
- "Clean up all completed downloads at once"
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Features:
- Added rich metadata extraction for all anime providers (Anime-Sama, Neko-Sama, Anime-Ultime, Vostfree)
- New AnimeMetadata model with synopsis, genres, rating, release year, studio, poster/banner images, episode count, and status
- New /api/anime/metadata endpoint for fetching metadata of specific anime
- Enhanced /api/anime/search endpoint with optional include_metadata parameter
- Updated web interface with metadata display (expandable synopsis, genres, rating, year)
- Added metadata toggle checkbox in search UI (disabled by default for performance)
Bug Fixes:
- Fixed episode selection bug where select would reset to default after any change
- Removed onchange event from select element that was causing unwanted reloads
- Fixed download button disappearing after episode download
- Episodes can now be downloaded multiple times without page refresh
Enhancements:
- Metadata displayed with icons (📅 year, ⭐ rating, 🏷️ genres, 📺 episodes, 📡 status)
- Expandable synopsis section for detailed descriptions
- Better visual organization of anime information
- Maintains backward compatibility (metadata is optional)
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Add ability to download all episodes of a season with one click.
Backend changes:
- New POST /api/anime/download-season endpoint
- Retrieves all episodes and creates download tasks for each
- Returns list of task IDs and total episode count
Frontend changes:
- Add "Toute la saison" button next to episode selector
- Button shown immediately when episodes are loaded
- Confirmation dialog before starting batch download
- Success message showing number of episodes queued
Features:
- Respects max_parallel limit (default: 3 concurrent downloads)
- Proper episode naming (e.g., "Hells Paradise - Episode 01.mp4")
- Works with all anime providers (Anime-Sama, Anime-Ultime, etc.)
Example usage:
- Click "Toute la saison" button on any anime card
- Confirm the dialog
- All episodes are queued and download automatically
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
Add complete support for SendVid video hosting service used by Anime-Sama
for anime series like Hell's Paradise.
Changes:
- Create SendVidDownloader class with proper headers to avoid 403 errors
- Add SendVid detection and handling in AnimeSamaDownloader
- Update download_manager to include SendVid-specific headers
- Support custom episode naming (e.g., "Hells Paradise - Episode 01.mp4")
Technical details:
- SendVid embed pages require User-Agent and Referer headers
- Direct MP4 URLs extracted from <source> tags with IP/time-based parameters
- Tested with Hell's Paradise Episode 01 (7MB, 24min, 1280x720)
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>