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:
2026-05-11 09:49:52 +02:00
commit f55c91276e
1230 changed files with 252321 additions and 0 deletions

View File

@@ -0,0 +1,141 @@
<?php
/**
* Add recommended movies via IMDB
*
* @package Contrib
* @author Andreas Goetz <cpuidle@gmx.de>
* @version $Id: add_recommended_movies.php,v 1.8 2014/02/25 21:22:00 kec2 Exp $
*/
// move out of contrib for includes
chdir('..');
require_once './core/functions.php';
require_once './engines/engines.php';
// since we don't need session functionality, use this as workaround
// for php bug #22526 session_start/popen hang
session_write_close();
?>
<html>
<head>
<title>Find Movie Recommendations</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="VideoDB" />
<style>
.green { color:green }
</style>
</head>
<body>
<?
error_reporting(E_ALL ^ E_NOTICE);
if ($submit)
{
// validate form data
$required_rating = (is_numeric($required_rating)) ? (float) $required_rating : '';
$required_year = (is_numeric($required_year)) ? (int) $required_year : '';
// get list of all videos
$SQL = 'SELECT * FROM '.TBL_DATA;
if (empty($wishlist)) $SQL .= ' WHERE mediatype != '.MEDIA_WISHLIST;
$result = runSQL($SQL);
foreach ($result as $video)
{
if (empty($video['imdbID'])) continue;
$engine = strtoupper(engineGetEngine($video['imdbID']));
echo "Fetching recommendations for <b>{$video['title']}</b> ($engine Id {$video['imdbID']})<br/>";
$data = engineGetRecommendations($video['imdbID'], $required_rating, $required_year, 'imdb');
if (!empty($CLIENTERROR))
{
echo $CLIENTERROR."<br/>";
continue;
}
if (empty($data))
{
// sometimes there are no recommendations for a movie. This is true for Underworld: imdbId 0320691
echo "No recommendations for {$video['title']}.<br/><br/>";
continue;
}
echo '<table border="1">';
echo " <tr>";
echo " <th>Title</th> <th>Year</th> <th>Rating</th> <th>Id</th>";
echo " </tr>";
foreach ($data as $recommended)
{
$available = (count(runSQL("SELECT * FROM ".TBL_DATA." WHERE imdbID like '%".$recommended['id']."'")) > 0);
if (!$available)
{
$recommended['title'] = '<a class="green" href="../edit.php?save=1&mediatype='.MEDIA_WISHLIST.'&lookup=1&imdbID='.$recommended['id'].
'&title='.urlencode($recommended['title']).'" target="_blank">'.$recommended['title'].' <img src="../images/add.gif" border="0"/></a>';
}
echo "<tr>";
echo "<td align=left width=\"65%\">{$recommended['title']}</td>";
echo "<td align=right width=\"10%\">{$recommended['year']}</td>";
echo "<td align=right width=\"10%\">{$recommended['rating']}</td>";
echo "<td align=right width=\"15%\">{$recommended['id']}</td>";
echo "</tr>";
if ($download && !$available) engineGetData($recommended['id']);
}
echo "</table>";
echo "<br/>";
}
}
else
{
?>
<form action="<?php echo $_SERVER['PHP_SELF']?>">
<table>
<tr valign="top">
<td>
Limit to movies to no earlier then
</td>
<td>
<input type="text" name="required_year" id="required_year" value="1980" />
</td>
</tr>
<tr valign="top">
<td>
At least require this rating
</td>
<td>
<input type="text" name="required_rating" id="required_rating" value="7.0" />
</td>
</tr>
</table>
<label for="wishlist">
<input type="checkbox" name="wishlist" id="wishlist" value="1" />
Include wishlist
</label>
<br />
<label for="download">
<input type="checkbox" name="download" id="download" value="1" />
Download recommendations if movie is not in videoDB
</label>
<br />
<input type="submit" name="submit" value="Search" />
</form>
<?
}
?>
</body>
</html>

View File

