adding working metadata extract butto for yt embeds

This commit is contained in:
2026-06-21 20:26:44 +02:00
parent f190ff073a
commit 977cab8ad2
6 changed files with 35 additions and 12 deletions

View File

@@ -9662,6 +9662,7 @@ document.addEventListener('click', (e) => {
if (metaBtn) { if (metaBtn) {
e.preventDefault(); e.preventDefault();
const itemid = metaBtn.dataset.itemId; const itemid = metaBtn.dataset.itemId;
const ytSrc = metaBtn.dataset.src || null; // Set for YouTube items
const modal = document.getElementById('metadata-modal'); const modal = document.getElementById('metadata-modal');
if (!modal) return; if (!modal) return;
@@ -9705,7 +9706,7 @@ document.addEventListener('click', (e) => {
// Find the new item's metadata button // Find the new item's metadata button
const newMetaBtn = document.getElementById('a_metadata'); const newMetaBtn = document.getElementById('a_metadata');
if (!newMetaBtn) { if (!newMetaBtn) {
// New item doesn't support metadata extraction (YouTube, Flash, etc.) // New item doesn't support metadata extraction (Flash, etc.)
// Keep modal open but show a friendly message instead of closing // Keep modal open but show a friendly message instead of closing
loading.style.display = 'none'; loading.style.display = 'none';
resultsCont.style.display = 'none'; resultsCont.style.display = 'none';
@@ -9716,12 +9717,23 @@ document.addEventListener('click', (e) => {
return; return;
} }
const newItemId = newMetaBtn.dataset.itemId; const newItemId = newMetaBtn.dataset.itemId;
const newYtSrc = newMetaBtn.dataset.src || null;
// Re-attach nav listener for subsequent navigations // Re-attach nav listener for subsequent navigations
window.addEventListener('pjax:start', onNav); window.addEventListener('pjax:start', onNav);
// Fetch metadata for the new item // Fetch metadata for the new item (YouTube → oEmbed URL fetch, others → file extract)
try { try {
const resp = await fetch(`/api/v2/meta/extract/item/${newItemId}`); let resp, data;
const data = await resp.json(); if (newYtSrc) {
resp = await fetch(`/api/v2/meta/fetch?url=${encodeURIComponent(newYtSrc)}`);
const raw = await resp.json();
// Normalise oEmbed response into the same {success, fields} shape
data = raw.success
? { success: true, fields: [raw.meta.title, raw.meta.author].filter(Boolean) }
: raw;
} else {
resp = await fetch(`/api/v2/meta/extract/item/${newItemId}`);
data = await resp.json();
}
loading.style.display = 'none'; loading.style.display = 'none';
if (data.success && data.fields && data.fields.length > 0) { if (data.success && data.fields && data.fields.length > 0) {
resultsCont.style.display = 'block'; resultsCont.style.display = 'block';
@@ -9814,8 +9826,18 @@ document.addEventListener('click', (e) => {
document.addEventListener('metadata-modal-close', close, { once: true }); document.addEventListener('metadata-modal-close', close, { once: true });
try { try {
const resp = await fetch(`/api/v2/meta/extract/item/${itemid}`); let resp, data;
const data = await resp.json(); if (ytSrc) {
// YouTube item: use oEmbed via the URL-based fetch endpoint
resp = await fetch(`/api/v2/meta/fetch?url=${encodeURIComponent(ytSrc)}`);
const raw = await resp.json();
data = raw.success
? { success: true, fields: [raw.meta.title, raw.meta.author].filter(Boolean) }
: raw;
} else {
resp = await fetch(`/api/v2/meta/extract/item/${itemid}`);
data = await resp.json();
}
loading.style.display = 'none'; loading.style.display = 'none';
if (data.success && data.fields && data.fields.length > 0) { if (data.success && data.fields && data.fields.length > 0) {

View File

@@ -129,7 +129,7 @@ export default (router, tpl) => {
const item = data.item; const item = data.item;
data.is_mod_or_admin = !!(session && (session.admin || session.is_moderator)); data.is_mod_or_admin = !!(session && (session.admin || session.is_moderator));
data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username)); data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username));
data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1 && item.mime.indexOf('youtube') === -1); data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1);
data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user)); data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user));
data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : ''; data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : '';
data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : ''; data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : '';

View File

@@ -347,7 +347,8 @@ export default (router, tpl) => {
// Can the current user manage this item (owner, admin, or mod)? // Can the current user manage this item (owner, admin, or mod)?
data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username)); data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username));
// Is the item's MIME type suitable for metadata extraction? // Is the item's MIME type suitable for metadata extraction?
data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1 && item.mime.indexOf('youtube') === -1); // YouTube items use oEmbed via /meta/fetch; all non-flash MIME types are eligible.
data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1);
// Has the current user favorited this item? // Has the current user favorited this item?
data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user)); data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user));
// Hall columns for display // Hall columns for display

