You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
242 lines
6.8 KiB
242 lines
6.8 KiB
|
|
// TODO: could get path constants from DOM in jinja template |
|
const FOLDER_CONTENTS_PATH = '/pvdb/file_listing/file_listing_json/'; |
|
const QUERY_PATH = '/pvdb/tmdb/query_media_json'; |
|
const CREATE_MAPPING_PATH = '/pvdb/tmdb/create_path_mapping'; |
|
const PATH_PATH = '/pvdb/tmdb/query_path_json'; |
|
const VIDEO_PREFIX = '/video/'; |
|
const IMAGE_PREFIX = '/pvdb/tmdb/images'; |
|
|
|
|
|
// NOTE: create links for folder contents |
|
function addContents(node, json) { |
|
let a = document.createElement('a'); |
|
a.href = window.location; |
|
a.dataset.base_name = json.base_name; |
|
a.dataset.file_extension = json.file_extension; |
|
a.dataset.is_dir = json.is_dir; |
|
a.dataset.rel_path = json.rel_path; |
|
|
|
if (json.is_dir) { |
|
a.classList.add('folder'); |
|
} else { |
|
if (json.in_db) |
|
a.classList.add('file_stored'); |
|
else |
|
a.classList.add('file'); |
|
} |
|
|
|
a.appendChild(document.createTextNode(json.base_name)); |
|
a.addEventListener('click', function(e) { |
|
e.preventDefault(); |
|
let element = e.target.parentNode; // NOTE: the parent 'li' element |
|
let ul_node = element.querySelector('li > ul'); |
|
let div_node = element.querySelector('li > .search_result'); |
|
|
|
if (ul_node != null) { |
|
element.removeChild(ul_node); |
|
} else if (div_node != null) { |
|
element.removeChild(div_node); |
|
} else { |
|
if (a.dataset.is_dir == 'true') { |
|
fetchJSON(FOLDER_CONTENTS_PATH + a.dataset.rel_path, parseResponse, element); |
|
} else { |
|
if (a.className == 'file_stored') |
|
openInfoCard(a.dataset, e.target); |
|
else // 'file' |
|
openQueryDialog(a.dataset, e.target); |
|
} |
|
} |
|
}); |
|
|
|
let li = document.createElement('li'); |
|
li.appendChild(a); |
|
node.appendChild(li); |
|
} |
|
|
|
// NOTE: display an 'info card' for a path that has already been stored |
|
function openInfoCard(dataset, element) { |
|
query_str = PATH_PATH + '?rel_path=' + dataset.rel_path; |
|
fetchJSON(query_str, function(json) { |
|
if (json.errors) { |
|
for (let e of json.errors) |
|
logError(e) |
|
} else { |
|
blurb = createBlurb(json); |
|
// NOTE: don't need the mapping link here |
|
let p = blurb.querySelector('.mapping_link').parentNode; |
|
p.parentNode.removeChild(p); |
|
|
|
// NOTE: add play link |
|
let a = document.createElement('a'); |
|
a.classList.add('play_link'); |
|
a.href = VIDEO_PREFIX + dataset.rel_path; |
|
a.appendChild(document.createTextNode('play')); |
|
let div = blurb.querySelector('.search_result'); |
|
div.insertBefore(a, div.firstChild); |
|
|
|
element.parentNode.appendChild(blurb); |
|
} |
|
}); |
|
} |
|
|
|
// NOTE: create query results dialog from html templates |
|
function openQueryDialog(dataset, element) { |
|
query_str = QUERY_PATH |
|
+ '?query=' + dataset.base_name |
|
+ '&rel_path=' + dataset.rel_path; |
|
|
|
fetchJSON(query_str, function(json) { |
|
if (json.errors) { |
|
for (let e of json.errors) |
|
logError(e) |
|
} else { |
|
let tclone = document.importNode( |
|
document.querySelector('#query_results').content, |
|
true |
|
); |
|
tclone.querySelector('#query_close').addEventListener('click', function(e) { |
|
e.preventDefault(); |
|
document.querySelector('body').removeChild(e.target.parentNode); |
|
}); |
|
|
|
for (let result of json) { |
|
blurb = createBlurb(result); |
|
blurb.querySelector('.mapping_link').addEventListener('click', function(e) { |
|
submitFileMapping(e, result.detail_id, dataset.rel_path, element); |
|
}); |
|
tclone.querySelector('#query_result_container').appendChild(blurb); |
|
} |
|
|
|
document.querySelector('body').appendChild(tclone); |
|
} |
|
}); |
|
} |
|
|
|
function createBlurb(details) { |
|
console.log('createBlurb(), ' + query_str); |
|
console.log(details); |
|
|
|
let qtclone = document.importNode(document.querySelector('#query_result').content, true); |
|
|
|
let title_link = qtclone.querySelector('h3 > a'); |
|
title_link.href = details.tmdb_link; |
|
title_link.appendChild(document.createTextNode(details.title)); |
|
|
|
let date = qtclone.querySelector('.query_release_date'); |
|
date.appendChild(document.createTextNode(details.release_date)); |
|
|
|
let description = qtclone.querySelector('.query_description'); |
|
description.appendChild(document.createTextNode(details.overview)); |
|
|
|
if (details.poster_path != '') { |
|
let image = qtclone.querySelector('.result_image'); |
|
image.src = IMAGE_PREFIX + details.poster_path; |
|
} |
|
|
|
return qtclone; |
|
} |
|
|
|
async function submitFileMapping(click_event, detail_id, rel_path, element) { |
|
click_event.preventDefault(); |
|
// NOTE: remove the query box |
|
document.querySelector('body').removeChild(document.querySelector('#query_result_container')); |
|
query_str = CREATE_MAPPING_PATH; |
|
params = new FormData(); |
|
params.append('detail_id', detail_id); |
|
params.append('rel_path', rel_path); |
|
|
|
let json = null; |
|
const response = await fetch(CREATE_MAPPING_PATH, { body: params, method: 'POST' }); |
|
try { |
|
json = await response.json(); |
|
} catch (e) { |
|
logError('error in submitFileMapping(), ' + e); |
|
} |
|
|
|
if (json != null && json.errors.length == 0) { |
|
// NOTE: display success dialog |
|
let map_temp = document.querySelector('#mapping_success'); |
|
let clone = document.importNode(map_temp.content, true); |
|
clone.querySelector('div > p').appendChild(document.createTextNode(json.message)); |
|
let body = document.querySelector('body'); |
|
body.appendChild(clone); |
|
window.setTimeout(function() { |
|
body.removeChild(document.querySelector('.success_container')); |
|
}, 500); |
|
// NOTE: update the displayed link class |
|
element.className = 'file_stored'; |
|
} |
|
} |
|
|
|
function parseResponse(json, node) { |
|
if (node == null) { |
|
logError('parent node cannot be null'); |
|
return; |
|
} |
|
|
|
if (json.errors.length > 0) { |
|
for (let err of json.errors) |
|
logError(err); |
|
} else { |
|
let frag = document.createDocumentFragment(); |
|
let ul = document.createElement('ul'); |
|
frag.appendChild(ul); |
|
|
|
for (let path of json.paths) |
|
addContents(ul, path); |
|
|
|
node.appendChild(frag); |
|
} |
|
} |
|
|
|
window.onload = function() { |
|
document.querySelector('#noscript').style.display = 'none'; |
|
document.querySelector('#js_errors').style.display = 'none'; |
|
|
|
if (!('fetch' in window)) { |
|
logError('Unsupported Browser, No fetch API'); |
|
return; |
|
} |
|
|
|
if ((!'content' in document.createElement('template'))) { |
|
logError('Unsupported Browser, No template support'); |
|
return; |
|
} |
|
|
|
fetchJSON(FOLDER_CONTENTS_PATH, parseResponse, document.querySelector('.content')); |
|
} |
|
|
|
|
|
function logError(s) { |
|
console.log(s); |
|
let error_box = document.querySelector('#js_errors'); |
|
let p = document.createElement('p'); |
|
p.appendChild(document.createTextNode(s)); |
|
error_box.appendChild(p); |
|
error_box.style.display = 'block'; |
|
} |
|
|
|
function removeAllChildren(node) { |
|
while(node.hasChildNodes()) |
|
node.removeChild(node.lastChild); |
|
} |
|
|
|
function fetchJSON(url, responseFunc, node=null) { |
|
fetch(url) |
|
.then(function(response) { |
|
if (!response.ok) |
|
throw Error(response.statusText); |
|
|
|
return response.json(); |
|
}) |
|
.catch(function(error) { |
|
logError('fetch error: ' + error); |
|
return null; |
|
}) |
|
.then(function(json) { |
|
if (json != null) |
|
(node == null) ? responseFunc(json) : responseFunc(json, node); |
|
}); |
|
} |
|
|
|
|