@@ -0,0 +1,202 @@
<?php
/**
* Borrow / return movie via barcode
*
* (c) 2005 GPL'd
*
* @package Contrib
* @author Chinamann <chinamann@users.sourceforge.net>
*
*/
chdir('..');
require_once './core/session.php';
require_once './core/functions.php';
require_once './core/genres.php';
require_once './core/custom.php';
require_once './core/security.php';
// check for localnet
localnet_or_die();
// multiuser permission check
permission_or_die(PERM_WRITE, $_COOKIE['VDBuserid']);
$SELECT = 'SELECT opt FROM '.TBL_CONFIG." WHERE LOWER(opt) LIKE 'custom_type' AND value = 'barcode'";
$result = runSQL($SELECT);
if (count($result)>0) $customFieldName = preg_replace('/type/','',$result[0]['opt']);
if (count($result) == 0) {
?>
<html>
<head>
<title>Borrow / return movie via barcode</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>Please select &qt;barcode&qt; as a custom field in the &qt;configuration&qt; tab.</body>
</html>
<?
} elseif (isset($_GET['process']) && $_GET['process'] != "") {
$notFound=-1;
if ($_GET['process'] == "BORROW") {
$who = escapeSQL(trim($_GET['borrowText']));
$barcode = trim($_GET['barcode']);
if ($who == '') {
$notFound=2;
} elseif ($barcode == '' || preg_match('/[^0-9]+/',$barcode)) {
$notFound=1;
} else {
$result = runSQL('SELECT diskid, '.$customFieldName.' AS barcode
FROM '.TBL_DATA.'
LEFT JOIN '.TBL_USERS.'
ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
WHERE '.TBL_USERS.".name = '".escapeSQL($_COOKIE['VDBusername'])."'".'
AND '.TBL_DATA.'.'.$customFieldName." LIKE '%".$barcode."'");
foreach($result as $row)
{
// missing zeros at the beginning?
if (($lenDiff = strlen($row['barcode'])-strlen($barcode))>0) {
// If there is a rotten apple - just skip
if (preg_match('/[^0]+/',substr($row['barcode'],0,$lenDiff))) {
continue;
}
}
$DELETE = 'DELETE FROM '.TBL_LENT.' WHERE diskid = '.escapeSQL($row['diskid']);
$INSERT = 'INSERT '.TBL_LENT." SET who = '".escapeSQL($who)."', diskid = '".escapeSQL($row['diskid'])."'";
runSQL($DELETE,false);
runSQL($INSERT);
$specialJsCode = "parent.mainFrame.location.href='../borrow.php';";
$notFound=0;
}
}
} else if ($_GET['process'] == "RETURN") {
$barcode = trim($_GET['barcode']);
if ($barcode == '' || preg_match('/[^0-9]+/',$barcode)) {
$notFound=1;
} else {
$result = runSQL('SELECT diskid, '.$customFieldName.' AS barcode
FROM '.TBL_DATA.'
LEFT JOIN '.TBL_USERS.'
ON '.TBL_DATA.'.owner_id = '.TBL_USERS.'.id
WHERE '.TBL_USERS.".name = '".escapeSQL($_COOKIE['VDBusername'])."'".'
AND '.TBL_DATA.'.'.$customFieldName." LIKE '%".$barcode."'");
foreach($result as $row)
{
// missing zeros at the beginning?
if (($lenDiff = strlen($row['barcode'])-strlen($barcode))>0) {
// If there is a rotten apple - just skip
if (preg_match('/[^0]+/',substr($row['barcode'],0,$lenDiff))) {
continue;
}
}
$DELETE = 'DELETE FROM '.TBL_LENT.' WHERE diskid = '.escapeSQL($row['diskid']);
runSQL($DELETE);
$specialJsCode = "parent.mainFrame.location.href='../borrow.php';";
$notFound=0;
}
}
}
?>
<html>
<head>
<title>Borrow / return movie via barcode</title>
<link rel="stylesheet" href="../<?php echo $config['style'] ?>" type="text/css" />
<script language="JavaScript">
<!--
function changed() {
if (document.barcodeForm.process.value == "BORROW") {
document.getElementsByName('borrowTextDesc')[0].style.display='';
document.barcodeForm.barcode.focus();
document.barcodeForm.barcode.select();
} else { // RETURN
document.getElementsByName('borrowTextDesc')[0].style.display='none;';
document.barcodeForm.barcode.focus();
document.barcodeForm.barcode.select();
}
}
function bgmonitor(field) {
if (field.defaultValue != field.value) {
document.barcodeForm.barcode.style.backgroundColor='';
document.barcodeForm.borrowText.style.backgroundColor='';
}
}
//-->
</script>
</head>
<body class="tablemenu" >
<TABLE width="100%" border="0" cellspacing="0" cellpadding="0">
<TR>
<TD align="left" valign="top" class="logo" style="font-size:16px;font-style:normal;float:left;">
<form name="barcodeForm" method="get" action="<?php echo $_SERVER['PHP_SELF']?>">
<select name="process" onChange="changed();">
<option value="BORROW" <?php if ($process=="BORROW" || $process=="LOAD") {?>selected<?php }?>>borrow</option>
<option value="RETURN" <?php if ($process=="RETURN") {?>selected<?php }?>>return</option>
</select>
barcode:
<?php
if ($notFound == 1) $textFieldStyleB='style="background-color:red;"';
elseif ($notFound == 2) $textFieldStyleT='style="background-color:red;"';
elseif ($notFound == 0) {
$textFieldStyleB='style="background-color:green;"';
$textFieldStyleT='style="background-color:green;"';
}
?>
<input type="text" <?php echo $textFieldStyleB ?> name="barcode" size="20" onkeydown="bgmonitor(this);" value="<?php echo $barcode ?>">
<span name="borrowTextDesc">
to:
<input type="text" <?php echo $textFieldStyleT ?> name="borrowText" size="20" onkeydown="bgmonitor(this);" value="<?php echo $borrowText ?>">
</span>
<input type="submit" name="submit" value="OK">
</form>
<script language="JavaScript">
<!--
changed();
<?php if ($notFound != 2) { ?>
document.barcodeForm.barcode.focus();
document.barcodeForm.barcode.select();
<?php } else { ?>
document.barcodeForm.borrowText.focus();
document.barcodeForm.borrowText.select();
<?php } ?>
<?php echo $specialJsCode ?>
//-->
</script>
</TD>
<TD align="right" valign="top" width="14"><a href="javascript:parent.location.href='../index.php';"><img src="../images/close.gif" width="14" height="14" alt="" border="0" /></a></TD>
</TR>
</TABLE>
</body>
</html>
<?
} else { // Frameset
?>
<html>
<head>
<title>Borrow / return movie via barcode</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<frameset name="fs1" rows="25,*" frameborder="NO" border="0" framespacing="0">
<frame name="topFrame" scrolling="NO" noresize src="<?php echo $_SERVER['PHP_SELF']?>?process=LOAD">
<frame name="mainFrame" src="../borrow.php">
</frameset>
<noframes>
<body>Please use a browser which supports frames!</body>
</noframes>
</html>
<?
}
?>

View File

@@ -0,0 +1,194 @@
<?php
/**
* Cleanup utility to remove unused images from cache folders
*
* @package Contrib
* @author Andreas Goetz <cpuidle@gmx.de>
* @modified Constantinos Neophytou <jaguarcy@gmail.com>
*/
// move out of contrib for includes
chdir('..');
require_once './core/functions.php';
require_once './core/setup.core.php';
?>
<html>
<head>
<title>Cleanup Image Cache</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="VideoDB" />
<!--
<link rel="stylesheet" href="../templates/modern/compact.css" type="text/css" />
-->
</head>
<body>
<?php
error_reporting(E_ALL ^ E_NOTICE);
// get list of all used images
//$SQL = "SELECT imgurl FROM videodata UNION SELECT imgurl FROM actors";
//$result = runSQL($SQL);
$coverSQL = "SELECT imgurl FROM ".TBL_DATA;
$actorSQL = "SELECT imgurl FROM ".TBL_ACTORS;
$coverResult = runSQL($coverSQL);
$actorResult = runSQL($actorSQL);
#dump($coverResult);
// find covers in cache
foreach ($coverResult as $val)
{
$url = $val['imgurl'];
if (preg_match("/\.(jpe?g|gif|png)$/i", $url, $matches))
{
// get the cache file name, honor manually uploaded files
if (preg_match('#^cache#i', $url))
$cache_file = $url;
else
cache_file_exists($url, $cache_file, CACHE_IMG, $matches[1]);
$covers[] = $cache_file;
$images[] = $cache_file;
}
}
// find actor images in cache
foreach ($actorResult as $val)
{
$url = $val['imgurl'];
if (preg_match("/\.(jpe?g|gif|png)$/i", $url, $matches))
{
// get the cache file name, honor manually uploaded files
if (preg_match('#^cache#i', $url))
$cache_file = $url;
else
cache_file_exists($url, $cache_file, CACHE_IMG, $matches[1]);
$actors[] = $cache_file;
$images[] = $cache_file;
}
}
$size = 0;
$coverSize = 0;
$actorSize = 0;
$unused = 0;
$coverNum = 0;
$actorNum = 0;
/**
* Check cache folder for expired entries
*
* @author Andreas Goetz
* @param string $dir cache folder
* @param boolean $all return list of all files (or outdated files)
* @return array $total, $expired, $files sum and list of total and expired files
*/
function analyzeCacheFolder($dir, $all = false)
{
global $config;
$files = array();
if ($handle = opendir($dir))
{
// read cache directory (note syntax, according to docs!)
while (false !== ($file = readdir($handle)))
{
// prevent deletion of hidden files (*nix) or directory references (Windows)
if (preg_match("/^\./", $file)) continue;
$cfile = "$dir/$file";
// file found?
if (!is_dir($cfile))
{
$total += filesize($cfile);
if ($all || !(time()-filemtime($cfile) < $config['IMDBage']))
{
$expired += filesize($cfile);
$files[] = $cfile;
}
}
// or hierarchical cache directories?
elseif ($config['hierarchical'])
{
// one-char directory name?
if (preg_match("/^\w$/", $file))
{
list($atotal, $aexpired, $afiles) = analyzeCacheFolder($cfile, $all);
$total += $atotal;
$expired += $aexpired;
$files = array_merge($files, $afiles);
}
}
}
closedir($handle);
}
return array($total, $expired, $files);
}
// get list of all images currently in cache
list($total, $foo, $files) = analyzeCacheFolder('cache/img', true);
if ($submit) dump('Deleting:');
// loop over cache files
foreach ($files as $file)
{
if (!in_array($file, $images))
{
$size += filesize($file);
$unused++;
if ($submit)
{
unlink($file);
dump($file);
}
}
elseif (in_array($file, $covers))
{
$coverSize += filesize($file);
$coverNum++;
}
elseif (in_array($file, $actors))
{
$actorSize += filesize($file);
$actorNum++;
}
}
echo sprintf("
$coverNum out of %d files with a size of %.2fMB are used for covers<br/>
$actorNum out of %d files with a size of %.2fMB are used for headshots<br/>
$unused out of %d files with a size of %.2fMB are currently unused<br/>",
count($files), $coverSize/(1024*1024),
count($files), $actorSize/(1024*1024),
count($files), $size/(1024*1024));
if ($unused)
{
if ($submit)
{
echo "$unused files with a size of ".round($size/(1024*1024),2)."Mb have been deleted<br/>";
}
?>
<form action=<?php echo $PHP_SELF?>>
<input type="submit" name="submit" value="Delete" />
</form>
<?php
}
?>
</body>
</html>

View File

@@ -0,0 +1,67 @@
<?php
/**
* transfer ownerless to moves to one user
*
* @package Contrib
* @author Chinamann <chinamann@users.sourceforge.net>
*
* @meta ACCESS:PERM_ADMIN
*/
// move out of contrib for includes
chdir('..');
require_once './core/functions.php';
require_once './core/output.php';
// check for localnet
localnet_or_die();
// multiuser permission check
permission_or_die(PERM_ADMIN);
$owners = out_owners(null, 0, true);
if (empty($owner_id)) $owner_id = $_COOKIE['VDBuserid'];
if ($convert)
{
runSQL("UPDATE ".TBL_DATA."
SET owner_id = ".$owner_id."
WHERE owner_id = 0");
// show the saved movie
header('Location: ../index.php');
exit();
}
else
{
?>
<html>
<head>
<title>Transfer ownerless movies to a user</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']?>">
<h3>Do you realy want to convert all ownerless movies to be owned by <SELECT name='owner_id'>
<?
foreach (array_keys($owners) as $owner)
{
if ($owner == $owner_id) $selected = "selected";
else $selected = "";
print "<OPTION $selected value='$owner'>".$owners[$owner]."</OPTION>\n";
}
?></SELECT> ?</h3>
<input type="submit" name="convert" value="Convert" />
</form>
<?
}
?>
</body>
</html>

View File

@@ -0,0 +1,135 @@
<?php
/**
* Produce a count of all actors in the database
*
* Code structure based on add_recommended_movies.php by Andreas Goetz
*
* @package Contrib
* @author Constantinos Neophytou <jaguarcy@gmail.com>
* @version $Id: count_actors.php,v 1.4 2007/09/08 09:17:16 andig2 Exp $
*/
// move out of contrib for includes
chdir('..');
require_once './core/functions.php';
?>
<html>
<head>
<title>List actor counts</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="VideoDB" />
</head>
<body>
<?
if ($submit)
{
// validate form data
$maxcount = (is_numeric($maxcount)) ? (int) $maxcount : 0;
// Build query - ignore duplicate imdbID fields
$query = 'SELECT DISTINCT `imdbID`, `director`, `actors` FROM '.TBL_DATA;
if (empty($wishlist)) $query .= ' WHERE mediatype != '.MEDIA_WISHLIST;
$result = runSQL($query);
$includeDirectors = !empty($director);
$actors = array(); // Actor array
// If we are counting the directors separately than the actors, create the array
if (empty($notseparate) && $includeDirectors) {
$directors = array();
$displayDirectorCount = true;
} else {
// Otherwise, use the actor array for directors as well.
$directors = &$actors;
$displayDirectorCount = false;
}
foreach ($result as $row)
{
$cast = split("\r?\n", $row['actors']);
// Counting actors
foreach ($cast as $actor) {
$actorary = split('::', $actor);
if (!isset($actors[$actorary[0]])) {
// Use actor name as array index so all counts are attributed to the same name
$actors[$actorary[0]] = 0;
}
$actors[$actorary[0]]++;
}
// Director count
if ($includeDirectors) {
if (!isset($directors[$row['director']])) {
$directors[$row['director']] = 0;
}
$directors[$row['director']]++;
}
}
// Sort array by actor appearances in reverse order (high to low)
arsort($actors);
$i = 1;
foreach ($actors as $key=>$val)
{
if ($val > $maxcount)
{
// Build name search url
$url = "../search.php?q=%22" . htmlentities(urlencode($key)) . "%22&isname=Y";
// Text for director counts
$dirText = '';
if ($displayDirectorCount && $directors[$key]) {
$dirText = ", " . $directors[$key] . " director entries";
}
echo "$i - <a href='$url'>$key</a>: $val actor entries" . $dirText . "<br />";
$i++;
}
}
} else {
?>
<form action="<?php echo $_SERVER['PHP_SELF']?>">
<label for="maxcount">
Only show names with more than
<input type="text" name="maxcount" id="maxcount" value="3" size="2" maxlength="2" />
actor entries
</label>
<br />
<label for="director">
<input type="checkbox" name="director" id="director" value="1" checked />
Count director entries (will appear next to the actor entries, will not be sorted)
</label>
<br />
<label for="notseparate">
<input type="checkbox" name="notseparate" id="notseparate" value="1" />
Count director entries as "actor" (i.e. don't separate them)
</label>
<br />
<label for="wishlist">
<input type="checkbox" name="wishlist" id="wishlist" value="1" />
Include wishlist
</label>
<br />
<br />
<input type="submit" name="submit" value="List" />
</form>
<br />
<small>Note: Duplicate movie entries (determined by imdbID) will not be counted.</small>
<?
}
?>
</body>
</html>

View File

@@ -0,0 +1,102 @@
<?php
/**
* Convert HTML entities to plain text
*
* @package Contrib
* @author Andreas Goetz <cpuidle@gmx.de>
* @version $Id: decode_entities.php,v 1.6 2008/01/23 09:06:25 andig2 Exp $
* @meta ACCESS:PERM_ADMIN
*/
// move out of contrib for includes
chdir('..');
require_once './core/functions.php';
require_once './engines/engines.php';
?>
<html>
<head>
<title>Decode HTML Entities</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="description" content="VideoDB" />
<!--
<link rel="stylesheet" href="../templates/modern/compact.css" type="text/css" />
-->
<style>
.green { color:green }
</style>
</head>
<body>
<?
error_reporting(E_ALL ^ E_NOTICE);
if (!$submit) echo "<h2>Warning- be sure to backup your data before submitting the cleanup request!</h2>";
$SQL = 'SELECT * FROM '.TBL_DATA;
$result = runSQL($SQL);
$count = 0;
foreach ($result as $video)
{
$SQL = '';
$keys = array();
foreach ($video as $key => $value)
{
if ($key == 'id') continue;
$new = html_clean_utf8($value);
if ($new != $value)
{
$keys[] = $key;
if ($SQL) $SQL .= ', ';
$SQL .= "$key = '".escapeSQL($new)."'";
}
}
if ($SQL)
{
$count++;
echo (($submit) ? 'Converting: ' : '<b>Conversion needed:</b> ').$video['title']."<br/>\n";
// actually perform the conversion?
if ($submit)
{
$SQL = "UPDATE ".TBL_DATA." SET $SQL WHERE id = ".$video['id'];
runSQL($SQL);
}
else
{
foreach($keys as $key)
{
echo $key.': '.htmlentities($video[$key])."<br/>\n";
}
echo "<br/>\n";
}
}
}
$action = ($submit) ? 'Converted' : 'Analyzed';
echo "$action $count of ".count($result)." movies.<br/>\n";
if (empty($submit))
{
?>
<form action="<?php echo $_SERVER['PHP_SELF']?>">
<input type="submit" name="submit" value="Convert" />
</form>
<?
}
?>
</body>
</html>

View File

@@ -0,0 +1,142 @@
#!/usr/bin/perl
use DBI;
#DB-Connection
$db_server = "localhost";
$db_user = "www";
$db_password = "leech";
$db_database = "VideoDB";
#output directory
$outdir = '/ftp/moviez/VideoDB/';
#imgcache
$imgcache = 'http://xerxes/videodb/imgcache';
#showurl
$showurl = 'http://xerxes/videodb/show.php';
#lynx
$lynx = '/usr/bin/lynx';
###############################################################################
#okay lets go
#delete old stuff
system("rm -rf $outdir/*");
#connect
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
#unseen nontv
$out = "$outdir/unseen";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE seen = 0
AND istv = 0";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
#unseen nontv
$out = "$outdir/unseen/tv";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE seen = 0
AND istv = 1";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
#seen nontv
$out = "$outdir/seen";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE seen = 1
AND istv = 0";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
#unseen tv
$out = "$outdir/seen/tv";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE seen = 1
AND istv = 1";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
#all nontv
$out = "$outdir";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE istv = 0";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
#all tv
$out = "$outdir/tv";
mkdir($out) unless(-e $out);
$SELECT = "SELECT id, title , subtitle
FROM videodata
WHERE istv = 1";
$result = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($result->[$row][0])){
&show($result->[$row][0],$result->[$row][1],$result->[$row][2],$out);
$row++;
}
###############################################################################
sub show($$$$){
my $id = $_[0];
my $title = $_[1];
my $subtitle = $_[2];
my $out = $_[3];
print '.';
my $name;
if ($subtitle ne ''){
$name = "$title - $subtitle.html";
}else{
$name = "$title.html";
}
my $output = `$lynx --dump --source '$showurl?id=$id'`;
# print "$lynx --dump '$showurl?id=$id'\n";
$output =~ m/<!-- content begin -->(.*)<!-- content end -->/is;
$output = $1;
$output =~ s/SRC="imgcache/SRC="$imgcache/is;
$output =~ s/<span CLASS="show_title">(.*?)<\/span>/<H1>$1/is;
$output =~ s/<span CLASS="show_subtitle">(.*?)<\/span>/$1<\/H1>/is;
open (FILE,">$out/$name") || die("file open '$out/$name' failed");
print FILE $output;
close FILE;
}

314
videodb/contrib/dvdadd.pl Normal file
View File

@@ -0,0 +1,314 @@
#!/usr/bin/perl
#program version
my $VERSION="0.1.0";
# Path to your lsdvd binary (http://acidrip.thirtythreeandathird.net/lsdvd.html)
$lsdvd = '/usr/bin/lsdvd';
# DVD drive to use (reads it from commandline)
$device = $ARGV[ 0 ];
$device = "/dev/cdrom" unless (defined($device));
# if you use the multiuser feature you may want to give an
# owner of the movies to add here - if you don't need it just
# set it to a blank string. It has to be a number for videoDB 2.x
$owner = 3;
# if you want to define what mediatype you are going to add (7=dvd-r 1=dvd)
$mediatype = 7;
# Database stuff
$driver = "mysql";
$database = "VideoDB";
$hostname = "localhost";
$user = "www";
$password = "leech";
################################################################################
use DBI;
use Data::Dumper;
#Connect to database
$dsn = "DBI:$driver:database=$database;host=$hostname";
$dbh = DBI->connect($dsn, $user, $password);
#quote this only once:
$owner = $dbh->quote($owner);
#prepare language codes
%lc = preparelc();
#work
&readlsdvd();
#disconnect
$dbh->disconnect();
#
###############################################################################
sub readlsdvd($)
{
my $output = `$lsdvd -t 1 -a -s -v -p $device`;
if ($output eq '')
{
print STDERR "running lsdvd failed - check pathnames\n";
exit 1;
}
eval($output);
# prepare for inserts
my $title = $dbh->quote($lsdvd{ title });
my $video_width = $dbh->quote($lsdvd{ track }[ 0 ]{ width });
my $video_height = $dbh->quote($lsdvd{ track }[ 0 ]{ height });
my $runtime = $dbh->quote(sprintf("%d", $lsdvd{ track }[ 0 ]{ 'length' } / 60));
# get languages... first is default, the next are written to custom1 and custom2 respectively (add custom3 and four if you want 4 languages
my $language1 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ langcode } });
my $language2 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 1 ]{ langcode } });
my $language3 = $dbh->quote($lc{ $lsdvd{ track }[ 0 ]{ audio }[ 2 ]{ langcode } });
# reads if PAL or NTSC and how many channels the audio has
my $audio_codec = $dbh->quote($lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ format } . ' ' . $lsdvd{ track }[ 0 ]{ audio }[ 0 ]{ channels } . ' channels');
# video codec is either PAL or NTSC ... Aspectratio is 16x9 or 4x3
my $video_codec = $dbh->quote($lsdvd{ track }[ 0 ]{ format });
my $aspectratio = $dbh->quote($lsdvd{ track }[ 0 ]{ aspect });
# just for those who want to use pixels instead of Aspectratio
my $videowidth = $dbh->quote($lsdvd{ track }[ 0 ]{ width });
my $videoheight = $dbh->quote($lsdvd{ track }[ 0 ]{ height });
# Get subtitles prepared... based on GPL code from acidrip-0.12
my $this_track = 0;
my $subtitle = "Subtitles: ";
foreach my $this_subp (@{ $lsdvd{ track }[ 0 ]->{ 'subp' } })
{
my $subp_ix = $this_subp->{ 'ix' };
my $label = $subp_ix . " " . $this_subp->{ 'language' };
$label .= "\: " . $this_subp->{ 'content' } if $this_subp->{ 'content' } ne "Undefined";
$subtitle = $subtitle . $label . "\, ";
}
# Detect aspect ratio and put into video width and height... comment if you prefer pixel count
if ($aspectratio = "16/9")
{
$video_width = "16";
$video_height = "9";
}
elsif ($aspectratio = "4/3")
{
$video_width = "4";
$video_height = "3";
}
# insert... remove both custom1 and custom2 if you use them for something else or change them to
# something different
#
# video_width can be replaced with $videowidth and video_height with $videoheight to achieve pixel
# count like width = 720, height = 576
my $INSERT = "INSERT INTO videodata
SET title = $title,
video_width = $video_width,
video_height = $video_height,
video_codec = $video_codec,
mediatype = $mediatype,
created = NOW(),
runtime = $runtime,
language = $language1,
custom1 = $language2,
custom2 = $language3,
audio_codec = $audio_codec,
comment = '$subtitle',
owner_id = $owner";
# comment if you are testing the script... this writes to the database
$dbh->do($INSERT);
#print $INSERT;
}
sub preparelc()
{
my %lc;
$lc{ 'aa' } = 'afar';
$lc{ 'ab' } = 'abkhazian';
$lc{ 'af' } = 'afrikaans';
$lc{ 'am' } = 'amharic';
$lc{ 'ar' } = 'arabic';
$lc{ 'as' } = 'assamese';
$lc{ 'ay' } = 'aymara';
$lc{ 'az' } = 'azerbaijani';
$lc{ 'ba' } = 'bashkir';
$lc{ 'be' } = 'byelorussian';
$lc{ 'bg' } = 'bulgarian';
$lc{ 'bh' } = 'bihari';
$lc{ 'bi' } = 'bislama';
$lc{ 'bn' } = 'bengali';
$lc{ 'bo' } = 'tibetan';
$lc{ 'br' } = 'breton';
$lc{ 'ca' } = 'catalan';
$lc{ 'co' } = 'corsican';
$lc{ 'cs' } = 'czech';
$lc{ 'cy' } = 'welsh';
$lc{ 'da' } = 'danish';
$lc{ 'de' } = 'german';
$lc{ 'dz' } = 'bhutani';
$lc{ 'el' } = 'greek';
$lc{ 'en' } = 'english';
$lc{ 'eo' } = 'esperanto';
$lc{ 'es' } = 'spanish';
$lc{ 'et' } = 'estonian';
$lc{ 'eu' } = 'basque';
$lc{ 'fa' } = 'persian';
$lc{ 'fi' } = 'finnish';
$lc{ 'fj' } = 'fiji';
$lc{ 'fo' } = 'faroese';
$lc{ 'fr' } = 'french';
$lc{ 'fy' } = 'frisian';
$lc{ 'ga' } = 'irish';
$lc{ 'gd' } = 'gaelic';
$lc{ 'gl' } = 'galician';
$lc{ 'gn' } = 'guarani';
$lc{ 'gu' } = 'gujarati';
$lc{ 'ha' } = 'hausa';
$lc{ 'he' } = 'hebrew';
$lc{ 'hi' } = 'hindi';
$lc{ 'hr' } = 'croatian';
$lc{ 'hu' } = 'hungarian';
$lc{ 'hy' } = 'armenian';
$lc{ 'ia' } = 'interlingua';
$lc{ 'id' } = 'indonesian';
$lc{ 'ie' } = 'interlingue';
$lc{ 'ik' } = 'inupiak';
$lc{ 'is' } = 'icelandic';
$lc{ 'it' } = 'italian';
$lc{ 'iu' } = 'inuktitut';
$lc{ 'ja' } = 'japanese';
$lc{ 'jw' } = 'javanese';
$lc{ 'ka' } = 'georgian';
$lc{ 'kk' } = 'kazakh';
$lc{ 'kl' } = 'greenlandic';
$lc{ 'km' } = 'cambodian';
$lc{ 'kn' } = 'kannada';
$lc{ 'ko' } = 'korean';
$lc{ 'ks' } = 'kashmiri';
$lc{ 'ku' } = 'kurdish';
$lc{ 'ky' } = 'kirghiz';
$lc{ 'la' } = 'latin';
$lc{ 'ln' } = 'lingala';
$lc{ 'lo' } = 'laothian';
$lc{ 'lt' } = 'lithuanian';
$lc{ 'lv' } = 'latvian';
$lc{ 'mg' } = 'malagasy';
$lc{ 'mi' } = 'maori';
$lc{ 'mk' } = 'macedonian';
$lc{ 'ml' } = 'malayalam';
$lc{ 'mn' } = 'mongolian';
$lc{ 'mo' } = 'moldavian';
$lc{ 'mr' } = 'marathi';
$lc{ 'ms' } = 'malay';
$lc{ 'mt' } = 'maltese';
$lc{ 'my' } = 'burmese';
$lc{ 'na' } = 'nauru';
$lc{ 'ne' } = 'nepali';
$lc{ 'nl' } = 'dutch';
$lc{ 'no' } = 'norwegian';
$lc{ 'oc' } = 'occitan';
$lc{ 'om' } = 'oromo';
$lc{ 'or' } = 'oriya';
$lc{ 'pa' } = 'punjabi';
$lc{ 'pl' } = 'polish';
$lc{ 'ps' } = 'pashto';
$lc{ 'pt' } = 'portuguese';
$lc{ 'qu' } = 'quechua';
$lc{ 'rm' } = 'rhaeto-romance';
$lc{ 'rn' } = 'kirundi';
$lc{ 'ro' } = 'romanian';
$lc{ 'ru' } = 'russian';
$lc{ 'rw' } = 'kinyarwanda';
$lc{ 'sa' } = 'sanskrit';
$lc{ 'sd' } = 'sindhi';
$lc{ 'sg' } = 'sangho';
$lc{ 'sh' } = 'serbo-croatian';
$lc{ 'si' } = 'sinhalese';
$lc{ 'sk' } = 'slovak';
$lc{ 'sl' } = 'slovenian';
$lc{ 'sm' } = 'samoan';
$lc{ 'sn' } = 'shona';
$lc{ 'so' } = 'somali';
$lc{ 'sq' } = 'albanian';
$lc{ 'sr' } = 'serbian';
$lc{ 'ss' } = 'siswati';
$lc{ 'st' } = 'sesotho';
$lc{ 'su' } = 'sundanese';
$lc{ 'sv' } = 'swedish';
$lc{ 'sw' } = 'swahili';
$lc{ 'ta' } = 'tamil';
$lc{ 'te' } = 'telugu';
$lc{ 'tg' } = 'tajik';
$lc{ 'th' } = 'thai';
$lc{ 'ti' } = 'tigrinya';
$lc{ 'tk' } = 'turkmen';
$lc{ 'tl' } = 'tagalog';
$lc{ 'tn' } = 'setswana';
$lc{ 'to' } = 'tonga';
$lc{ 'tr' } = 'turkish';
$lc{ 'ts' } = 'tsonga';
$lc{ 'tt' } = 'tatar';
$lc{ 'tw' } = 'twi';
$lc{ 'ug' } = 'uighur';
$lc{ 'uk' } = 'ukrainian';
$lc{ 'ur' } = 'urdu';
$lc{ 'uz' } = 'uzbek';
$lc{ 'vi' } = 'vietnamese';
$lc{ 'vo' } = 'volapuk';
$lc{ 'wo' } = 'wolof';
$lc{ 'xh' } = 'xhosa';
$lc{ 'yi' } = 'yiddish';
$lc{ 'yo' } = 'yoruba';
$lc{ 'za' } = 'zhuang';
$lc{ 'zh' } = 'chinese';
$lc{ 'zu' } = 'zulu';
return %lc;
}
__END__
=head1 NAME
dvdadd - reads DVD Video Data and writes it to videoDB
=head1 SYNOPSIS
reads DVD Video Data and writes it to videoDB
=head1 DESCRIPTION
reads DVD Video Data and writes it to videoDB using Perl and lsdvd. Linux or Unix is required, not tested on MS Windows.
=head1 SEE ALSO
videoDB http://videodb.sf.net
lsdvd 0.10 http://acidrip.thirtythreeandathird.net/lsdvd.html
perl http://perl.org
=head1 AUTHOR
Elkin Fricke, videoDB DevTeam.
=head1 LICENSE
VideoDB is released under the GNU General Public License (GPL)
See COPYING for more Info
VideoDB comes with the Smarty Template Engine
Smarty is released under the GNU Lesser General Public License (LGPL)
See COPYING.lib in the smarty directory for more Info
=cut