View File

@@ -163,7 +163,7 @@ export default (router, tpl) => {
const item = data.item; const item = data.item;
data.is_mod_or_admin = !!(session && (session.admin || session.is_moderator)); data.is_mod_or_admin = !!(session && (session.admin || session.is_moderator));
data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username)); data.can_manage_item = !!(session && (session.admin || session.is_moderator || session.user === item.username));
data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1 && item.mime.indexOf('youtube') === -1); data.can_extract_meta = !!(item.mime && item.mime.indexOf('flash') === -1);
data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user)); data.user_has_favorited = !!(session && Array.isArray(item.favorites) && item.favorites.some(f => f.user === session.user));
data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : ''; data.halls_slugs = Array.isArray(item.halls) ? item.halls.map(h => h.slug).join(',') : '';
data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : ''; data.user_halls_slugs = Array.isArray(item.user_halls) ? item.user_halls.map(h => h.slug).join(',') : '';

View File

@@ -141,7 +141,7 @@
@if(can_manage_item) @if(can_manage_item)
<i class="iconset {{ item.is_oc ? 'fa-solid' : 'fa-regular' }} fa-star" id="a_oc" data-item-id="{{ item.id }}" data-is-oc="{{ item.is_oc }}" title="{{ item.is_oc ? 'Remove OC status' : 'Mark as OC' }}"></i> <i class="iconset {{ item.is_oc ? 'fa-solid' : 'fa-regular' }} fa-star" id="a_oc" data-item-id="{{ item.id }}" data-is-oc="{{ item.is_oc }}" title="{{ item.is_oc ? 'Remove OC status' : 'Mark as OC' }}"></i>
@if(can_extract_meta) @if(can_extract_meta)
<i class="iconset fa-solid fa-magic" id="a_metadata" data-item-id="{{ item.id }}" title="Extract Metadata"></i> <i class="iconset fa-solid fa-magic" id="a_metadata" data-item-id="{{ item.id }}" @if(item.mime === 'video/youtube') data-src="https://www.youtube.com/watch?v={{ item.dest.replace('yt:', '') }}" @endif title="Extract Metadata"></i>
@endif @endif
@if(item.mime === 'application/x-shockwave-flash' || item.mime === 'application/vnd.adobe.flash.movie') @if(item.mime === 'application/x-shockwave-flash' || item.mime === 'application/vnd.adobe.flash.movie')
<i class="iconset fa-solid fa-image" id="a_rethumb" data-item-id="{{ item.id }}" title="Re-upload Thumbnail"></i> <i class="iconset fa-solid fa-image" id="a_rethumb" data-item-id="{{ item.id }}" title="Re-upload Thumbnail"></i>

View File

@@ -140,7 +140,7 @@
<i class="iconset fa-solid fa-triangle-exclamation report-item-btn" data-item-id="{{ item.id }}" title="Report this post"></i> <i class="iconset fa-solid fa-triangle-exclamation report-item-btn" data-item-id="{{ item.id }}" title="Report this post"></i>
@if(can_manage_item) @if(can_manage_item)
<i class="iconset {{ item.is_oc ? 'fa-solid' : 'fa-regular' }} fa-star" id="a_oc" data-item-id="{{ item.id }}" data-is-oc="{{ item.is_oc }}" title="{{ item.is_oc ? 'Remove OC status' : 'Mark as OC' }}"></i> <i class="iconset {{ item.is_oc ? 'fa-solid' : 'fa-regular' }} fa-star" id="a_oc" data-item-id="{{ item.id }}" data-is-oc="{{ item.is_oc }}" title="{{ item.is_oc ? 'Remove OC status' : 'Mark as OC' }}"></i>
<i class="iconset fa-solid fa-magic" id="a_metadata" data-item-id="{{ item.id }}" title="Extract Metadata"></i> <i class="iconset fa-solid fa-magic" id="a_metadata" data-item-id="{{ item.id }}" @if(item.mime === 'video/youtube') data-src="https://www.youtube.com/watch?v={{ item.dest.replace('yt:', '') }}" @endif title="Extract Metadata"></i>
@if(is_flash_item) @if(is_flash_item)
<i class="iconset fa-solid fa-image" id="a_rethumb" data-item-id="{{ item.id }}" title="Re-upload Thumbnail"></i> <i class="iconset fa-solid fa-image" id="a_rethumb" data-item-id="{{ item.id }}" title="Re-upload Thumbnail"></i>
@endif @endif