- tmdb.py : recherche TMDB par title+subtitle, matching fuzzy, cache SQLite 30 jours (table tmdb_cache dans arte_dl.db) - arte_api.py : enrichissement concurrent (5 workers) après résolution des IDs ; ajoute tmdb_id, tmdb_poster, tmdb_backdrop au concert - app.js : backdrop TMDB utilisé comme thumbnail de carte quand dispo ; subtitle affiché sous le titre de carte ; poster dans la modal ; lien direct vers la fiche TMDB - docker-compose.yml : passage de TMDB_API_KEY au container Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+25
-3
@@ -102,12 +102,14 @@ function renderConcerts(data) {
|
||||
statusText.textContent = `${total} concert${total > 1 ? 's' : ''} · page ${state.page} / ${pages}`;
|
||||
|
||||
grid.innerHTML = concerts.map(c => {
|
||||
const thumb = c.thumbnail
|
||||
? `<img class="card-thumb" src="${c.thumbnail}" alt="" loading="lazy" />`
|
||||
const imgSrc = c.tmdb_backdrop || c.thumbnail;
|
||||
const thumb = imgSrc
|
||||
? `<img class="card-thumb" src="${imgSrc}" alt="" loading="lazy" />`
|
||||
: `<div class="card-thumb" style="background:#1a1a1a"></div>`;
|
||||
const dur = c.duration ? `<span class="card-duration">${fmtDuration(c.duration)}</span>` : '';
|
||||
const dl = state.downloadedUrls.has(c.url) ? `<span class="card-downloaded">✓ Téléchargé</span>` : '';
|
||||
const date = fmtDate(c.upload_date);
|
||||
const sub = c.subtitle ? `<div class="card-subtitle">${c.subtitle}</div>` : '';
|
||||
|
||||
return `
|
||||
<div class="card" data-id="${c.id}" tabindex="0" role="button" aria-label="${c.title}">
|
||||
@@ -116,6 +118,7 @@ function renderConcerts(data) {
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<div class="card-title">${c.title}</div>
|
||||
${sub}
|
||||
${date ? `<div class="card-date">${date}</div>` : ''}
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -175,9 +178,20 @@ pagination.addEventListener('click', e => {
|
||||
function openModal(concert) {
|
||||
state.current = concert;
|
||||
|
||||
$('modal-thumb').src = concert.thumbnail || '';
|
||||
const modalThumbEl = $('modal-thumb');
|
||||
modalThumbEl.src = concert.tmdb_backdrop || concert.thumbnail || '';
|
||||
|
||||
const posterEl = $('modal-poster');
|
||||
if (concert.tmdb_poster) {
|
||||
posterEl.src = concert.tmdb_poster;
|
||||
posterEl.hidden = false;
|
||||
} else {
|
||||
posterEl.hidden = true;
|
||||
}
|
||||
|
||||
$('modal-title').textContent = concert.title;
|
||||
$('modal-meta').textContent = [
|
||||
concert.subtitle || '',
|
||||
concert.duration ? fmtDuration(concert.duration) : '',
|
||||
concert.upload_date ? fmtDate(concert.upload_date) : '',
|
||||
].filter(Boolean).join(' · ');
|
||||
@@ -185,6 +199,14 @@ function openModal(concert) {
|
||||
$('modal-dur-badge').textContent = concert.duration ? fmtDuration(concert.duration) : '';
|
||||
$('btn-watch').href = concert.url || '#';
|
||||
|
||||
const btnTmdb = $('btn-tmdb');
|
||||
if (concert.tmdb_id) {
|
||||
btnTmdb.href = `https://www.themoviedb.org/movie/${concert.tmdb_id}`;
|
||||
btnTmdb.hidden = false;
|
||||
} else {
|
||||
btnTmdb.hidden = true;
|
||||
}
|
||||
|
||||
const btnDl = $('btn-download');
|
||||
const alreadyDone = state.downloadedUrls.has(concert.url);
|
||||
btnDl.textContent = alreadyDone ? '✓ Déjà téléchargé' : 'Télécharger';
|
||||
|
||||
+31
-2
@@ -337,6 +337,16 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
margin-top: 3px;
|
||||
font-size: 11.5px;
|
||||
color: var(--gold);
|
||||
letter-spacing: 0.02em;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.card-date {
|
||||
margin-top: 6px;
|
||||
font-size: 11.5px;
|
||||
@@ -483,6 +493,26 @@ body {
|
||||
background: linear-gradient(to bottom, transparent 50%, var(--surface) 100%);
|
||||
}
|
||||
|
||||
.modal-head {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 14px;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.modal-head-text { flex: 1; min-width: 0; }
|
||||
|
||||
.modal-poster {
|
||||
width: 64px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 16px rgba(0,0,0,0.5);
|
||||
object-fit: cover;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.modal-poster[hidden] { display: none; }
|
||||
|
||||
.modal-duration-badge {
|
||||
position: absolute;
|
||||
bottom: 12px; right: 12px;
|
||||
@@ -505,14 +535,13 @@ body {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
line-height: 1.3;
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.modal-meta {
|
||||
font-size: 12.5px;
|
||||
color: var(--gold);
|
||||
letter-spacing: 0.04em;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.modal-desc {
|
||||
|
||||
Reference in New Issue
Block a user