View File

@@ -0,0 +1,152 @@
<?php
/**
* Refresh whole IMDB info (rund from command line)
*
* This script should be executed from command line
* Look for the NOTE: comments to change behavior
* The script should be placed under videodb/contrib and run as "php fetch_imdb_all.php"
*
* @package Contrib
* @author Alex Mondshain <alex_mond@yahoo.com>
*/
chdir('..');
require_once './engines/engines.php';
require_once './core/functions.php';
require_once './core/genres.php';
require_once './core/custom.php';
require_once './core/edit.core.php';
//Id is imdb id
//lookup is either 1 (add missing) or 2 (overwrite)
function FetchSaveMovie($id,$lookup)
{
$debug = 0;
$video = runSQL('SELECT * FROM '.TBL_DATA.' WHERE id = '.$id);
// get fields (according to list) from db to be saved later
if ($debug){
echo "\n=================== Video DB Data ============================\n";
print_r( $video[0]);
echo "\n=================== Video DB Data ============================\n";
}
$imdbID = $video[0]['imdbID'];
echo "Movie/imdb -- ".$video[0]['title']."/".$video[0]['imdbID']."\n";
if (empty($imdbID)) {
echo "No imdbID\n";
return;
}
if (empty($engine)) $engine = engineGetEngine($imdbID);
if ($debug) {
echo "IMDBID = $imdbID, engine = $engine\n";
}
$imdbdata = engineGetData($imdbID, $engine);
# removed due to performance issues of is_utf8
// fix erroneous IMDB encoding issues
if (!is_utf8($imdbdata)) {
echo "Applying encoding fix\n";
$imdbdata = fix_utf8($imdbdata);
}
if (empty($imdbdata[title])) {
echo "Fetch failed , try again...\n";
$imdbdata = engineGetData($imdbID, $engine);
}
if (empty($imdbdata[title])) {
echo "Fetch failed again , next movie";
return;
}
if ($debug) {
echo "\n=================== IMDB Data ============================\n";
print_r($imdbdata);
echo "\n=================== IMDB Data ============================\n";
}
if (!empty($imdbdata[title])) {
//
// NOTE: comment out any of the following lines if you do not want them updated
//
$video[0][title]=$imdbdata[title];
$video[0][subtitle]=$imdbdata[subtitle];
$video[0][year]=$imdbdata[year];
$video[0][imgurl]=$imdbdata[coverurl];
$video[0][runtime]=$imdbdata[runtime];
$video[0][director]=$imdbdata[director];
$video[0][rating]=$imdbdata[rating];
$video[0][country]=$imdbdata[country];
$video[0][language]=$imdbdata[language];
$video[0][actors]=$imdbdata[cast];
$video[0][plot]=$imdbdata[plot];
}
if (count($genres) == 0 || ($lookup > 1))
{
$genres = array();
$gnames = $imdbdata['genres'];
if (isset($gnames))
{
foreach ($gnames as $gname)
{
// check if genre is found- otherwise fail silently
if (is_numeric($genre = getGenreId($gname))) {
$genres[] = $genre;
} else {
echo "MISSING GENRE $gname\n";
}
}
}
}
// custom filds , not working for now
for ($i=1; $i<=4; $i++)
{
$custom = 'custom'.$i;
$type = $config[$custom.'type'];
if (!empty($type))
{
// copy imdb data into corresponding custom field
$video[0][$custom]=$imdbdata[$type];
echo "CUSTOM $custom $type = $imdbdata[$type]\n";
}
}
// -------- SAVE
$SETS = prepareSQL($video[0]);
if ($debug) {
echo "\n=================== Final Data ============================\n";
echo "SETS = $SETS \n";
echo "\n=================== Final Data ============================\n";
}
$id = updateDB($SETS, $id);
// save genres
setItemGenres($id, $genres);
// set seen for currently logged in user
set_userseen($id, $seen);
}
// NOTE: Edit this line if you want to update specific set of files by adding WHERE statment
$allids = runSQL('SELECT id FROM '.TBL_DATA);
foreach ($allids as $id) {
#if ($id['id'] <= 2113) continue;
echo "Updating ID:".$id['id']."\n";
FetchSaveMovie($id['id'],3);
}
// for testing
// FetchSaveMovie(1,3);
?>

