Files
datascape/assets/editor/movie.js
T
2026-05-04 11:54:58 +02:00

128 lines
4.2 KiB
JavaScript

window.EditorMovie = (function () {
'use strict';
// OMDb API key. Shipped to the browser; acceptable for a single-user LAN tool.
var OMDB_API_KEY = '';
var BEGIN = '<!-- BEGIN MOVIE -->';
var END = '<!-- END MOVIE -->';
function firstHeading(text) {
var m = text.match(/^#{1,6}\s+(.+?)\s*$/m);
return m ? m[1].trim() : '';
}
function parseTitleYear(raw) {
var m = raw.match(/^(.+?)\s*\((\d{4})\)\s*$/);
return m ? { title: m[1].trim(), year: m[2] } : { title: raw.trim(), year: null };
}
function safe(v) { return (!v || v === 'N/A') ? '' : String(v); }
function esc(s) {
return String(s)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
function buildBlock(m) {
var out = [BEGIN, '<aside class="movie-info">'];
if (m.Poster && m.Poster !== 'N/A') {
out.push('<img class="movie-poster" src="' + esc(m.Poster) +
'" alt="' + esc(safe(m.Title)) + ' poster">');
}
out.push('<table>');
[
['Title', m.Title],
['Year', m.Year],
['Runtime', m.Runtime],
['Genre', m.Genre],
['Director', m.Director],
['Cast', m.Actors],
['Plot', m.Plot],
].forEach(function (r) {
out.push('<tr><th>' + r[0] + '</th><td>' + esc(safe(r[1])) + '</td></tr>');
});
out.push('</table>', '</aside>', END);
return out.join('\n');
}
function replaceRange(ta, start, end, text) {
ta.focus();
ta.selectionStart = start;
ta.selectionEnd = end;
document.execCommand('insertText', false, text);
}
function insertOrReplace(ta, markup) {
var t = ta.value || '';
var b = t.indexOf(BEGIN);
var e = t.indexOf(END);
if (b !== -1 && e !== -1 && e > b) {
replaceRange(ta, b, e + END.length, markup);
} else {
var h = t.match(/^#{1,6}\s+.+?\s*$/m);
if (h) {
var idx = t.indexOf(h[0]) + h[0].length;
replaceRange(ta, idx, idx, '\n\n' + markup);
} else {
replaceRange(ta, 0, 0, t ? markup + '\n\n' : markup);
}
}
}
function fetchMovie(title, year) {
var url = 'https://www.omdbapi.com/?apikey=' + encodeURIComponent(OMDB_API_KEY) +
'&type=movie&t=' + encodeURIComponent(title);
if (year) url += '&y=' + encodeURIComponent(year);
return fetch(url).then(function (r) { return r.json(); });
}
function showMessage(title, msg) {
openModal({ title: title, body: msg, confirm: { label: 'OK' } });
}
function run(textarea) {
if (!OMDB_API_KEY) {
showMessage('Movie import', 'OMDb API key is not set. Edit assets/editor/movie.js.');
return;
}
var input = document.createElement('input');
input.type = 'text';
input.className = 'modal-input';
input.placeholder = 'Title, optionally with (YYYY)';
input.value = firstHeading(textarea.value || '');
openModal({
title: 'Import movie',
body: input,
confirm: {
label: 'IMPORT',
onConfirm: function () {
var raw = input.value.trim();
if (!raw) return;
var parsed = parseTitleYear(raw);
closeModal();
fetchMovie(parsed.title, parsed.year)
.then(function (data) {
if (!data || data.Response === 'False') {
showMessage('Not found',
(data && data.Error) || 'Movie not found.');
return;
}
insertOrReplace(textarea, buildBlock(data));
})
.catch(function () {
showMessage('Import failed', 'OMDb lookup failed.');
});
},
},
});
}
return { run: run };
})();