feat: add videodb media index with Docker stack
- Add videodb PHP/MySQL media collection manager (Blu-ray, DVD, CD) - Dockerfile: PHP 8.1 + Apache with GD/mysqli/exif extensions - docker-compose.yml: app on port 6761 + MySQL 8.0 with health checks - docker-entrypoint.sh: auto-generates config.inc.php from env vars, waits for MySQL, initializes DB schema idempotently - init-db.php: CLI schema installer using app's own prefix_query() logic - Persistent volumes for DB, cache, and cover images Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
321
videodb/show.php
Normal file
321
videodb/show.php
Normal file
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
/**
|
||||
* Movie Detail View
|
||||
*
|
||||
* Shows all data of a movie
|
||||
*
|
||||
* @package videoDB
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: show.php,v 2.52 2013/03/15 16:42:46 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/custom.php';
|
||||
require_once './core/output.php';
|
||||
|
||||
/**
|
||||
* input
|
||||
*/
|
||||
$id = req_int('id');
|
||||
$ajax_update = req_int('ajax_update');
|
||||
$seen = req_int('seen');
|
||||
$rating = req_int('rating');
|
||||
$export = req_string('export');
|
||||
$save = req_int('save');
|
||||
$method = req_string('method'); // only boxeePlay
|
||||
|
||||
/**
|
||||
* Play movie on configured Boxee box
|
||||
*/
|
||||
function boxeePlay($filename) {
|
||||
global $config;
|
||||
|
||||
$socket = fsockopen($config['boxeeHost'], $config['boxeePort']);
|
||||
if (!$socket) {
|
||||
throw new Exception("Couldn't connect to boxee on ".$config['boxeeHost'].':'.$config['boxeePort']);
|
||||
}
|
||||
|
||||
$data = array(
|
||||
'id' => 1,
|
||||
'jsonrpc' => '2.0',
|
||||
'method' => 'XBMC.Play',
|
||||
'params' => array('file' => $filename)
|
||||
);
|
||||
|
||||
$json = json_encode($data, JSON_FORCE_OBJECT);
|
||||
|
||||
fputs($socket, $json);
|
||||
/*
|
||||
$response = '';
|
||||
while (!(feof($socket))) {
|
||||
$response .= fgets($socket);
|
||||
}
|
||||
*/
|
||||
// close socket
|
||||
$status = stream_get_meta_data($socket);
|
||||
fclose($socket);
|
||||
|
||||
// check for timeout
|
||||
if (@$status['timed_out']) {
|
||||
$response['error'] = "Connection timed out";
|
||||
}
|
||||
|
||||
return trim($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle seen status
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
*/
|
||||
if ($ajax_update)
|
||||
{
|
||||
// add some delay for debugging
|
||||
if ($config['debug'] && $_SERVER['SERVER_ADDR'] == '127.0.0.1') usleep(rand(200,1000)*1000);
|
||||
|
||||
if (isset($seen))
|
||||
{
|
||||
set_userseen($ajax_update, $seen);
|
||||
|
||||
header('X-JSON: '.json_encode(array('result' => $seen > 0)));
|
||||
}
|
||||
elseif (isset($rating))
|
||||
{
|
||||
// Permission check same as edit.php
|
||||
// check for localnet
|
||||
localnet_or_die();
|
||||
|
||||
// multiuser permission check
|
||||
if (empty($id))
|
||||
permission_or_die(PERM_WRITE);
|
||||
else
|
||||
permission_or_die(PERM_WRITE, get_owner_id($ajax_update));
|
||||
|
||||
runSQL('UPDATE '.TBL_DATA.' SET rating='.$rating.' WHERE id='.$ajax_update);
|
||||
}
|
||||
|
||||
// make sure no artifacts
|
||||
$smarty->clearCache('list.tpl');
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
// random view
|
||||
if (empty($id))
|
||||
{
|
||||
$count = 0;
|
||||
$all = strtoupper($lang['radio_all']);
|
||||
$WHERES = '';
|
||||
$JOINS = '';
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
// explicit setting of owner
|
||||
$owner = session_get('owner');
|
||||
if ($owner && $owner == $all || check_permission(PERM_READ, $uid = get_userid($owner)))
|
||||
{
|
||||
if ($owner == $all) $uid = -1;
|
||||
$owner_id = $uid;
|
||||
}
|
||||
elseif (check_permission(PERM_READ, get_current_user_id()))
|
||||
{
|
||||
$owner_id = get_current_user_id();
|
||||
}
|
||||
elseif (count($owners = out_owners(false, PERM_READ, true)) == 1)
|
||||
{
|
||||
// check if there is only one owner available
|
||||
$owners = array_keys($owners);
|
||||
$owner_id = $owners[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
// help! take ALL
|
||||
$owner_id = -1;
|
||||
}
|
||||
|
||||
session_set('owner', ($owner_id && $owner_id >= 0) ? get_username($owner_id) : $all);
|
||||
|
||||
// if we don't have read all permissions, limit visibility using cross-user permissions
|
||||
if (!check_permission(PERM_READ))
|
||||
{
|
||||
$JOINS = ' LEFT JOIN '.TBL_PERMISSIONS.' ON '.TBL_DATA.'.owner_id = '.TBL_PERMISSIONS.'.to_uid';
|
||||
$WHERES .= ' AND '.TBL_PERMISSIONS.'.from_uid = '.get_current_user_id().' AND '.TBL_PERMISSIONS.'.permissions & '.PERM_READ.' != 0';
|
||||
}
|
||||
|
||||
// further limit to single owner
|
||||
if ($owner_id > 0) $WHERES .= " AND owner_id = '".$owner_id."' ";
|
||||
}
|
||||
|
||||
// limit random to not unseen movies only
|
||||
if (array_key_exists( 'showrandomunseen', $config) && $config['showrandomunseen'])
|
||||
{
|
||||
// WARNING: this may make the SQL query expensive for large databases
|
||||
$WHERES .= ' AND ('.TBL_DATA.'.id NOT IN (SELECT video_id FROM '.TBL_USERSEEN.'))';
|
||||
}
|
||||
|
||||
// find a random id
|
||||
$SELECT = 'SELECT id, REVERSE(RAND(NOW())) AS rnd
|
||||
FROM '.TBL_DATA."
|
||||
$JOINS
|
||||
WHERE mediatype != ".MEDIA_WISHLIST." $WHERES
|
||||
ORDER BY rnd
|
||||
LIMIT 1";
|
||||
|
||||
while (!$id)
|
||||
{
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
// prevent endless loop
|
||||
if (!count($result) || ($count++ > 50)) break;
|
||||
|
||||
$id = $result[0]['id'];
|
||||
if (!adultcheck($id)) $id = 0; //adult movie? -> try again
|
||||
}
|
||||
|
||||
// id still empty? go back to index.
|
||||
if (empty($id)) redirect('index.php');
|
||||
}
|
||||
|
||||
// get data (id may be empty on a empty database)
|
||||
if (!empty($id))
|
||||
{
|
||||
// no adult permissions? -> back to index
|
||||
if (!adultcheck($id) || !check_videopermission(PERM_READ, $id)) redirect('index.php');
|
||||
|
||||
// XML / RSS / PDF export
|
||||
if ($export && $config[$export])
|
||||
{
|
||||
// either (xml|rss|pdf)export
|
||||
$func = $export.'export';
|
||||
if ($export == 'rss') $export = 'xml';
|
||||
require_once './core/'.$export.'.php';
|
||||
|
||||
if (function_exists($func)) $func('WHERE '.TBL_DATA.'.id = '.$id);
|
||||
exit;
|
||||
}
|
||||
|
||||
$SELECT = 'SELECT '.TBL_DATA.'.id, title, subtitle, language, diskid, comment,
|
||||
disklabel, imdbID, year, imgurl, director, actors, runtime,
|
||||
country, plot, filename, filesize, filedate, audio_codec,
|
||||
video_codec, video_width, video_height, istv, lastupdate,
|
||||
email, rating, custom1, custom2, custom3, custom4,
|
||||
!ISNULL('.TBL_USERSEEN.'.video_id) AS seen,
|
||||
'.TBL_USERS.'.name AS owner, '.TBL_MEDIATYPES.'.name AS mediatype
|
||||
FROM '.TBL_DATA.'
|
||||
LEFT JOIN '.TBL_USERS.' ON owner_id = '.TBL_USERS.'.id
|
||||
LEFT JOIN '.TBL_USERSEEN.'
|
||||
ON '.TBL_DATA.'.id = '.TBL_USERSEEN.'.video_id AND '.TBL_USERSEEN.'.user_id = '.get_current_user_id().'
|
||||
LEFT JOIN '.TBL_MEDIATYPES.' ON mediatype = '.TBL_MEDIATYPES.'.id
|
||||
WHERE '.TBL_DATA.'.id = '.$id;
|
||||
$res = runSQL($SELECT);
|
||||
|
||||
// existing id?
|
||||
if (!count($res)) redirect('index.php');
|
||||
|
||||
// get the item
|
||||
$video = $res[0];
|
||||
|
||||
// is it editable/ copyable?
|
||||
$video['editable'] = localnet();
|
||||
$video['copyable'] = localnet();
|
||||
|
||||
// multi-user permissions
|
||||
if ($config['multiuser'])
|
||||
{
|
||||
$video['editable'] = $video['editable'] && check_permission(PERM_WRITE, get_userid($video['owner']));
|
||||
$video['copyable'] = $video['copyable'] && check_permission(PERM_WRITE, PERM_ANY);
|
||||
}
|
||||
|
||||
// save seen state
|
||||
if ($save)
|
||||
{
|
||||
set_userseen($id, $seen);
|
||||
$video['seen'] = $seen; // store in video for display
|
||||
}
|
||||
|
||||
// diskid to global scope:
|
||||
$diskid = $video['diskid'];
|
||||
|
||||
// check if it is lent and to whom- save query if id not set
|
||||
if ($diskid)
|
||||
{
|
||||
$SELECT = 'SELECT who
|
||||
FROM '.TBL_LENT."
|
||||
WHERE diskid = '".escapeSQL($diskid)."'";
|
||||
$result = runSQL($SELECT);
|
||||
|
||||
if (isset($result[0]['who']))
|
||||
{
|
||||
$video['who'] = $result[0]['who'];
|
||||
}
|
||||
}
|
||||
/*
|
||||
// append child episodes
|
||||
$SELECT = 'SELECT id, title, season, episode, plot
|
||||
FROM '.TBL_DATA.'
|
||||
WHERE '.TBL_DATA.'.parent_id = '.$id.'
|
||||
ORDER BY season, episode, title, subtitle';
|
||||
$episodes = runSQL($SELECT);
|
||||
|
||||
$video['episodes'] = $episodes;
|
||||
*/
|
||||
|
||||
// previous/next buttons
|
||||
$video['prev_id'] = 0;
|
||||
$video['next_id'] = 0;
|
||||
if (is_array($ids = session_get('query_result')))
|
||||
{
|
||||
if (($key = array_search($id, $ids)) !== false)
|
||||
{
|
||||
$video['prev_id'] = ($key > 0) ? $ids[$key-1] : 0;
|
||||
$video['next_id'] = ($key < count($ids)-1) ? $ids[$key+1] : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// breadcrumbs
|
||||
$breadcrumbs = session_get('breadcrumbs', array('current' => 0, 'crumbs' => array()));
|
||||
if (sizeof($breadcrumbs['crumbs']) > 10)
|
||||
$breadcrumbs['crumbs'] = array_slice($breadcrumbs['crumbs'], 0, -10);
|
||||
$breadcrumbs['current'] = $id;
|
||||
$breadcrumbs['crumbs'][] = array(
|
||||
'id' => $id,
|
||||
'title' => $video['title']);
|
||||
$size = sizeof($breadcrumbs['crumbs']);
|
||||
for ($i=0; $i < $size-1; $i++) {
|
||||
if ($breadcrumbs['crumbs'][$i]['id'] == $id) {
|
||||
unset($breadcrumbs['crumbs'][$size-1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
session_set('breadcrumbs', $breadcrumbs);
|
||||
}
|
||||
|
||||
if ($method == 'boxeePlay') {
|
||||
boxeePlay($video['filename']);
|
||||
}
|
||||
|
||||
// prepare templates
|
||||
tpl_page('detailview', $video['title']);
|
||||
if (!empty($id)) tpl_show($video);
|
||||
|
||||
// caching enabled?
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
require_once('./core/httpcache.php');
|
||||
httpCacheCaptureStart();
|
||||
}
|
||||
|
||||
// display templates
|
||||
smarty_display('header.tpl');
|
||||
if (!$config['http_caching']) flush();
|
||||
|
||||
if (!empty($id)) smarty_display('show.tpl', $id);
|
||||
|
||||
smarty_display('footer.tpl');
|
||||
|
||||
// caching enabled?
|
||||
if ($config['http_caching'])
|
||||
{
|
||||
httpCacheOutput('show'.$id, httpCacheCaptureEnd());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user