View File

@@ -0,0 +1,7 @@
<html>
<head>
<meta http-equiv="refresh" content="0; URL=../contrib.php">
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,116 @@
<?php
/**
* Language Checker
*
* Checks languagefiles for completeness
*
* @package Contrib
* @version $Id: langcheck.php,v 1.7 2013/03/10 17:08:36 andig2 Exp $
*/
$LANGDIR = '../language';
$base_lang = 'en';
#include($LANGDIR.'/'.$base_lang.'_withtooltips.php');
$tooltip_lang = array(); # $lang
unset($lang);
include($LANGDIR.'/en.php');
error_reporting(E_WARNING);
?>
<html>
<head>
<title>Translation statistics</title>
</head>
<body>
<?php
function printlang($missing, $code, $type)
{
$c = count($missing);
print '<b>'.$code.'</b> ';
if ($c)
{
print $c.' translations '.$type;
print '<br /><br />';
foreach($missing as $key)
{
print $key.'<br />';
}
}
else
{
print 'complete';
}
print '<br /><hr noshade="noshade" size="1" />';
}
function getlangs(&$tooltipLangs)
{
global $LANGDIR;
if ($dh = opendir($LANGDIR))
{
while (($file = readdir($dh)) !== false)
{
if(preg_match("/(.*)\.php$/",$file,$matches))
{
$langs[]=$matches[1];
if(substr($file, -16) == "withtooltips.php")
{
$tooltipLangs[] = $matches[1];
}
}
}
closedir($dh);
}
else
{
print "could not open language directory $LANGDIR";
exit;
}
return $langs;
}
function loadlang($code)
{
global $LANGDIR;
include($LANGDIR.'/'.$code.'.php');
return $lang;
}
foreach(getlangs($tooltipLangs) as $code) if ($base_lang !== $code)
{
$foreign = loadlang($code);
$missing = array();
$identical = array();
$useLang = $lang;
foreach (array_keys($useLang) as $key)
{
if(empty($foreign[$key]))
{
$missing[]=$key;
}
if ($useLang[$key] == $foreign[$key])
{
$identical[] = $key;
}
}
printlang($missing, $code, 'missing');
if ($_GET['copycheck']) printlang($identical, $code, 'identical');
}
?>
</body>
</html>

View File

@@ -0,0 +1,97 @@
<?php
/**
* Add a DVD/Video to VideoDB via the barcode on the box
* (c) 2004 GPL'd
*
* @package Contrib
* @author Andrew Pritchard <videodb@teppic.homeip.net>
* @version $Id: lookup_barcode.php,v 1.4 2007/09/08 09:17:16 andig2 Exp $
*/
chdir('..');
require_once('./core/functions.php');
$notFound = 0;
if (isset($_GET['barcode']))
{
// Base URL for the search
$url = 'http://s1.amazon.co.uk/exec/varzea/sdp/sai-condition/';
// Add our post options and get the data
$post = 'sdp-sai-asin='.$_GET['barcode'];
$amazon_data = httpClient ($url, 0, $post);
// If it succeeds....
if ($amazon_data['success'] == 1)
{
if (preg_match("/<b class=\"sans\">(.*)<\/b>/", $amazon_data['data'], $matches))
{
if ($matches[1] == 'Identify the exact item you&//039;re selling')
{
$notFound = 1;
}
else
{
$media_type = 1;
$title = urlencode($matches[1]);
if (preg_match("/http:\/\/www.amazon.co.uk\/exec\/obidos\/ASIN\/(.*)\//", $amazon_data, $matches))
{
$asin_number = "ASIN: $matches[1]";
}
else
{
$asin_number = 'ASIN not found';
}
if (preg_match("/alt=\"VHS\"/", $amazon_data['data'], $matches))
{
$media_type = 6;
}
header("Location: ../edit.php?save=1&lookup=1&title=$title&diskid={$_GET['barcode']}&mediatype=$media_type&subtitle=$asin_number");
}
}
else
{
$notFound = 2;
}
}
else
{
// Print the error message
print "Failed to download:<br>\n";
print $amazon_data['error'];
}
}
?>
<html>
<head>
<title>Add movie by Amazon-UK barcode</title>
</head>
<body>
<h1>Add movie by Amazon-UK barcode</h1>
<form name="addbarcode" method="get" action="<?php echo $_SERVER['PHP_SELF']?>">
<input type="text" name="barcode" size="20">
<input type="submit" name="submit" value="Submit">
<input type="reset" name="reset" value="Reset">
</form>
<script language="JavaScript">
<!--
document.addbarcode.barcode.focus();
//-->
</script>
<?php
if ($notFound == 1)
{
print "Sorry - your barcode wasn't found at Amazon<br>\n";
//print_r($amazon_data);
}
elseif ($notFound == 2)
{
print "No data returned!<br>\n";
print_r($amazon_data);
}
?>
</body>
</html>

View File

