Files
ohm_streaming/templates/components/anime_provider_tab.html
T
root 1fe7392063 feat: Complete Sonarr integration with security enhancements
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>
2026-01-24 21:25:47 +00:00

33 lines
1.6 KiB
HTML

{# Template pour un onglet de provider anime spécifique #}
{# Variables disponibles: provider_id, provider_info #}
<div id="tab-anime-{{ provider_id }}" class="tab-content">
<div class="url-form">
<div class="anime-input-group">
<input
type="text"
id="searchInput-{{ provider_id }}"
placeholder="Rechercher un anime sur {{ provider_info.name }}..."
onkeypress="if(event.key === 'Enter') searchAnimeProvider('{{ provider_id }}')"
>
<select id="langSelect-{{ provider_id }}" style="max-width: 120px;">
<option value="vostfr">VOSTFR</option>
<option value="vf">VF</option>
</select>
<button type="button" class="btn-primary" onclick="searchAnimeProvider('{{ provider_id }}')">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
</svg>
Rechercher
</button>
</div>
<div style="display: flex; align-items: center; gap: 10px; margin-top: 10px; font-size: 13px; color: #888;">
<input type="checkbox" id="includeMetadata-{{ provider_id }}" style="width: auto; margin: 0;">
<label for="includeMetadata-{{ provider_id }}" style="cursor: pointer; user-select: none;">
📊 Inclure les métadonnées
</label>
</div>
</div>
<div id="searchResults-{{ provider_id }}" class="search-results"></div>
</div>