discord-media-server
Version:
Self-hosted Discord bot for scanning and serving information on local media files.
266 lines (230 loc) • 9.37 kB
HTML
<html>
<head>
<title>Media Dashboard</title>
<style>
.hidden { display: none; }
body { font-family: sans-serif; padding: 20px; background: #f4f4f4; }
header h1 { display: inline; margin-left: 10px; }
h1 { margin-bottom: 10px; }
nav h5 { margin-right: 15px; text-decoration: none; color: #0077cc; display: inline; cursor: pointer; }
nav h5:hover { color: #0007cc; }
input, select, button { margin: 5px; padding: 5px; }
ul { list-style: none; padding-left: 0; }
li { background: white; padding: 10px; margin-bottom: 5px; border-radius: 4px; }
</style>
<script src="/js/jquery-3.6.0.min.js"></script>
</head>
<body>
<header>
<img src="/logo.png" alt="Logo"><h1>Media Dashboard</h1>
</header>
<nav>
<h5 class="nav-buttons" id="nav-home">Home</h5>
<h5 class="nav-buttons" id="nav-movies">Movie List</h5>
<h5 class="nav-buttons" id="nav-settings">Settings</h5>
<h5 class="buttons" id="search" >Search</h5>
</nav>
<div id="media-search" class="media">
<form id="searchForm" onsubmit="doSearch(event)">
<input name="title" placeholder="Title">
<input name="year" placeholder="Year">
<input name="format" placeholder="Format (e.g. mkv)">
<button type="submit" >Search</button>
</form>
<ul id="mediaList"></ul>
</div>
<hr>
<p id="total"></p>
<div id="data"></div>
<script>
$(document).ready(function () {
$('#media-search').hide();
$('body').on('click', '.nav-buttons', function(){
//event.stopPropagation();
//event.stopImmediatePropagation();
let id = $(this).attr('id');
$('.media').hide();
if (id == 'nav-edit' || id == 'edit') {
//$('#media-edit').show();
fetch('/api/config')
.then(res => res.json())
.then(env => {
$('#data').html(`
<h1>Discord Media Server Setup</h1>
<form method="POST" action="/submit">
<label>TMDb API Key: <input name="tmdbKey" value="${env.TMDB_API_KEY || ''}"></label><br>
<label>Media Directory: <input name="mediaDirectory" value="${env.MEDIA_DIR || ''}" required></label><br>
<label>DB Type:
<select id="dbType" name="dbType">
<option value="sqlite" ${env.DB_TYPE === 'sqlite' ? 'selected' : ''}>SQLite</option>
<option value="mysql" ${env.DB_TYPE === 'mysql' ? 'selected' : ''}>MySQL</option>
</select>
</label><br>
<label>DB Name: <input name="dbName" value="${env.DB_NAME || ''}"></label><br>
<div id="mysqlFields" style="display:${env.DB_TYPE === 'mysql' ? 'block' : 'none'};">
<label>DB Host: <input name="dbHost" value="${env.DB_HOST || ''}"></label><br>
<label>DB User: <input name="dbUser" value="${env.DB_USER || ''}"></label><br>
<label>DB Pass: <input name="dbPass" value="${env.DB_PASS || ''}" type="password"></label><br>
</div>
<button type="submit">Save</button>
<button class="nav-buttons" id="cancel">Cancel</button>
</form>
<form action="/launch" method="post">
<button type="submit">Start Server & Bot</button>
</form>
`);
});
} else if (id == 'nav-home' || id == 'cancel') {
//loadStats();
//$('#media-home').show();
$('#data').html(`
<h1>Discord Media Server Setup</h1>
`);
} else if (id == 'nav-settings') {
fetch('/api/config')
.then(res => res.json())
.then(env => {
$('#data').html(`
<h1>Discord Media Server Setup</h1>
<fieldset>
<label><b>TMDb API Key:</b> ${env.TMDB_API_KEY || ''}</label><br>
<label><b>Media Directory:</b> ${env.MEDIA_DIR || ''}</label><br>
<label><b>DB Type:</b> ${env.DB_TYPE || ''}</label><br>
<label><b>DB Name:</b> ${env.DB_NAME || ''}</label><br>
<button class="nav-buttons" id="edit">Edit</button>
</fieldset>
`);
/*
<form action="/launch" method="get">
<button type="submit" id='getBot' name='startBot' value=${botRunning ? 'reset' : 'start'}>${botRunning ? 'Restart Bot' : 'Turn on Bot'}</button>
</form>
<button type="submit" id='startBot' value=${botRunning ? 'reset' : 'start'}>${botRunning ? 'Restart' : 'Off'}</button>
<div id='status'></div>
*/
});
} else if (id == 'nav-refresh') {
refreshIndex();
$('#media-refresh').show();
} else if (id == 'nav-movies') {
fetch('/dashboard/media')
.then(res => res.json())
.then(data => {
document.getElementById('total').textContent = `Total Movies: ${data.total}`;
const list = document.getElementById('data');
list.innerHTML = '';
data.media.forEach(m => {
const li = document.createElement('li');
li.textContent = `${m.title} (${m.year}) – ${m.format} - added ${new Date(m.added_at).toLocaleDateString()}`;
list.appendChild(li);
});
});
}
});
// Attach change event listener to the select element
$('#data').on('change', '#dbType', function(){
if ($(this).val() === 'mysql') {
$('#mysqlFields').show(); // or $('#mysqlFields').css('display', 'block');
} else {
$('#mysqlFields').hide(); // or $('#mysqlFields').css('display', 'none');
}
});
$('#search').on('click', function(){
$('#media-search').toggle(1000);
});
});
function formatBytes(a, b = 2, k = 1024) {
if (a === 0) return '0 Bytes';
const i = Math.floor(Math.log(a) / Math.log(k));
return `${(a / Math.pow(k, i)).toFixed(b)} ${['Bytes', 'KB', 'MB', 'GB', 'TB'][i]}`;
}
function doSearch(event) {
event.preventDefault();
const form = document.getElementById('searchForm');
const params = new URLSearchParams(new FormData(form)).toString();
fetch(`/dashboard/search?${params}`)
.then(res => res.json())
.then(data => {
document.getElementById('total').textContent = `Search Results: ${data.count}`;
renderList(data.results);
});
}
function formatMovie(m) {
return `${m.title} ${m.year==='0000' ? '' : '('+m.year+')'} – ${m.format} – size: ${formatBytes(m.filesize)} - added ${new Date(m.added_at).toLocaleDateString()}`;
}
function renderList(data) {
document.getElementById('mediaList').innerHTML = '';
data.forEach(m => {
const li = document.createElement('li');
li.textContent = formatMovie(m);
document.getElementById('mediaList').appendChild(li);
});
}
function loadStats() {
fetch('/dashboard/movies')
.then(res => res.json())
.then(data => {
document.getElementById('total').textContent = `Total Movies: ${data.total}`;
renderList(data.recent);
});
}
function refreshIndex() {
fetch('/api/media/refresh', { method: 'POST' })
.then(res => res.json())
.then(data => {
alert(`Index refreshed. Total: ${data.count}`);
loadStats();
});
}
//loadStats(); // initial load
</script>
</body>
</html>
<!--
<!DOCTYPE html>
<html>
<head>
<title>Media Dashboard</title>
<style>
body { font-family: sans-serif; padding: 20px; background: #f4f4f4; }
h1 { margin-bottom: 5px; }
ul { list-style: none; padding-left: 0; }
li { background: white; padding: 10px; margin-bottom: 5px; border-radius: 4px; }
</style>
</head>
<body>
<h1>Media Dashboard</h1>
<p id="total"></p>
<h2>Recently Added</h2>
<ul id="mediaList"></ul>
<script>
/*
fetch('/dashboard/media')
.then(res => res.json())
.then(data => {
document.getElementById('total').textContent = `Total Movies: ${data.total}`;
const list = document.getElementById('mediaList');
data.media.forEach(m => {
const li = document.createElement('li');
li.textContent = `${m.title} (${m.year}) – ${m.format} – added ${new Date(m.dateAdded).toLocaleDateString()}`;
list.appendChild(li);
});
});
*/
</script>
<script>
fetch('/dashboard/movies')
.then(res => res.json())
.then(data => {
document.getElementById('total').textContent = `Total Movies: ${data.count}`;
const list = document.getElementById('mediaList');
data.results.forEach(m => {
const li = document.createElement('li');
li.textContent = `${m.title} (${m.year}) – ${m.format} - ${m.imdb}`;
list.appendChild(li);
});
});
</script>
</body>
</html>
-->