@@ -0,0 +1,265 @@
<?php
/**
* mass_add.php
*
* Form for batch importing entries based on imdb id's.
*
* Changelog:
* vv0.000000.1e-100000000 Initial version by Branko Kokanovic
* v0.2 seen attribute now stored in userseen table - Alrik Bronsema
*
* @todo Optional check for duplicate entries.
*
* @package Contrib
* @author Branko Kokanovic
* @author Alrik Bronsema <alrikb@gmail.com>
* @version $Id: mass_add.php,v 1.2 2007/07/27 10:09:07 andig2 Exp $
*/
chdir('..');
require_once './core/functions.php';
require_once './core/genres.php';
require_once './core/custom.php';
require_once './core/security.php';
?>
<html>
<head>
<title>Mass IMDB movie add</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<?php
//slightly modified VideoDB function that does pretty much the same thing
function InsertMovie($imdb_id,&$ret_title,$seen,$mediatype){
$imdb_set_fields = array('md5','title','subtitle','language','diskid','mediatype','comment','disklabel',
'imdbID','year','imgurl','director','actors','runtime','country','plot','filename',
'filesize','filedate','audio_codec','video_codec','video_width','video_height','istv',
'custom1','custom2','custom3','custom4');
//fetching all the data
$imdbdata=engineGetData($imdb_id);
if ($imdbdata['title']=='') return 0;
//sorting needed things
//genres--------------------------
$genres = array();
$gnames = $imdbdata['genres'];
if (isset($gnames))
{
foreach ($gnames as $gname)
{
// check if genre is found- otherwise fail silently
if (is_numeric($genre = getGenreId($gname)))
{
$genres[] = $genre;
}
}
}
//--------------------------------
//actors
$actors = $imdbdata['cast'];
//movie owner---------------------
if (check_permission(PERM_WRITE, $_COOKIE['VDBuserid'])){
$owner_id = $_COOKIE['VDBuserid'];
}else{
$owner_id=0;
}
//--------------------------------
//cover
$imgurl = $imdbdata['coverurl'];
// lookup all other fields
foreach (array_keys($imdbdata) as $name){
if (in_array($name, array('coverurl', 'genres', 'cast', 'id'))) continue;
$$name = $imdbdata[$name];
}
//year
if (empty($year)) $year = '0000';
// set owner
if (!empty($owner_id))
$SETS = 'owner_id = '.escapeSQL($owner_id);
$imdbID=$imdb_id;
// update all fields according to list
foreach ($imdb_set_fields as $name){
// sanitize input
$$name = removeEvilTags($$name);
// make sure no formatting contained in basic data
if (in_array($name, array('title', 'subtitle'))){
$$name = trim(strip_tags($$name));
// string leading articles?
if ($config['removearticles']){
foreach ($articles as $article){
if (preg_match("/^$article+/i", $$name)){
$$name = trim(preg_replace("/(^$article)(.+)/i", "$2, $1", $$name));
break;
}
}
}
}
$SET = "$name = '".escapeSQL($$name)."'";
if (empty($$name)){
if (in_array($name, $db_null_fields))
$SET = "$name = NULL";
elseif (in_array($name, $db_zero_fields))
$SET = "$name = 0";
}
if ($SETS) $SETS .= ', ';
$SETS .= $SET;
}
//inserting into database--------------------
$INSERT = 'INSERT INTO '.TBL_DATA.' SET '.$SETS.', created = NOW()';
//print_r($INSERT);
//echo "<br><br>";
$id = runSQL($INSERT);
// save genres
setItemGenres($id, $genres);
//-------------------------------------------
// insert userseen data
$INSERTSEEN = 'INSERT INTO `userseen` (`video_id`, `user_id`) VALUES ('.$id.','.$owner_id.')';
runSQL($INSERTSEEN);
$ret_title=$title;
return 1;
}
if ((isset($_POST['Submit'])) && (is_uploaded_file($_FILES['id_list']['tmp_name']))){
//lets set time limit of we can
set_time_limit(30000);
$filename = $_FILES['id_list']['tmp_name'];
echo "File uploaded. Starting fetching and inserting into database...<br>";
ob_flush();
flush();
//get seen field from form
$seen=isset($_POST['seen'])?1:0;
//get mediatype id from form
$mediatype=$_POST['mediatype'];
$lines=file($filename);
//iterate for all lines in uploaded file
foreach( $lines as $line){
//trim \n from end of line
$line=rtrim($line);
//if line is empty, go to the next line
if ($line=="") continue;
//if we import by title, first get id from best matcing title
if ($_POST['import_type']=='title'){
$all=engineSearch($line);
$id=$all[0][id];
}
else{
$id=$line;
}
if (strpos($id,"imdb:")===false){
$id="imdb:".$id;
}
//try to insert movie
if (InsertMovie($id,&$title,$seen,$mediatype)==1){
echo "<a href=\"http://www.imdb.com/title/tt".substr($id,-7)."/\">$title</a> inserted ";
if ($_POST['import_type']=='title'){
echo "(additional info - title form file was $line)";
}
echo "<br>";
}
else{ //ops, error
echo "Error while inserting ID - ".$id." (additional info - ";
if ($_POST['import_type']=='title')
echo "title from file was $line) <br>";
else{
echo "id from file was $line) <br>";
}
}
ob_flush();
flush();
}
}
?>
<h1>Mass IMDB movie add v0.2</h1><br>
Ok, here is the thing:<br>
1. Browse for file with movie data (imdb ids or titles), hit Submit and pray:)
<br>
2. Script will try to set time limit, but this also depends from PHP configuration, so if script stops before all movies has been entered, check for PHP config.
<br>
3. File you need to browse is in form - one line per movie. So, if you want to import imdb ids, it should be something like:
<br>
<center>
0088247
<br>
0088248
<br>
or
<br>
imdb:0088247
<br>
imdb:0088248
<br>
</center>
and for titles:
<br>
<center>
terminator
<br>
terrible joe moran
<br>
</center>
In second case (import by titles), first matching title will be imported.
<br>
4. You must be logged to VideoDB as user who has write access (i.e. you can add movies on your own). All imported movies will be assigned to you. If you don't have write access or you are not logged, owner id will be 0.
<br>
5. Backup your data, make sure nothing can be lost, no responsibility, blah, blah...you already know it all.
<br>
<br>
<form action="" method="post" enctype="multipart/form-data" name="form" id="form">
<input name="import_type" type="radio" value="id" checked="checked" /> Import by ids
<br>
<input name="import_type" type="radio" value="title" /> Import by titles
<br>
<input type="checkbox" name="seen" value="1" /> Set all movies as seen
<br>
Media type:
<select name="mediatype">
<?php
$first=false;
$ret=runSQL("SELECT * FROM mediatypes");
foreach($ret as $mediatype){
if ($first==false){
$first=true;
echo "<option value=\"$mediatype[id]\" selected=\"selected\">$mediatype[name]</option>";
}
else{
echo "<option value=\"$mediatype[id]\">$mediatype[name]</option>";
}
}
?>
</select>
<br>
Import list:<input type="file" name="id_list" />
<br>
<input type="submit" name="Submit" value="Mass add" />
</form>
<br>
</body>
</html>

30
videodb/contrib/mklist.pl Normal file
View File

@@ -0,0 +1,30 @@
#!/usr/bin/perl
use DBI;
$db_server = "localhost";
$db_user = "www";
$db_password = "leech";
$db_database = "VideoDB";
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
$SELECT = "SELECT filename, filesize, diskid
FROM videodata
ORDER BY filename";
$result = $dbh->selectall_arrayref($SELECT);
print "DiskID\tSize\t\tFilename\n";
print "-"x74;
print "\n";
$row=0;
while (defined($result->[$row][0])){
printf("%s\t",$result->[$row][2]);
printf("%3.2f MB\t",($result->[$row][1]/(1024*1024)));
printf("%s\n",$result->[$row][0]);
$row++;
}

View File

@@ -0,0 +1,276 @@
<?php
/**
* Refetch and overwrite all movie information by according engine
*
* (c) 2005 GPL'd
*
* @package Contrib
* @author Chinamann <chinamann@users.sourceforge.net>
* @meta ACCESS:PERM_ADMIN
*/
chdir('..');
require_once './core/functions.php';
require_once './core/custom.php';
require_once './core/security.php';
require_once './engines/engines.php';
require_once './core/compatibility.php';
// check for localnet
localnet_or_die();
// multiuser permission check
permission_or_die(PERM_WRITE);
/**
* Fetch a list of all editable video fields (keys)
* and assign 1 (value) if they should be preselected else 0
*/
function getFields()
{
$edit_file = file_get_contents('./core/edit.core.php');
$edit_file = preg_replace("/\n/",'',$edit_file);
if (preg_match('/\$imdb_set_fields\s*=\s*array\s*\((.*?)\)/', $edit_file, $fieldslist) &&
preg_match('/\$imdb_overwrite_fields.*?array\s*\((.*?)\)/', $edit_file, $overwritelist))
{
$fields = array_map('trim', split(',', preg_replace("/'/", '', $fieldslist[1])));
$overwrites = array_map('trim', split(',', preg_replace("/'/", '', $overwritelist[1])));
$ret = array();
foreach ($fields as $field)
{
$value = (in_array($field, $overwrites)) ? 1 : 0;
if (preg_match('/custom/', $field)) $value = 0;
$ret = array_merge ($ret, array($field => $value));
}
return $ret;
}
}
if (!check_permission(PERM_ADMIN)) {
?>
<html>
<head>
<title>Refetch all external engine information</title>
<meta http-equiv="refresh" content="0; URL=../index.php">
<META http-equiv="Content-Style-Type" content="text/html">
</head>
<body>
</body>
</html>
<?php
}
else
{
if (isset($submit) && $submit == "Yes")
{
$contribUrl = "http://".$_SERVER['SERVER_NAME'].":".$_SERVER['SERVER_PORT']
.substr($_SERVER['PHP_SELF'],0,strrpos ( $_SERVER['PHP_SELF'], '/' ));
$baseUrl = substr($contribUrl,0,strrpos ($contribUrl, '/'));
// get list movies in DB
$SQL = 'SELECT * FROM '.TBL_DATA;
if ($user != '0') $SQL .= ' WHERE owner_id = '.$user;
$result = runSQL($SQL);
$CLIENTERRORS = array();
$CLIENTOKS = array();
$diskid = 0;
foreach ($result as $video)
{
$diskid++;
// Filter movies of unselected Users.
// if ($user != '0' && $video['owner_id'] != $user) continue;
// Filter movies of unselected Engines
if ($selectedengine != 'all' && engineGetEngine($video['imdbID']) != $selectedengine) continue;
// new DiskID ?
if (isset($resetDI) && $resetDI == "true")
{
$didigits = $GLOBALS['config']['diskid_digits'];
if (empty($didigits)) $didigits = 4;
$newId=sprintf('%0'.$didigits.'d',$diskid);
// make sure lent table is changed too
$SELECT = "SELECT diskid FROM ".TBL_DATA." WHERE id = ".$video['id'];
$oldDiskId = runSQL($SELECT);
$UPDATE = "UPDATE ".TBL_LENT." SET diskid = 'TMP".$newId."' WHERE diskid = '".$oldDiskId[0]['diskid']."'";
runSQL($UPDATE);
$UPDATE = "UPDATE ".TBL_DATA." SET diskid = '".$newId."' WHERE id = ".$video['id'];
runSQL($UPDATE);
}
// cannot refetch without external id
if (empty($video['imdbID'])) continue;
set_time_limit(300); // raise per movie execution timeout limit if safe_mode is not set in php.ini
$id = $video['id'];
$imdbID = $video['imdbID'];
$engine = engineGetEngine($video['imdbID']);
$fieldlist = "";
foreach (array_keys($_POST) as $param)
{
if (preg_match('/^(update_.*)/',$param,$fieldname))
{
$fieldlist .= "&".$fieldname[1]."=1";
}
}
$url = $baseUrl."/edit.php?id=".$id."&engine=".$engine."&save=1&lookup=".$lookup.$fieldlist;
$resp = httpClient($url, false, array('cookies' => $_COOKIE, 'no_proxy' => true, 'no_redirect' => true));
if (!$resp['success'])
{
$CLIENTERRORS[] = $video['title']." (".$video['diskid']."/".engineGetEngine($video['imdbID'])."): ".$resp['error'];
}
else $CLIENTOKS[] = $video['title']." (".$video['diskid']."/".engineGetEngine($video['imdbID']).")";
}
if (isset($resetDI) && $resetDI == "true")
{
// fix lent table after upper temp. changes
$SELECT = "SELECT diskid FROM ".TBL_LENT." WHERE diskid like 'TMP%'";
$lentResult = runSQL($SELECT);
foreach ($lentResult as $lentRow)
{
$diskid = preg_replace('/^TMP/','',$lentRow['diskid']);
$UPDATE = "UPDATE ".TBL_LENT." SET diskid = '".$diskid."' WHERE diskid = 'TMP".$diskid."'";
runSQL($UPDATE);
}
}
?>
<html>
<head>
<title>Refetch all external engine information</title>
</head>
<body>
<h1>Report</h1><p>
<h2>ERROR:</h2><p>
<?php foreach ($CLIENTERRORS as $error) { ?>
<?php echo $error ?>
<br>
<?php } ?>
<h2>SUCCESS:</h2><p>
<?php foreach ($CLIENTOKS as $ok) { ?>
<?php echo $ok ?>
<br>
<?php } ?>
</body>
</html>
<?php
}
elseif (isset($submit) && $submit == "LOAD")
{
?>
<html>
<head>
<title>Refetch all external engine information</title>
<link rel="stylesheet" href="../<?php echo $config['style'] ?>" type="text/css" />
</head>
<body style="font-size: 16px">
<form method="post" action="<?php echo $_SERVER['PHP_SELF']?>" target="mainFrame" onSubmit="alert('This may take a LONG time (dependent on movie count and connection speed)!!!');">
<div>
<div style="float:right">
<a href="javascript:parent.location.href='../index.php';"><img src="../images/close.gif" width="14" height="14" alt="" border="0" /></a>
</div>
Refetch and overwrite selected fields of movies for this User:
<select name="user">
<option value="0" selected="selected">All Users</option>
<?php
$SQL = 'SELECT name, id FROM '.TBL_USERS;
$result = runSQL($SQL);
foreach ($result as $user)
{
print '<option value="'.$user['id'].'">'.$user['name']."</option>\n";
}
?>
</select>
</div>
<div>
Update fields only for movies fetched by this engine:
<select name="selectedengine">
<option value="all" selected="selected">All Engines</option>
<?php
global $config;
foreach ($config['engines'] as $engine => $meta)
{
print '<option value="'.$engine.'">'.$meta['name']."</option>\n";
}
?>
</select>
</div>
<div>
Data Lookup:
<label for="lookup1"><input type="radio" name="lookup" id="lookup1" value="5" checked = "checked" />add missing</label>
<label for="lookup2"><input type="radio" name="lookup" id="lookup2" value="6" />overwrite</label>
</div>
<div>
<table><tr>
<?
$fields_in_a_row = 6;
$fields = getFields();
$keys = array_keys($fields);
$field_amount = count($keys);
for($i = 0; $i < $field_amount; $i++)
{
$checked = ($fields[$keys[$i]] == 1) ? "checked" : "";
if ($i % $fields_in_a_row == 0 && $i != 0) print "</TR><TR>";
print '<TD nowrap="nowrap"><input type="checkbox" name="update_'.$keys[$i].'" value="1" '.$checked.' />'.$keys[$i].'</TD>';
}
for ($i = 0; $i < ($fields_in_a_row - ($field_amount % $fields_in_a_row)); $i++) {
print '<TD>&nbsp;</TD>';
}
?>
</tr></table>
</div>
<div>
reset DiskIDs FOR ALL MOVIES AND ALL USERS?<input type="checkbox" name="resetDI" value="true" />
</div>
<div>
Are you shure to know what you are doing?
<input type="submit" name="submit" value="Yes">
<input type="button" value="No" onClick="parent.location.href='../index.php';">
</div>
</form>
</body>
</html>
<?php
} else {
?>
<html>
<head>
<title>Refetch all external engine information</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<frameset name="fs1" rows="260,*" frameborder="NO" border="0" framespacing="0">
<frame name="topFrame" scrolling="NO" noresize src="<?php echo $_SERVER['PHP_SELF']?>?submit=LOAD">
<frame name="mainFrame" src="">
</frameset>
<noframes>
<body>Please use a browser which supports frames!</body>
</noframes>
</html>
<?php
}
}
?>

