refactor: Apply code quality improvements from PR review

This commit implements the optional improvements identified during code review:

**Backend (animesama.py):**
- Replace all print() statements with logger calls for consistency
  - Use logger.debug() for detailed debugging information
  - Use logger.info() for general operational messages
  - Use logger.warning() for non-critical issues
  - Use logger.error() for error conditions
- Add comprehensive docstring to get_seasons() method:
  - Document two-phase parallel loading strategy
  - Explain performance characteristics (200x faster)
  - Document timeout behavior and error handling
  - Include usage examples and return value format
- Import logging module and initialize logger

**Frontend (anime.js & api.js):**
- Create providerSupportsSeasons() helper function in api.js:
  - Uses provider configuration as single source of truth
  - Eliminates hardcoded 'animesama' and 'anime-sama' checks
  - Supports explicit supports_seasons flag in provider config
  - Fallback to domain detection for unknown URLs
- Update renderAnimeCard() to use async helper function
- Update loadSeasonsForAnime() to use provider configuration
- Update displaySearchResults() to handle async card rendering
- Export helper function globally for use across modules

**Tests (test_anime_sama_seasons.py):**
- Fix import paths for new animesama.py location
  - Update from app.downloaders.animesama to app.downloaders.anime_sites.animesama
- All tests passing with new structure

**Benefits:**
- Consistent logging throughout the codebase
- Better maintainability with configuration-driven behavior
- Improved documentation for complex async logic
- Easier to add new season-supporting providers in future
- No hardcoded provider checks in frontend code

All tests passing: 5/5 

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 is contained in:
root
2026-01-29 19:19:53 +00:00
parent 764b4e2edd
commit 7dabce1c3c
4 changed files with 194 additions and 98 deletions
+19 -14
View File
@@ -10,7 +10,7 @@ async function displaySearchResults(data, lang) {
const providers = await getProvidersInfo();
let totalResults = 0;
let html = '';
let htmlPromises = [];
for (const [providerId, results] of Object.entries(data.results)) {
if (results && results.length > 0) {
@@ -18,18 +18,22 @@ async function displaySearchResults(data, lang) {
results.forEach(anime => {
const providerInfo = providers.anime_providers[providerId];
html += renderAnimeCard(anime, providerId, providerInfo, lang);
// Collect promises for async rendering
htmlPromises.push(renderAnimeCard(anime, providerId, providerInfo, lang));
});
}
}
if (totalResults === 0) {
html = '<div class="no-results">Aucun résultat trouvé</div>';
resultsContainer.innerHTML = '<div class="no-results">Aucun résultat trouvé</div>';
return;
}
resultsContainer.innerHTML = html;
// Wait for all cards to be rendered
const htmlSegments = await Promise.all(htmlPromises);
resultsContainer.innerHTML = htmlSegments.join('');
// Auto-load seasons (for Anime-Sama) or episodes for each anime
// Auto-load seasons for providers that support them
// Stagger the requests to avoid overwhelming the server
let delayCounter = 0;
for (const [providerId, results] of Object.entries(data.results)) {
@@ -37,7 +41,7 @@ async function displaySearchResults(data, lang) {
results.forEach((anime, index) => {
// Stagger requests: 500ms delay between each anime
setTimeout(() => {
// Try to load seasons first (for Anime-Sama)
// Try to load seasons first (if provider supports them)
if (anime.url) {
loadSeasonsForAnime(providerId, encodeURIComponent(anime.url));
}
@@ -51,13 +55,13 @@ async function displaySearchResults(data, lang) {
/**
* Render anime card HTML
*/
function renderAnimeCard(anime, providerId, providerInfo, lang) {
async function renderAnimeCard(anime, providerId, providerInfo, lang) {
const metadataHtml = renderAnimeMetadata(anime.metadata);
// Check if this is Anime-Sama (for season support)
const isAnimeSama = providerId === 'animesama' || anime.url?.includes('anime-sama');
// Check if provider supports seasons using helper function
const supportsSeasons = await providerSupportsSeasons(providerId, anime.url);
const seasonSelectHtml = isAnimeSama ? `
const seasonSelectHtml = supportsSeasons ? `
<select id="seasons-${providerId}-${encodeURIComponent(anime.url)}" onchange="handleSeasonChange('${providerId}', '${encodeURIComponent(anime.url)}', '${lang}')" style="margin-bottom: 8px;">
<option value="">Chargement des saisons...</option>
</select>
@@ -73,7 +77,7 @@ function renderAnimeCard(anime, providerId, providerInfo, lang) {
<div class="anime-card-actions">
${seasonSelectHtml}
<select id="episodes-${providerId}-${encodeURIComponent(anime.url)}">
<option value="">${isAnimeSama ? 'Sélectionner une saison d\'abord' : 'Charger les épisodes...'}</option>
<option value="">${supportsSeasons ? 'Sélectionner une saison d\'abord' : 'Charger les épisodes...'}</option>
</select>
</div>
<div class="anime-card-actions" id="actions-${providerId}-${encodeURIComponent(anime.url)}" style="display:none;">
@@ -131,7 +135,7 @@ function renderAnimeMetadata(metadata) {
}
/**
* Load seasons for Anime-Sama anime
* Load seasons for anime (if provider supports it)
*/
async function loadSeasonsForAnime(providerId, encodedUrl) {
const url = decodeURIComponent(encodedUrl);
@@ -140,8 +144,9 @@ async function loadSeasonsForAnime(providerId, encodedUrl) {
const seasonSelectElement = document.getElementById(seasonSelectId);
if (!seasonSelectElement) return;
// Only proceed if this is Anime-Sama
if (!url.includes('anime-sama')) {
// Check if provider supports seasons
const supportsSeasons = await providerSupportsSeasons(providerId, url);
if (!supportsSeasons) {
seasonSelectElement.style.display = 'none';
return;
}