View File

@@ -0,0 +1,54 @@
#!/usr/bin/perl
# Set title
$TITLE="South Park";
# Set genres (see list below for ids)
@GENRES=(4,3);
# 1 Action
# 2 Adventure
# 3 Animation
# 4 Comedy
# 5 Crime
# 6 Documentary
# 7 Drama
# 8 Family
# 9 Fantasy
# 10 Film-Noir
# 11 Horror
# 12 Musical
# 13 Mystery
# 14 Romance
# 15 Sci-Fi
# 16 Short
# 17 Thriller
# 18 War
# 19 Western
$db_server = "localhost";
$db_user = "www";
$db_password = "leech";
$db_database = "VideoDB";
######################################################################
use DBI;
$dbh = DBI->connect("dbi:mysql:$db_database:$db_server",$db_user,$db_password) || die("Can't connect");
$SELECT = "SELECT id from videodata
WHERE title LIKE '$TITLE'";
$idr = $dbh->selectall_arrayref($SELECT);
$row=0;
while (defined($idr->[$row][0])){
my $id = $idr->[$row][0];
#clear existing genres:
$dbh->do("DELETE FROM videogenre WHERE id = $id");
#insert new genres
foreach my $gid (@GENRES){
$dbh->do("INSERT INTO videogenre SET id = $id, gid = $gid");
}
$row++;
}

View File

@@ -0,0 +1,7 @@
# This SQL statement changes the owner of all unowned movies be sure to change
# NEWOWNER to the name of the user who should own the movies.
UPDATE videodata
SET owner = 'NEWOWNER'
WHERE owner IS NULL
OR owner = '';

View File

@@ -0,0 +1,177 @@
<?php
/**
* UTF-8 Migration Utility
*
* @package Contrib
* @author Andreas Goetz <cpuidle@gmx.de>
* $Id: utf_migration.php,v 1.2 2008/01/06 12:30:00 andig2 Exp $
*/
chdir('..');
require_once './core/functions.php';
require_once './core/encoding.php';
?>
<html>
<head>
<title>Migrate database contents to UTF-8</title>
<meta http-equiv="Content-Type" content="text/html; charset=<?=$targetencoding?>" />
</head>
<body>
<b>
Attention: Be sure to perform a backup before running the encoding migration!
</b>
<h2>1. Choose source and target encoding</h2>
<form action="<?=$PHP_SELF?>">
<div>
Source encoding:
<select name="sourceencoding">
<option value="iso-8859-1" <? if($sourceencoding=='iso-8859-1'|| empty($sourceencoding)) echo 'selected="selected"' ?>>iso-8859-1</option>
<option value="iso-8859-7" <? if($sourceencoding=='iso-8859-7') echo 'selected="selected"' ?>>iso-8859-7</option>
<option value="iso-8859-9" <? if($sourceencoding=='iso-8859-9') echo 'selected="selected"' ?>>iso-8859-9</option>
<option value="windows-1251" <? if($sourceencoding=='windows-1251') echo 'selected="selected"' ?>>windows-1251</option>
<option value="koi8-r" <? if($sourceencoding=='koi8-r') echo 'selected="selected"' ?>>koi8-r</option>
<option value="utf-8" <? if($sourceencoding=='utf-8') echo 'selected="selected"' ?>>utf-8</option>
</select>
</div>
<div>
Target encoding:
<select name="targetencoding">
<option value="iso-8859-1" <? if($sourceencoding=='iso-8859-1') echo 'selected="selected"' ?>>iso-8859-1</option>
<option value="iso-8859-7" <? if($targetencoding=='iso-8859-7') echo 'selected="selected"' ?>>iso-8859-7</option>
<option value="iso-8859-9" <? if($targetencoding=='iso-8859-9') echo 'selected="selected"' ?>>iso-8859-9</option>
<option value="windows-1251" <? if($targetencoding=='windows-1251') echo 'selected="selected"' ?>>windows-1251</option>
<option value="koi8-r" <? if($targetencoding=='koi8-r') echo 'selected="selected"' ?>>koi8-r</option>
<option value="utf-8" <? if($targetencoding=='utf-8' || empty($targetencoding)) echo 'selected="selected"' ?>>utf-8</option>
</select>
</div>
<div>
Simulate only: <input type="checkbox" name="simulate" checked="checked" />
</div>
<input type="submit" value="Submit" />
</form>
<?
/**
* SQL function
*/
function sql_native($sql_string)
{
global $config, $db_native;
if (!is_resource($db_native))
{
$db_native = mysqli_pconnect($config['db_server'], $config['db_user'], $config['db_password'], $config['db_database']);
if (mysqli_connect_error())
errorpage('DB Connection Error',
"<p>Edit the database settings in <code>".CONFIG_FILE."</code>.</p>
<p>Alternatively, consider running the <a href='install.php'>installation script</a>.</p>");
}
$res = mysqli_query($db_native, $sql_string);
// mysqli_db_query returns either positive result ressource or true/false for an insert/update statement
if ($res === false)
{
// report DB Problem
errorpage('Database Problem', mysqli_error($db_native)."\n<br />\n".$sql_string);
}
elseif ($res === true)
{
// on insert, return id of created record
$result = mysqli_insert_id($db_native);
}
else
{
// return associative result array
$result = array();
for ($i=0; $i<mysqli_num_rows($res); $i++)
{
$result[] = mysqli_fetch_assoc($res);
}
mysqli_free_result($res);
}
return $result;
}
function db_encode($s)
{
global $db_native;
if (is_numeric($s)) return $s;
elseif (empty($s)) return 'NULL';
else return "'".mysqli_escape_string($db_native, $s)."'";
}
$db_encodings = array('iso-8859-1'=>'latin1', 'iso-8859-7'=>'latin7', 'iso-8859-9'=>'latin9', 'windows-1251'=>'cp1251', 'koi8-r'=>'koi8r', 'utf-8'=>'utf8');
$tables = array(TBL_DATA, TBL_ACTORS);
extract($_REQUEST);
$db_sourceencoding = $db_encodings[$sourceencoding];
$db_targetencoding = $db_encodings[$targetencoding];
if ($sourceencoding && $targetencoding && ($sourceencoding != $targetencoding))
{
# if (!preg_match('/^(\w\d)+$/', $sourceencoding)) die ('Security violation');
# if (!preg_match('/^(\w\d)+$/', $targetencoding)) die ('Security violation');
?>
<h2>2. Validate data correctness and execute</h2>
<?
dump("Converting from $sourceencoding to $targetencoding");
sql_native("SET NAMES '".$db_targetencoding."'");
foreach ($tables as $table)
{
dump("Table: ".$table);
$res = sql_native('SELECT * FROM '.$table);
dump("Items: ".count($res)."<br/>");
$enc = iconv_array($sourceencoding, $targetencoding, $res);
for ($i=0; $i<count($enc); $i++)
{
$row = $enc[$i];
// check if encoding really changed
if (join(array_values($row)) == join(array_values($res[$i]))) continue;
$id = $row['id'];
if (!$id) die("No ID found");
unset($row['id']);
$SQL = '';
foreach ($row as $key=>$val)
{
if ($SQL) $SQL .= ', ';
$SQL .= $key.'='.db_encode($val);
}
$SQL = "UPDATE $table SET ".$SQL." WHERE id=".$id;
dump($SQL);
if (!$simulate) sql_native($SQL);
}
}
}
?>
</body>
</html>

View File

@@ -0,0 +1,70 @@
#!/bin/sh
#
# Extract documentation from wiki to include in release package
#
# @package Release
# @author Andreas Gohr <a.gohr@web.de>
# @author Andreas Goetz <cpuidle@gmx.de>
# @link http://www.splitbrain.org/dokuwiki/vdb:videodb
# @version $Id: vdb_wiki.sh,v 1.1 2004/08/11 10:09:13 andig2 Exp $
#
# remove existing doku
rm -f *.html
# get doku from dokuwiki
wget --level 2 -r -np -nc -nd -E -k -A 'vdb*' -R '*\?*' http://www.splitbrain.org/dokuwiki/vdb:videodb
# delete files
for x in `ls *@*`
do
rm $x
done
# fix filenames
for x in `ls *%3A*`
do
mv $x `echo $x|tr -s %3A _`
done
#cp ../Copy\ of\ vdb/* .
# fix html
for x in `ls *.html`
do
# move to tempfile
cp $x $x.tmp
# add new header
cat >$x <<EOF
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
<title>VideoDB - Documentation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<a href="vdb_videodb.html">Table of Contents</a>
<!-- begin content -->
EOF
# add fixed content
cat $x.tmp | \
perl -e '$foo=join("",<>);
$foo=~s/vdb(:|%3A)/vdb_/gs;
$foo=~m/<!-- wikipage start -->(.*)<!-- foocache/s;
print $1' \
>> $x
# add new footer
cat >>$x <<EOF
<!-- end content -->
</body>
</html>
EOF
# remove tempfile
rm -f $x.tmp
done

View File

@@ -0,0 +1,422 @@
<?php
/**
* Add movies on a file system to the DB
*
* Pre-requsisions:
* mplayer:
* Test if installed with this command: mplayer -v
* If not installed use this command (Ubuntu) to install: sudo apt install mplayer
*
* Please change following variables
*
* movie_dirs -- list of directories to search for a new files
* update_missing -- if set to TRUE, the movie with a file in DB but not on a disk will be set as wanted
* update_moved -- if set to TRUE, if file was moved to a different location on a disk, the location in a DB will be updated to a new path
* clean_file_name -- is a substring in a name of the file you want to be removed when setting movie name
* skip_folders -- a list of subfolders to be skipped
*
* @package pages
* @author Alexander Mondshain <alex_mond@yahoo.com>
* @author Alexander Mondshain <klaus_edwin@hotmail.com>
* @version $Id: videoadd.php,v 1.3 2018/09/23 13:02:11 kec2 Exp $
*/
chdir('..');
require './core/functions.php';
// Movies on the file system.
// File name is key and full path is value.
$moviesFS = array();
// duplicate file on file system.
// File name is key and full path is value.
$doubles = array();
// NOTE : as a minimum change the following movie_dirs variable to point to a movie directory $movieDirs = array("/moviedir1","/moviedir2);
$movieDirs = array();
$movieExts = '(avi|mpg|bin|mpeg|ogm|bin|mkv|m2ts|iso)';
$cleanFileName = '(.avi|.mkv|.iso|.m2ts|XVID|XviD|XViD|Xvid|CD1)';
$skipFolders = '/^\.|^CVS|^lost|^photos|^music|^staff/';
// NOTE:update_missing, update missing files and associeted movies as wanted
// NOTE:update_moved. update moved files with a new file location
$update_missing = false;
$update_moved = false;
/**
* Check if MPlayer is installed.
*
* @return boolean True if it is installed.
*/
function isMPlayerInstalled()
{
$out = null;
$ret = - 1;
@exec("mplayer -v", $out, $ret);
return $ret == '0';
}
/**
* If a movies consits of multiple file then all but one will be removed.
* fx. Thor_CD1.avi, Thor_CD2.avi and Thor_CD3.avi => Thor_CD1.avi.
*/
function removeCDNumbers($moviesFS)
{
foreach ($moviesFS as $movie) {
$filePathParts = preg_split("/\//", $movie);
$fileName = end($filePathParts);
if (preg_match("/CD2/i", $movie)) {
unset($moviesFS[$fileName]);
} else if (preg_match("/CD3/i", $movie)) {
unset($moviesFS[$fileName]);
} else if (preg_match("/CD4/i", $movie)) {
unset($moviesFS[$fileName]);
}
}
return $moviesFS;
}
function getFileSizeLinux($file)
{
$out = null;
$ret = - 1;
@exec("stat -c %s \"$file\"", $out, $ret);
if ($ret != '0') {
return FALSE;
} else {
return ($out[0]);
}
}
function getFileTimeLinux($file)
{
$out = null;
$ret = - 1;
@exec("stat -c %Y \"$file\"", $out, $ret);
if ($ret != '0') {
return FALSE;
} else {
return ($out[0]);
}
}
/**
*
* Get all movie files requrcily starting from \$dir.
*
* @param String $dir
* The starting point.
* @param String $ext
* Files with these file extensions are or included in the result.
* @param String $skip
* Directories to skip.
*/
function recurseDir($dir, $ext, $skip)
{
// echo "In DIR $dir<br>";
global $moviesFS, $doubles;
if ($dh = opendir($dir)) {
while ($file = readdir($dh)) {
// Exclude all dot file, CVS and lost+found directories
if (preg_match($skip, $file)) {
continue;
}
// If the file is a movie, we add it to the list
if (preg_match("/\.$ext$/", $file)) {
if (isset($moviesFS[$file])) {
array_push($doubles, $moviesFS[$file]);
array_push($doubles, "$dir/$file");
} else {
$moviesFS[$file] = "$dir/$file";
}
}
// If this is a directory we search it
if (is_dir("$dir/$file")) {
recurseDir("$dir/$file", $ext, $skip);
}
}
closedir($dh);
}
}
/**
* Get combined file size of a movies with multiple files.
* fx. Thor_CD1.avi (100k), Thor_CD2.avi (200k) and Thor_CD3.avi (150k) => 450k.
*
* @param string $filePath
* Path to the first file.
* @return integer The size of the file(s).
*/
function getFileSize($filePath)
{
$fileSize = getFileSizeLinux($filePath);
if (preg_match("/CD1/i", $filePath)) {
$newfile = preg_replace("/(CD)(\d)/i", '${1}2', $filePath);
$fileSize += getFileSizeLinux($newfile);
$newfile = preg_replace("/(CD)(\d)/i", '${1}3', $filePath);
$fileSize += getFileSizeLinux($newfile);
$newfile = preg_replace("/(CD)(\d)/i", '${1}4', $filePath);
$fileSize += getFileSizeLinux($newfile);
}
return $fileSize;
}
/**
* Get metadata of a movie.
* Data include video codec, audio codec, video width and video height.
* MPlayer is used to retrive these data.
*
* @param String $filePath
* File path to the movie.
* @return array An assosiative array with keys: videoCodec, audioCodec, videoHeight and videoWidth.
*/
function getMetadata($filePath)
{
$metadata = array();
$command = "mplayer -vo null -ao null -frames 3 -identify \"$filePath\"";
// echo "command: ".$command."<br>";
$output = array();
$return_var = 0;
$match = array();
exec($command, $output, $return_var);
// parse mplayer output
foreach ($output as $line) {
trim($line);
if (preg_match("/ID_VIDEO_CODEC=(.*)/", $line, $match)) {
$videoCodec = strtolower($match[1]);
switch ($videoCodec) {
case 'ffh264':
$metadata['videoCodec'] = 'H.264';
break;
case 'ffvc1':
$metadata['videoCodec'] = 'VC1';
break;
case '0x10000001':
$metadata['videoCodec'] = 'MPEG1';
break;
case 'ffmpeg2':
$metadata['videoCodec'] = 'MPEG2';
break;
case '0x10000002':
$metadata['videoCodec'] = 'MPEG2';
break;
case 'mpg4':
$metadata['videoCodec'] = 'MPEG4';
break;
case 'div3':
$metadata['videoCodec'] = 'DivX3';
break;
case 'div4':
$metadata['videoCodec'] = 'DivX4';
break;
case 'divx':
$metadata['videoCodec'] = 'DivX4';
break;
case 'dx50':
$metadata['videoCodec'] = 'DivX5';
break;
case 'xvid':
$metadata['videoCodec'] = 'XviD';
break;
default:
$metadata['videoCodec'] = 'Unknown';
echo 'Unknown Video Codec: ' . $match[1] . '<br>';
}
} else if (preg_match("/ID_AUDIO_CODEC=(.*)/", $line, $match)) {
$audioCodec = strtolower($match[1]);
switch ($audioCodec) {
case 'fftruehd':
$metadata['audioCodec'] = 'Dolby TrueHD';
break;
case 'ffdca':
$metadata['audioCodec'] = 'DTS-HD Master Audio';
break;
case 'ffac3':
$metadata['audioCodec'] = 'AC-3';
break;
case 'a52':
$metadata['audioCodec'] = 'AC3';
break;
case 'pcm':
$metadata['audioCodec'] = 'Uncompressed PCM';
break;
case 'dvdpcm':
$metadata['audioCodec'] = 'Uncompressed DVD/VOB LPCM';
break;
case 'mad':
$metadata['audioCodec'] = 'MP3';
break;
case 'mp3':
$metadata['audioCodec'] = 'MP3';
break;
case 'ffvorbis':
$metadata['audioCodec'] = 'Vorbis';
break;
case 'ffwmav1':
$metadata['audioCodec'] = 'WMA1';
break;
case 'ffwmav2':
$metadata['audioCodec'] = 'WMA2';
break;
default:
$metadata['audioCodec'] = 'Unknown';
echo 'Unknown Audio Codec: ' . $match[1] . '<br>';
}
} else if (preg_match("/ID_VIDEO_WIDTH=(.*)/", $line, $match)) {
$metadata['videoWidth'] = $match[1];
} else if (preg_match("/ID_VIDEO_HEIGHT=(.*)/", $line, $match)) {
$metadata['videoHeight'] = $match[1];
}
}
return $metadata;
}
?>
<html>
<head>
<title>Add and move files</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="description" content="VideoDB" />
<link rel="stylesheet" href="../<?php echo $config['style'] ?>"
type="text/css" />
</head>
<body>
<?php
if (!isMPlayerInstalled()) {
echo '<h1 style="color:red;">mplayer is not installed! Please install it.</h1><br>';
exit();
}
if (count($movieDirs) == 0) {
echo '<h1 style="color:red;">PLEASE edit the script and set at least one folder in \$movie_dirs variable </h1><br>';
exit();
}
// get all files. Result is in $moviesFS and $doubles;
foreach ($movieDirs as $dir) {
recurseDir($dir, $movieExts, $skipFolders);
}
// Get all movies that are not on the whishlist (50) or inserted by this tool (51)
$SELECT = 'SELECT id, filename FROM ' . TBL_DATA . ' WHERE mediatype < 50 ORDER BY filename';
$rows = runSQL($SELECT);
echo '<h3>Scanning...</h3>';
echo '<b>Total movie files found on disk:</b> ' . sizeof($moviesFS) . '<br>';
echo '<b>Total movie files found in DB:</b> ' . count($rows) . '<br><br>';
echo '<h3>Comparing results.</h3>';
foreach ($rows as $row) {
$filePathParts = preg_split("/\//", $row['filename']);
$fileName = end($filePathParts);
$id = $row['id'];
// The path does not match the path found in the database
if ($moviesFS[$fileName] != $row['filename']) {
if (! isset($moviesFS[$fileName])) {
echo "<b>MISSING</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
if ($update_missing) {
$UPDATE = "UPDATE " . TBL_DATA . " SET mediatype='" . MEDIA_WISHLIST . "' WHERE id='{$id}'";
runSQL($UPDATE);
}
} else {
echo "<b>MOVED</b> - <a href='../show.php?id={$id}'>{$fileName}</a><br>";
if ($update_moved) {
$UPDATE = "UPDATE " . TBL_DATA . " SET filename='" . escapeSQL($moviesFS[$fileName]) . "' WHERE id='{$id}'";
runSQL($UPDATE);
}
}
} else {
unset($moviesFS[$fileName]);
}
}
echo '<br><b>New files found:</b> ' . sizeof($moviesFS) . '<br>';
asort($moviesFS);
$moviesFS = removeCDNumbers($moviesFS);
echo '<b>New files found with no CD[2-3-4]:</b> ' . sizeof($moviesFS) . '<br>';
// remove all movies added last time and not updated with real information
// mediatype 51 indicates that the movie was inserted/modified by this tool.
$UPDATE = "DELETE FROM " . TBL_DATA . " WHERE mediatype='51'";
runSQL($UPDATE);
echo '<h3>Data on movies to add.</h3>';
echo "<table class='collapse'>
<tr>
<th>File Name</th>
<th>Title</th>
<th>File Size</th>
<th>Audio Codec</th>
<th>Video Codec</th>
<th>Video Width</th>
<th>Video Height</th>
<th>File Date</th>
</tr>";
$currentUserId = get_current_user_id();
foreach ($moviesFS as $movie) {
$filePathParts = preg_split("/\//", $movie);
$fileName = end($filePathParts);
$title = preg_replace($cleanFileName, '', $fileName);
$title = str_replace('_', ' ', $title);
$filePath = $moviesFS[end($filePathParts)];
$fileSize = (int) getFileSize($filePath);
$fileDate = getFileTimeLinux($filePath);
$metadata = getMetadata($filePath);
$audioCodec = $metadata['audioCodec'];
$videoCodec = $metadata['videoCodec'];
$videoWidth = (int) $metadata['videoWidth'];
$videoHeight = (int) $metadata['videoHeight'];
echo "<tr>
<td>$filePath</td>
<td>$title</td>
<td>$fileSize</td>
<td>$audioCodec</td>
<td>$videoCodec</td>
<td>$videoWidth</td>
<td>$videoHeight</td>
<td>$fileDate</td>
</tr>";
$UPDATE = "INSERT " . TBL_DATA . " SET filename='" . escapeSQL($filePath) . "',
mediatype = 51,
title = '$title',
filesize = $fileSize,
audio_codec = '$audioCodec',
video_codec = '$videoCodec',
video_width = $videoWidth,
video_height = $videoHeight,
owner_id = $currentUserId,
filedate = FROM_UNIXTIME($fileDate)";
runSQL($UPDATE);
}
echo '</table>';
$SELECT = "SELECT id, title FROM " . TBL_DATA . " WHERE mediatype='51' ORDER BY title";
$rows = runSQL($SELECT);
echo '<br><br><h3><New movies added (click to edit):</h3>';
foreach ($rows as $row) {
echo "<a href='../edit.php?id={$row['id']}'>{$row['title']}</a><br>";
}
?>
<h3>All Done</h3>
</body>
</html>

324
videodb/contrib/videoadd.pl Normal file
View File

@@ -0,0 +1,324 @@
#!/usr/bin/perl
##
# Add video files from local disc
#
# @package videoDB
# @author Andreas Gohr <a.gohr@web.de>
#
# TODO check paths for correctness
##
# path to md4sum
# Get it from http://www-tet.ee.tu-berlin.de/solyga/linux/
#
# If you don't want md4 sums (time consuming) set it to a
# blank string
$md4sum = ''; #/usr/local/bin/md4sum';
# If you want md4 sums: in which custom field should it be
# stored? In VideoDB it should have 'ed2k' as type
#$md4field = 'custom2';
# If you want a download link to the file: in which custom
# field should it be stored? In VideoDB it should have
# 'url' as type
#$urlfield = 'custom1';
# path to the eject tool,
#found this not real useful when you can rub the script to process a directory,
#but if you going to us a cdrom you un comment it it.
#$eject = '/usr/bin/eject';
# path to mplayer (only version 0.90 was tested, 1.0rc1 works too)
$mplayer = '/usr/bin/mplayer';
# cdrom to use (reads it from commandline)
$device = $ARGV[ 0 ];
# alter "/writer" to the directory you have videos in to process.
$device = "/writer" unless (defined($device));
# do the mount ?
$do_mount = 0;
# remove articles
$remove_article = 1;
# if you use the multiuser feature you may want to give an
# owner of the movies to add here - if you don't need it just
# set it to a blank string
$owner_id = 1;
# allowed suffixes
$suffix_re = 'avi|ogm|ogg|bin|mpe?g|ra?m|mov|asf|wmv|mp4|mkv';
# Database stuff
$driver = "mysql";
$database = "VideoDB";
$prefix = ""; // enter your DB prefix like videodb. in here
$hostname = "server";
$user = "www";
$password = "leech";
################################################################################
use DBI;
#Connect to database
$dsn = "DBI:$driver:database=$database;host=$hostname";
$dbh = DBI->connect($dsn, $user, $password);
#quote this only once:
$owner = $dbh->quote($owner);
if (-f $device)
{
$plain = $device;
$plain =~ s#.*/([^/]+)$#\1#i;
add($device,$plain);
}
else
{
# mount
($do_mount) && system("$eject -t $device");
($do_mount) && system("mount $device");
#work
&readfiles($device);
#umount
($do_mount) && system("umount $device");
($do_mount) && system("$eject $device");
}
#disconnect
$dbh->disconnect();
#
###############################################################################
sub readfiles($)
{
my $path = $_[ 0 ];
opendir(ROOT, $path);
my @files = readdir(ROOT);
closedir(ROOT);
my ($file, $ffile);
foreach $file (@files)
{
$ffile = "$path/$file";
next if ($file =~ /^\.|\.\.$/); #skip upper dirs
if (-d $ffile)
{
readfiles($ffile);
}
if ($ffile =~ /\.($suffix_re)$/i)
{
&add($ffile, $file); #add it
print STDERR "$ffile\n";
}
}
}
sub add($$)
{
my $ffile = $_[ 0 ]; #full path
my $file = $_[ 1 ]; #file only
# get filestatistics
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($ffile);
# get md4
my $md4;
if ($md4sum ne '')
{
$md4 = `$md4sum "$ffile"`;
$md4 =~ s/\s.*$//;
}
# get videoinfos
my ($audio_codec, $video_codec, $video_width, $video_height, $runtime);
print qq($mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null);
my @out = `$mplayer -identify -ao null -vo null -frames 0 "$ffile" 2>/dev/null` if ($mplayer);
foreach my $line (@out)
{
next unless ($line =~ m/^ID_/);
chomp($line);
if ($line =~ m/^ID_VIDEO_FORMAT=(.*)/)
{
$video_codec = $1;
$video_codec = 'MPEG1' if ($video_codec eq '0x10000001');
$video_codec = 'MPEG2' if ($video_codec eq '0x10000002');
$video_codec = 'MPEG4' if ($video_codec eq 'MPG4');
#FIXME id's of other mpegs??
$video_codec = 'DivX3' if ($video_codec eq 'DIV3');
$video_codec = 'DivX3' if ($video_codec eq 'div3');
$video_codec = 'DivX4' if ($video_codec eq 'DIV4');
$video_codec = 'DivX4' if ($video_codec eq 'DIVX');
$video_codec = 'DivX4' if ($video_codec eq 'divx');
$video_codec = 'DivX5' if ($video_codec eq 'DX50');
$video_codec = 'XviD' if ($video_codec eq 'XVID');
#FIXME aliases of other codecs?
#Add more 20/1/2015 by LinuxHam couple extra codecs to help get data needed
$video_codec = 'H264' if ($video_codec eq 'ffh264');
$video_codec = 'avc1' if ($video_codec eq 'ffh264');
$video_codec = 'MP4V' if ($video_codec eq 'ffodivx');
}
elsif ($line =~ m/^ID_VIDEO_WIDTH=(.*)/)
{
$video_width = $1;
}
elsif ($line =~ m/^ID_VIDEO_HEIGHT=(.*)/)
{
$video_height = $1;
}
elsif ($line =~ m/^ID_AUDIO_CODEC=(.*)/)
{
$audio_codec = $1;
$audio_codec = 'MP3' if ($audio_codec eq 'mad');
$audio_codec = 'MP3' if ($audio_codec eq 'mp3');
$audio_codec = 'AC3' if ($audio_codec eq 'a52');
$audio_codec = 'Vorbis' if ($audio_codec eq 'ffvorbis');
$audio_codec = 'PCM' if ($audio_codec eq 'pcm');
$audio_codec = 'WMA2' if ($audio_codec eq 'ffwmav2');
$audio_codec = 'WMA1' if ($audio_codec eq 'ffwmav1'); # just a guess, needs confirmation
#Add more 20/1/2015 by LinuxHam, couple extra codecs to help get data needed
$audio_codec = '8192' if ($audio_codec eq 'ffac3');
$audio_codec = 'MP4A' if ($audio_codec eq 'ffaac');
$audio_codec = '85' if ($audio_codec eq 'ffmp3float');
}
elsif ($line =~ m/^ID_LENGTH=(.*)/)
{
$runtime = $1;
$runtime = sprintf("%d", $runtime / 60);
}
}
# get titles
my ($lang, $title, $subtitle, $istv) = &guessnames($file);
# prepare for inserts
$file = $dbh->quote($file);
$size = $dbh->quote($size);
$audio_codec = $dbh->quote($audio_codec);
$video_codec = $dbh->quote($video_codec);
$video_width = $dbh->quote($video_width);
$video_height = $dbh->quote($video_height);
$runtime = $dbh->quote($runtime);
$lang = $dbh->quote($lang);
$title = $dbh->quote($title);
$subtitle = $dbh->quote($subtitle);
$md4 = $dbh->quote($md4);
$ffile = $dbh->quote($ffile);
# insert
$INSERT = "INSERT INTO ".$prefix."videodata
SET filename = $file,
filesize = $size,
audio_codec = $audio_codec,
video_codec = $video_codec,
video_width = $video_width,
video_height = $video_height,
language = $lang,
title = $title,
subtitle = $subtitle,
runtime = $runtime,
mediatype = 4,
istv = $istv,
filedate = FROM_UNIXTIME($mtime),
created = NOW(),
owner_id = $owner_id";
if ($md4sum ne '')
{
$INSERT .= ", $md4field = $md4";
}
if ($urlfield ne '')
{
$INSERT .= ", $urlfield = $ffile";
}
$dbh->do($INSERT);
#print "$file \n$title - $subtitle\n\n";
}
sub guessnames($)
{
my $episode = "";
my $istv = 0;
my $file = $_[ 0 ]; #file only
# try to get language
# backdrafts: es matches german word, de probably some french stuff
my $lang = "";
$lang = "german" if ($file =~ m/\b(german|deutsch|ger|de)\b/i);
$lang = "english" if ($file =~ m/\b(english|eng|en)\b/i);
$lang = "french" if ($file =~ m/\b(french|français|fra|fr)\b/i);
$lang = "spanish" if ($file =~ m/\b(spanish|español|es)\b/i);
# remove add. info
$file =~ s/\(.*\)//;
#remove common trash and suffixes
$file =~ s/(\[[^\]]\]|bin|cd\d|dvd\d|divx|xvid|[ms]?vcd|dvdscr|dvdrip|shareconnector|eselfilme)//gi;
$file =~ s/\.($suffix_re)$//gi;
# get episode Number
if ($file =~ s/(s\d+e\d+)/-/i)
{
$episode = $1;
}
elsif ($file =~ s/(\d+x\d+)/-/i)
{
$episode = $1;
}
# change dots to underscores
$file =~ s/\./_/g;
# change underscores to spaces
$file =~ s/_/ /g;
# split title and subtitle and cleanup
my @parts = split ("-", $file, 2);
my $title = $parts[ 0 ];
my $subtitle = $parts[ 1 ];
$title =~ s/^[\s-]*//g;
$title =~ s/[\s-]*$//g;
$subtitle =~ s/^[\s-]*//g;
$subtitle =~ s/[\s-]*$//g;
if ($episode)
{
$subtitle = "[$episode] $subtitle";
$istv = 1;
}
if ($remove_article)
{
unless ($title =~ s/^(for the)\b(.*)$/$2, $1/i)
{
unless ($title =~ s/^(for a)\b(.*)$/$2, $1/i)
{
unless ($title =~ s/^(for)\b(.*)$/$2, $1/i)
{
unless ($title =~ s/^(the)\b(.*)$/$2, $1/i)
{
unless ($title =~ s/^(a)\b(.*)$/$2, $1/i)
{
($title =~ s/^(der|die|das)\b(.*)$/$2, $1/i);
}
}
}
}
}
}
chomp ($title);
return ($lang, $title, $subtitle, $istv);
}