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:
602
videodb/engines/allocine.php
Executable file
602
videodb/engines/allocine.php
Executable file
@@ -0,0 +1,602 @@
|
||||
<?php
|
||||
/**
|
||||
* Allocine Parser
|
||||
*
|
||||
* Parses data from the Allocine.fr
|
||||
*
|
||||
* @package Engines
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
* @link http://www.allocine.fr Internet Movie Database
|
||||
* @version $Id: allocine.php,v 1.17 2011/06/24 23:08:06 robelix Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['allocineServer'] = 'https://www.allocine.fr';
|
||||
$GLOBALS['allocineIdPrefix'] = 'allocine:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
|
||||
function allocineMeta()
|
||||
{
|
||||
return array('name' => 'Allocine (fr)');
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode title search to allow results with accentued characters
|
||||
* @author Martin Vauchel <martin@vauchel.com>
|
||||
* @param string The search string
|
||||
* @return string The search string with no accents
|
||||
*/
|
||||
function removeAccents($title)
|
||||
{
|
||||
$accentued = array("à","á","â","ã","ä","ç","è","é","ê","ë","ì",
|
||||
"í","î","","ï","ñ","ò","ó","ô","õ","ö","ù","ú","û","ü","ý","ÿ",
|
||||
"À","Á","Â","Ã","Ä","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","Ñ","Ò",
|
||||
"Ó","Ô","Õ","Ö","Ù","Ú","Û","Ü","Ý");
|
||||
$nonaccentued = array("a","a","a","a","a","c","e","e","e","e","i","i",
|
||||
"i","i","n","o","o","o","o","o","u","u","u","u","y","y","A","A","A",
|
||||
"A","A","C","E","E","E","E","I","I","I","I","N","O","O","O","O","O",
|
||||
"U","U","U","U","Y");
|
||||
|
||||
$title = str_replace($accentued, $nonaccentued, $title);
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search Allocine for a movie
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function allocineSearchUrl($title)
|
||||
{
|
||||
global $allocineServer;
|
||||
// The removeAccents function is added here
|
||||
return $allocineServer.'/recherche/?q='.urlencode(removeAccents($title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit Allocine for a specific movie
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function allocineContentUrl($id)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $allocineIdPrefix;
|
||||
|
||||
$allocineID = preg_replace('/^'.$allocineIdPrefix.'/', '', $id);
|
||||
return $allocineServer.'/film/fichefilm_gen_cfilm='.$allocineID.'.html';
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on Allocine and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Charles Morgan <cmorgan34@yahoo.com>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function allocineSearch($title)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
// The removeAccents function is added here
|
||||
$resp = httpClient(allocineSearchUrl($title), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array();
|
||||
|
||||
#echo '<pre>';
|
||||
#dump(htmlspecialchars($resp['data']));
|
||||
#echo '</pre>';
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
// no longer needed??
|
||||
$single = array();
|
||||
if (preg_match('#^'.preg_quote($allocineServer,'/').'/film/fichefilm_gen_cfilm=(\d+)\.html#', $resp['url'], $single))
|
||||
{
|
||||
$data[0]['id'] = 'allocine:'.$single[2];
|
||||
$data[0]['title']= $title;
|
||||
return $data;
|
||||
}
|
||||
|
||||
// multiple matches
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
// To have the result zone
|
||||
#$debutr = strpos($resp['data'], '<table class="totalwidth noborder purehtml">')+strlen('<table class="totalwidth noborder purehtml">');
|
||||
#$finr = strpos($resp['data'], '</table>', $debutr);
|
||||
#$chaine = substr($resp['data'], $debutr, $finr-$debutr);
|
||||
|
||||
preg_match('#<h2>\s*?Films\s*?</h2>(.*?)<h2>#si',$resp['data'],$ary);
|
||||
|
||||
$chaine = $ary[1];
|
||||
# contains some pretty random <b></b>
|
||||
$chaine = preg_replace('/<b>/','',$chaine);
|
||||
$chaine = preg_replace('/<\/b>/','',$chaine);
|
||||
|
||||
/*
|
||||
<tr><td style=" vertical-align:top;">
|
||||
<a href='/film/fichefilm_gen_cfilm=57999.html'><img
|
||||
src='http://images.allocine.fr/r_75_106/medias/nmedia/18/36/26/78/18759563.jpg'
|
||||
alt='Clerks II' /></a>
|
||||
</td><td style=" vertical-align:top;" class="totalwidth"><div><div style="margin-top:-5px;">
|
||||
<a href='/film/fichefilm_gen_cfilm=57999.html'>
|
||||
Clerks II</a>
|
||||
<br />
|
||||
<span class="fs11">
|
||||
2006<br />
|
||||
de Kevin Smith<br />
|
||||
avec Brian O'Halloran, Jeff Anderson<br />
|
||||
<div>
|
||||
<div class="spacer vmargin10"></div>
|
||||
</span> <!-- /fs11 -->
|
||||
*/
|
||||
|
||||
preg_match_all('#<a href=\'/film/fichefilm_gen_cfilm=(\d+).html\'>\s*?(.*?)</a>\s*?<br />\s*?<span class=\"fs11\">\s*?(\d+)<br />\s*?de (.*?)\s*?/#si', $chaine, $m, PREG_SET_ORDER);
|
||||
|
||||
foreach ($m as $row)
|
||||
{
|
||||
$info['id'] = 'allocine:'.$row[1];
|
||||
|
||||
$info['title'] = html_clean_utf8(strip_tags($row[2]));
|
||||
$info['title'] = str_replace("(", " (", $info['title']);
|
||||
|
||||
// add year (helpful in case of multiple matches)
|
||||
if (isset($row[3])) {$info['year'] = html_clean_utf8($row[3]);}
|
||||
|
||||
// add director (helpful in case of multiple matches)
|
||||
if (isset($row[4])) {
|
||||
$info['director'] = html_clean_utf8($row[4]);
|
||||
$info['director'] = preg_replace("/^de\s/", "", $info['director']);
|
||||
}
|
||||
|
||||
$data[] = $info;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given Allocine-ID
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @param int imdb-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function allocineData($imdbID)
|
||||
{
|
||||
global $allocineServer;
|
||||
global $allocineIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$allocineID = preg_replace('/^'.$allocineIdPrefix.'/', '', $imdbID);
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($allocineServer.'/film/fichefilm_gen_cfilm='.$allocineID.'.html', 1); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// Allocine ID
|
||||
$data['id'] = "allocine:".$allocineID;
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
/*
|
||||
Title and subtitle
|
||||
*/
|
||||
preg_match('#<h1.*?>(.*?)</h1>#si', $resp['data'], $ary);
|
||||
list($t, $s) = explode(" - ",trim($ary[1]),2);
|
||||
// Some bugs when using html_clean function --> using html_clean_utf8
|
||||
$data['title'] = html_clean_utf8($t);
|
||||
$data['subtitle'] = html_clean_utf8($s);
|
||||
|
||||
|
||||
/*
|
||||
Year
|
||||
*/
|
||||
preg_match('/<a.*? href="\/film\/tous\/decennie.*?year=(\d+)">(\d+)<\/a>/i', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {$data['year'] = trim($ary[1]);}
|
||||
|
||||
|
||||
/*
|
||||
Release Date
|
||||
added to the comments
|
||||
*/
|
||||
preg_match('#<a.*? href="/film/agenda\.html\?week=\d+\-\d+\-\d+">(.*)</a>#i',$resp['data'], $ary);
|
||||
$release_date = "";
|
||||
if (!empty($ary[1])) {$release_date = "\r\nDate de sortie cinéma : ".html_clean_utf8($ary[1]);}
|
||||
|
||||
/*
|
||||
Cover URL
|
||||
*/
|
||||
preg_match('#<div class="colleft">\s*?<div class="vmargin20b">\s*?<div class=\"poster\">\s*?<em class=\"imagecontainer\">\s*?<a .*?>\s*?<img.*?src=\'(.*?)\'.*?>#si', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
|
||||
/*
|
||||
Runtime
|
||||
*/
|
||||
#Durée : 02h13min
|
||||
|
||||
preg_match('/Durée :\s*?(\d+)h(\d+)\s*?min/i', $resp['data'], $ary);
|
||||
$hours = preg_replace('/,/', '', trim($ary[1]));
|
||||
$minutes = preg_replace('/,/', '', trim($ary[2]));
|
||||
$data['runtime'] = $hours * 60 + $minutes;
|
||||
|
||||
|
||||
/*
|
||||
Director
|
||||
*/
|
||||
preg_match('#Réalisé par\s*<span.*?><a.*?rel="v:directedBy".*?href=\'/personne/fichepersonne_gen_cpersonne=\d+\.html\' title=\'.*\'>(.*)</a></span>#i', $resp['data'], $ary);
|
||||
$data['director'] = trim($ary[1]);
|
||||
|
||||
|
||||
/*
|
||||
Rating
|
||||
*/
|
||||
preg_match('#<p class="withstars"><a.*?href="/film/critiquepublic_gen_cfilm=\d+\.html"><img.*?class="stareval.*?".*?<span class=\"moreinfo\">\((.*)\)</span></p>#i', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
$data['rating'] = str_replace(",", ".", $data['rating']);
|
||||
// Allocine rating is based on 5, imdb is based on 10
|
||||
$data['rating'] = $data['rating'] * 2;
|
||||
|
||||
|
||||
/*
|
||||
Countries
|
||||
*/
|
||||
// Countries in English
|
||||
$map_countries = array(
|
||||
'allemand' => 'Germany',
|
||||
'américain' => 'USA',
|
||||
'arménien' => 'Armenia',
|
||||
'argentin' => 'Argentina',
|
||||
'sud-africain' => 'South Africa',
|
||||
'australien' => 'Australia',
|
||||
'belge' => 'Belgium',
|
||||
'britannique' => 'UK',
|
||||
'bulgare' => 'Bulgaria',
|
||||
'canadien' => 'Canada',
|
||||
'chinois' => 'China',
|
||||
'coréen' => 'South Korea',
|
||||
'danois' => 'Denmark',
|
||||
'espagnol' => 'Spain',
|
||||
'français' => 'France',
|
||||
'grec' => 'Greece',
|
||||
'hollandais' => 'Netherlands',
|
||||
'hong-kongais' => 'Hong-Kong',
|
||||
'hongrois' => 'Hungary',
|
||||
'indien' => 'India',
|
||||
'irlandais' => 'Republic of Ireland',
|
||||
'islandais' => 'Iceland',
|
||||
'israëlien' => 'Israel',
|
||||
'italien' => 'Italy',
|
||||
'japonais' => 'Japan',
|
||||
'luxembourgeois' => 'Luxembourg',
|
||||
'mexicain' => 'Mexico',
|
||||
'norvégien' => 'Norge',
|
||||
'néo-zélandais' => 'New Zealand',
|
||||
'polonais' => 'Poland',
|
||||
'portugais' => 'Portugal',
|
||||
'roumain' => 'Romania',
|
||||
'russe' => 'Russia',
|
||||
'serbe' => 'Serbia',
|
||||
'suédois' => 'Sweden',
|
||||
'taïwanais' => 'Taiwan',
|
||||
'tchèque' => 'Czech Republic',
|
||||
'thaïlandais' => 'Thailand',
|
||||
'turc' => 'Turkey',
|
||||
'ukrainien' => 'Ukraine',
|
||||
'vietnamien' => 'Vietnam');
|
||||
|
||||
if (preg_match_all('#Long\-métrage\s*?<a.*?href=".*?">(.*?)</a>#si', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$originlist = explode(",",trim(join(', ', $ary[1])));
|
||||
foreach ($originlist as $origin)
|
||||
{
|
||||
$mapped_country_found = '';
|
||||
|
||||
foreach ($map_countries as $pattern_c => $mapped_country)
|
||||
{
|
||||
if (preg_match_all('/'.$pattern_c.'/i', $origin, $junk, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$mapped_country_found = $mapped_country;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if($data['country'] == '') {$data['country'] = $mapped_country_found;}
|
||||
elseif(stristr($data['country'], $mapped_country_found) == TRUE)
|
||||
{
|
||||
$data['country'] = $data['country'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$data['country'] = $data['country'] . ', ' . $mapped_country_found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Plot
|
||||
*/
|
||||
preg_match('#<div id="synopsis_full">\s*?<p>\s*?<span class=\"bold\">Synopsis \: </span>\s*?<span property="v:summary">(.*?)</span>#is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {
|
||||
$data['plot'] = $ary[1];
|
||||
$data['plot']= html_clean_utf8($data['plot']);
|
||||
|
||||
// And cleanup
|
||||
$data['plot'] = trim($data['plot']);
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/ /',' ', $data['plot']);
|
||||
}
|
||||
|
||||
/*
|
||||
Genres (as Array)
|
||||
*/
|
||||
$map_genres = array(
|
||||
'Action' => 'Action',
|
||||
'Animation' => 'Animation',
|
||||
'Arts Martiaux' => 'Action',
|
||||
'Aventure' => 'Adventure',
|
||||
'Biopic' => 'Biography',
|
||||
'Bollywood' => 'Musical',
|
||||
'Classique' => '-',
|
||||
'Comédie Dramatique' => 'Drama',
|
||||
'Comédie musicale' => 'Musical',
|
||||
'Comédie' => 'Comedy',
|
||||
'Dessin animé' => 'Animation',
|
||||
'Divers' => '-',
|
||||
'Documentaire' => 'Documentary',
|
||||
'Drame' => 'Drama',
|
||||
'Epouvante-horreur' => 'Horror',
|
||||
'Erotique' => 'Adult',
|
||||
'Espionnage' => '-',
|
||||
'Famille' => 'Family',
|
||||
'Fantastique' => 'Fantasy',
|
||||
'Guerre' => 'War',
|
||||
'Historique' => 'History',
|
||||
'Horreur' => 'Horror',
|
||||
'Musique' => 'Musical',
|
||||
'Policier' => 'Crime',
|
||||
'Péplum' => 'History',
|
||||
'Romance' => 'Romance',
|
||||
'Science fiction' => 'Sci-Fi',
|
||||
'Thriller' => 'Thriller',
|
||||
'Western' => 'Western');
|
||||
|
||||
if (preg_match_all('#Genre :(.*?)</a>\s*?<br#si', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$genrelist = explode(",", trim(join(', ', $ary[1])));
|
||||
|
||||
foreach ($genrelist as $genre)
|
||||
{
|
||||
$mapped_genre_found = '';
|
||||
foreach ($map_genres as $pattern => $mapped_genre)
|
||||
{
|
||||
if (preg_match_all('/'.$pattern.'/i', $genre, $junk, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$mapped_genre_found = $mapped_genre;
|
||||
break;
|
||||
}
|
||||
}
|
||||
$data['genres'][] = ($mapped_genre_found != '-') ? $mapped_genre_found : trim($genre);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Original Title
|
||||
*/
|
||||
preg_match('#Titre original : <span class=\"purehtml\"><em>(.*)</em></span>#', $resp['data'], $ary);
|
||||
$data['origtitle'] = trim($ary[1]);
|
||||
|
||||
/*
|
||||
Title and Subtitle
|
||||
If sub-title is blank, we'll try to fill in the original title for foreign films.
|
||||
*/
|
||||
if (empty($data['subtitle']))
|
||||
{
|
||||
if ($data['origtitle'])
|
||||
{
|
||||
$data['subtitle'] = $data['title'];
|
||||
$data['title'] = $data['origtitle'];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
CREDITS AND CAST
|
||||
*/
|
||||
// fetch credits
|
||||
// Another HTML page
|
||||
$resp = httpClient($allocineServer.'/film/casting_gen_cfilm='.$allocineID.'.html', 1);
|
||||
if (!$resp['success']) {$CLIENTERROR .= $resp['error']."\n";}
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
if (preg_match('#<h2>Acteurs, rôles, personnages</h2>(.*?)<div class="titlebar">\s*?<a class="anchor" id=\'actors\'></a>\s*?<h2>#is', $resp['data'], $Section))
|
||||
{
|
||||
|
||||
# the big ones with image
|
||||
/*
|
||||
<div class="titlebar">
|
||||
<h3>
|
||||
<a href="/personne/fichepersonne_gen_cpersonne=5568.html">Liam Neeson</a>
|
||||
</h3>
|
||||
</div>
|
||||
<p>
|
||||
Rôle : Qui-Gon Jinn
|
||||
</p>
|
||||
<div class="spacer"></div>
|
||||
*/
|
||||
preg_match_all('#<div class="titlebar">\s*?<h3>\s*?<a href="/personne/fichepersonne_gen_cpersonne=(\d+?).html">(.*?)</a>\s*?</h3>\s*?</div>\s*?<p>\s*Rôle : (.*?)\s*</p>#is', $Section[1], $ary, PREG_PATTERN_ORDER);
|
||||
|
||||
$count = 0;
|
||||
$cast = '';
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$cast .= $ary[2][$count]."::".$ary[3][$count]."::allocine:".$ary[1][$count]."\n";
|
||||
$count++;
|
||||
}
|
||||
|
||||
# extended cast - without image
|
||||
/*
|
||||
<tr class="odd">
|
||||
<td>
|
||||
Shmi Skywalker
|
||||
</td>
|
||||
<td>
|
||||
<a href="/personne/fichepersonne_gen_cpersonne=14279.html">Pernilla August</a>
|
||||
</td>
|
||||
</tr>
|
||||
*/
|
||||
preg_match_all('#<tr.*?>\s*?<td>\s*(.*?)\s*</td>\s*?<td>\s*?<a href="/personne/fichepersonne_gen_cpersonne=(\d+).html">(.*?)</a>\s*?</td>#si', $Section[1], $ary, PREG_PATTERN_ORDER);
|
||||
|
||||
$count = 0;
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$cast .= $ary[3][$count]."::".$ary[1][$count]."::allocine:".$ary[2][$count]."\n";
|
||||
$count++;
|
||||
}
|
||||
$data['cast'] = trim($cast);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Comments
|
||||
*/
|
||||
// By default
|
||||
$data['language'] = 'french';
|
||||
|
||||
// Another HTML page
|
||||
$resp = httpClient($allocineServer.'/film/fichefilm-'.$allocineID.'/technique/', 1);
|
||||
if (!$resp['success']) {$CLIENTERROR .= $resp['error']."\n";}
|
||||
|
||||
// We remove all the multiples spaces and line breakers
|
||||
$resp['data'] = preg_replace('/[\s]{2,}/','',$resp['data']);
|
||||
|
||||
// Technical informations as comment
|
||||
preg_match('#<div class=\"rubric\">\s*?<div class=\"vpadding20b\">\s*(.*?)\s*</div>\s*?</div>#si', $resp['data'], $ary);
|
||||
if (!empty($ary[1]))
|
||||
{
|
||||
$data['comment'] = $ary[1];
|
||||
|
||||
$data['comment'] = str_replace("Tourné en :", "Tourné en : ", $data['comment']);
|
||||
|
||||
// Adding the release date in theater
|
||||
$data['comment'] = $data['comment'] . $release_date;
|
||||
|
||||
// Search the language
|
||||
// Default language
|
||||
$data['language'] = "french";
|
||||
|
||||
if (preg_match('#<p>\s*?<span class=\"bold\">Tourné en :</span>\s*(.*?)\s*</p>#si', $resp['data'], $ary))
|
||||
{
|
||||
$data['language'] = $ary[1];
|
||||
|
||||
// Converting languages from french to english
|
||||
$map_languages = array(
|
||||
'Anglais' => 'english',
|
||||
'Français' => 'french',
|
||||
'Allemand' => 'german',
|
||||
'Italien' => 'italian',
|
||||
'Espagnol' => 'spanish',
|
||||
'Coréen' => 'Korean',
|
||||
'Roumain' => 'romanian',
|
||||
'Autre' => 'french',
|
||||
'Hindi' => 'hindi',
|
||||
'Arabe' => 'arabic',
|
||||
'Thaï' => 'thai',
|
||||
'Danois' => 'danish',
|
||||
'Suédois' => 'swedish',
|
||||
'Tchèque' => 'czech',
|
||||
'Japonais' => 'japanese',
|
||||
'Portugais' => 'portuguese',
|
||||
'Norvégien' => 'norwegian',
|
||||
'Bulgare' => 'bulgarian',
|
||||
'Grec' => 'greek',
|
||||
'Hongrois' => 'hungarian',
|
||||
'Turc' => 'turkish',
|
||||
'Islandais' => 'icelandic',
|
||||
'Polonais' => 'polish',
|
||||
'Russe' => 'russian',
|
||||
'Ukrainien' => 'ukrainian',
|
||||
'Serbe' => 'serbian',
|
||||
'Vietnamien' => 'vietnamese',
|
||||
'Afrikaans' => 'afrikaans'
|
||||
);
|
||||
|
||||
foreach($map_languages as $pattern => $map_lang)
|
||||
{
|
||||
$data['language'] = str_replace($pattern, $map_lang, $data['language']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the data collected
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process? Completion waiting on update of actor
|
||||
* functionality to support more than one engine.
|
||||
*
|
||||
* @author Douglas Mayle <douglas@mayle.org>
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function allocineActor($name, $actorid)
|
||||
{
|
||||
global $allocineServer;
|
||||
|
||||
if (empty ($actorid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$url = 'https://www.allocine.fr/personne/fichepersonne_gen_cpersonne='.urlencode($actorid).'.html';
|
||||
$resp = httpClient($url, 1);
|
||||
|
||||
$single = array();
|
||||
if (preg_match ('/src="([^"]+allocine.fr\/acmedia\/medias\/nmedia\/[^"]+\/[0-9]+\.jpg)[^>]+width="120"/', $resp['data'], $single)) {
|
||||
$ary[0][0]=$url;
|
||||
$ary[0][1]=$single[1];
|
||||
return $ary;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
331
videodb/engines/dvdfr.php
Executable file
331
videodb/engines/dvdfr.php
Executable file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
/**
|
||||
* Dvdfr Parser
|
||||
*
|
||||
* Parses data from www.dvdfr.com (french site)
|
||||
* 2006-08-12 Update Sebastien Koechlin <seb.videodb@koocotte.org>
|
||||
*
|
||||
* @package Engines
|
||||
* @author tedemo <tedemo@free.fr>
|
||||
* @link http://www.dvdfr.com
|
||||
* @version $Id: dvdfr.php,v 1.7 2011/06/23 12:27:28 robelix Exp $
|
||||
*/
|
||||
|
||||
require_once './core/compatibility.php';
|
||||
|
||||
$GLOBALS['dvdfrServer'] = 'https://www.dvdfr.com';
|
||||
$GLOBALS['dvdfrIdPrefix'] = 'dvdfr:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function dvdfrMeta()
|
||||
{
|
||||
return array('name' => 'Dvdfr (fr)', 'stable' => 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Clean a string
|
||||
*
|
||||
* @param string The string to clean
|
||||
* @return string The cleaned string
|
||||
*/
|
||||
function dvdfrCleanStr($str)
|
||||
{
|
||||
// Remove spaces
|
||||
$str = trim($str);
|
||||
|
||||
// Translate strange (MS-Word?) quotes
|
||||
$str = preg_replace( '/'/', '\'', $str );
|
||||
|
||||
// Remove HTML entities
|
||||
$str = html_entity_decode($str);
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search Dvdfr for a movie
|
||||
*
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function dvdfrSearchUrl($title)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
return $dvdfrServer.'/api/search.php?title='.urlencode(mb_convert_encoding($title,'ISO-8859-15','UTF-8'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit Dvdfr for a specific movie
|
||||
*
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function dvdfrContentUrl($id)
|
||||
{
|
||||
list($engineword, $dvdfrID) = explode(':',$id,2);
|
||||
global $dvdfrServer;
|
||||
return $dvdfrServer.'/api/dvd.php?id='.$dvdfrID;
|
||||
#return 'http://koocotte.org/DVDMARK';
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on Dvdfr and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function dvdfrSearch($title)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$para['useragent'] = 'VideoDB (http://www.videodb.net/)';
|
||||
|
||||
$resp = httpClient(dvdfrSearchUrl($title), 1, $para);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Encoding
|
||||
$ary['encoding'] = $resp['encoding'];
|
||||
|
||||
/* No more direct match with XLM API
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
$single = array();
|
||||
if (preg_match('/\/dvd\/dvd\.php\?id=(\d+)/', $resp['url'], $single))
|
||||
{
|
||||
$ary[0]['id'] = 'dvdfr:'.$single[1];
|
||||
preg_match('/<td><div class=\"dvd_title\">([^<]+)<\/div>[^<]*<div class=\"dvd_titlevo\">([^<]+)<\/div>[^<]*<div class=\"dvd_titleinfo\">([^<]+)</is', $resp['data'], $single);
|
||||
$ary[0]['title']= $single[1].' ('.$single[2].'/'.$single[3].')';
|
||||
return $ary;
|
||||
}
|
||||
*/
|
||||
// multiple matches
|
||||
/*
|
||||
<dvd>
|
||||
<id>16892</id> <= $1
|
||||
<media>DVD</media> <= $2
|
||||
<titres>
|
||||
<fr>Star Wars - Clone Wars - Vol. 1</fr> <= $3
|
||||
<vo>Star Wars: Clone Wars</vo> <= $4
|
||||
<alternatif></alternatif>
|
||||
<alternatif_vo></alternatif_vo>
|
||||
</titres>
|
||||
<annee>2003</annee> <= $5
|
||||
<edition></edition> <= $6
|
||||
<editeur>20th Century Fox</editeur> <= $7
|
||||
<stars>
|
||||
<star type="Réalisateur" id="49661">Genndy Tartakovsky</star>
|
||||
</stars>
|
||||
</dvd>
|
||||
*/
|
||||
|
||||
preg_match_all('#<dvd>\s*<id>(\d+)</id>\s*<media>(\w+)</media>\s*<titres>\s*<fr>(.+?)</fr>\s*<vo>(.*?)</vo>.*?<annee>(.*?)</annee>\s*<edition>(.*?)</edition>\s*<editeur>(.*?)</editeur>\s*.*?</dvd>#is', $resp['data'], $data, PREG_SET_ORDER);
|
||||
foreach ($data as $row)
|
||||
{
|
||||
$info['id'] = 'dvdfr:'.$row[1];
|
||||
$title = dvdfrCleanStr($row[3]);
|
||||
// add native title
|
||||
if( !empty($row[4]) ) $title .= " / " . dvdfrCleanStr($row[4]);
|
||||
|
||||
if( !empty($row[5]) and !empty($row[6]) and !empty($row[7]) ) {
|
||||
$title .= ' (';
|
||||
// add year (helpful in case of multiple matches)
|
||||
if( !empty($row[5]) ) $title .= dvdfrCleanStr($row[5]);
|
||||
$title .= '/';
|
||||
// add edition and editor
|
||||
if( !empty($row[6]) ) $title .= dvdfrCleanStr($row[6]);
|
||||
$title .= '/';
|
||||
if( !empty($row[7]) ) $title .= dvdfrCleanStr($row[7]);
|
||||
$title .=')';
|
||||
}
|
||||
|
||||
// Add record
|
||||
$info['title'] = $title;
|
||||
$ary[] = $info;
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given Dvdfr-ID
|
||||
*
|
||||
* @param int IMDB-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function dvdfrData($imdbID)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
$para['useragent'] = 'VideoDB (http://www.videodb.net/)';
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient(dvdfrContentUrl($imdbID), 1, $para); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// See http://www.dvdfr.com/api/dvd.php?id=2869 for output
|
||||
|
||||
// Titles
|
||||
preg_match('#<titres>\s*<fr>(.+?)</fr>\s*<vo>(.+?)</vo>#is', $resp['data'], $ary);
|
||||
$data['title'] = mb_convert_case(dvdfrCleanStr($ary[1]), MB_CASE_TITLE, $data['encoding']);
|
||||
$data['subtitle'] = mb_convert_case(dvdfrCleanStr($ary[2]), MB_CASE_TITLE, $data['encoding']);
|
||||
|
||||
// I found: <div class="dvd_titleinfo">USA, Royaume-Uni , 2004<br />R&D TV, Sky TV, USA Cable Entertainment</div>
|
||||
preg_match('#<listePays>\s*<pays.*?>(.+?)</pays>#is', $resp['data'], $ary);
|
||||
$data['country'] = dvdfrCleanStr($ary[1]);
|
||||
preg_match('#<annee>(\d+)</annee>#is', $resp['data'], $ary);
|
||||
$data['year'] = dvdfrCleanStr($ary[1]);
|
||||
|
||||
// Cover URL
|
||||
preg_match('#<cover>(.*?)</cover>#i', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
// Runtime
|
||||
preg_match('#<duree>(\d+)</duree>#i', $resp['data'], $ary);
|
||||
$data['runtime'] = $ary[1];
|
||||
|
||||
// Director (only the first one)
|
||||
preg_match('#<star type="R.*?alisateur" id="\d+">(.*?)</star>#i', $resp['data'], $ary);
|
||||
$data['director'] = dvdfrCleanStr($ary[1]);
|
||||
|
||||
// Plot
|
||||
preg_match('#<synopsis>(.*?)</synopsis>#is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) {
|
||||
$data['plot'] = $ary[1];
|
||||
// And cleanup
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/\s+/',' ', $data['plot']);
|
||||
$data['plot'] = dvdfrCleanStr($data['plot']);
|
||||
}
|
||||
|
||||
// maps dvdfr category ids to videodb category names
|
||||
$category_map = array
|
||||
(
|
||||
"1" => "Action",
|
||||
"2" => "Animation",
|
||||
"61" => "", // "Autres séries"
|
||||
"3" => "Adventure",
|
||||
"72" => "", //"Beaux-Arts"
|
||||
"81" => "Musical", //"Bollywood"
|
||||
"4" => "Comedy",
|
||||
"5" => "Drama", // "Comédie dramatique"
|
||||
"6" => "Musical", //"Comédie musicale"
|
||||
"74" => "Romance", // "Comédie romantique"
|
||||
"7" => "Music", //"Concert"
|
||||
"8" => "" , //"Conte"
|
||||
"9" => "Short", //"Court-Métrage"
|
||||
"10" => "Documentary", //"Culture"
|
||||
"78" => "Documentary", //"Culture Gay"
|
||||
"11" => "Music", //"Danse"
|
||||
"12" => "", //"Divers"
|
||||
"13" => "Documentary", //"Documentaire"
|
||||
"14" => "Drama", //"Drame"
|
||||
"73" => "Drama", //"Emotion"
|
||||
"15" => "Adult", //"Erotique"
|
||||
"16" => "Action", //"Espionnage"
|
||||
"17" => "Sci-Fi", //"Fantastique"
|
||||
"30" => "Musical", //"Film musical"
|
||||
"83" => "Sport", //"Freefight"
|
||||
"18" => "War", //"Guerre"
|
||||
"19" => "Musical", //"Hard-rock"
|
||||
"20" => "History", //"Historique"
|
||||
"21" => "Horror", //"Horreur"
|
||||
"22" => "Comedy", //"Humour"
|
||||
"23" => "Animation", //"Japanimation"
|
||||
"24" => "Adult", //"Japanimation érotique"
|
||||
"25" => "Music", //"Jazz & Blues"
|
||||
"79" => "", //"Jeux"
|
||||
"26" => "Music", //"Karaoke"
|
||||
"27" => "Action", //"Kung Fu"
|
||||
"28" => "", //"Méthode"
|
||||
"57" => "", //"Mini-series / Feuilletons"
|
||||
"29" => "Documentary", //"Muet"
|
||||
"32" => "Music", //"Musique Classique"
|
||||
"71" => "Music", //"Musiques du monde"
|
||||
"31" => "Music", //"Opéra"
|
||||
"33" => "War", //"Péplum"
|
||||
"34" => "Crime", //"Policier"
|
||||
"54" => "", //"Pour enfants"
|
||||
"76" => "Music", //"R&B & Soul"
|
||||
"55" => "Music", //"Rap"
|
||||
"56" => "Sci-Fi", //"Science Fiction"
|
||||
"60" => "", //"Série Anime / OAV"
|
||||
"75" => "", //"Série d'animation enfants"
|
||||
"58" => "", //"Série TV"
|
||||
"59" => "", //"Sitcom"
|
||||
"62" => "", //"Spectacle"
|
||||
"63" => "Sport",
|
||||
"82" => "Sport", //"Sports mécaniques"
|
||||
"64" => "Music", //"Techno / Electro"
|
||||
"65" => "", //"Theatre"
|
||||
"66" => "Thriller",
|
||||
"67" => "Music", //"Variété française"
|
||||
"68" => "Music", //"Variété internationale"
|
||||
"69" => "Documentary", //"Voyages"
|
||||
"70" => "Western",
|
||||
"Science Fiction" => "Sci-Fi",
|
||||
);
|
||||
|
||||
// Genres (as Array)
|
||||
if (preg_match_all('#<categorie>(.*?)</categorie>#i', $resp['data'], $ary, PREG_PATTERN_ORDER) > 0)
|
||||
{
|
||||
$count = 0;
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$data['genres'][] = $category_map[dvdfrCleanStr($ary[1][$count])];
|
||||
$count ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if( preg_match('#<stars>(.*)</stars>#is', $resp['data'], $Section) ) {
|
||||
preg_match_all('#<star type="Acteur" id="(\d+)">(.*?)</star>#i', $Section[1], $ary,PREG_PATTERN_ORDER);
|
||||
$cast = '';
|
||||
for ($i=0; $i < sizeof($ary[0]); $i++)
|
||||
{
|
||||
$cast .= dvdfrCleanStr($ary[2][$i]) . '::::dvdfr' . dvdfrCleanStr($ary[1][$i]) . "\n";
|
||||
#$cast .= "$actor::$character::$imdbIdPrefix$actorid\n";
|
||||
}
|
||||
$data['cast'] = dvdfrCleanStr($cast);
|
||||
}
|
||||
|
||||
#// Convert ISO to UTF8
|
||||
#$encoding = $data['encoding'];
|
||||
#foreach( $data as $k => $v ) {
|
||||
# $data[$k] = mb_convert_encoding(trim($v),'UTF-8',$encoding);
|
||||
#}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process? Completion waiting on update of actor
|
||||
* functionality to support more than one engine.
|
||||
*
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function dvdfrActor($name, $actorengineid)
|
||||
{
|
||||
global $dvdfrServer;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
452
videodb/engines/engines.php
Normal file
452
videodb/engines/engines.php
Normal file
@@ -0,0 +1,452 @@
|
||||
<?php
|
||||
/**
|
||||
* Multi-engine glue logic
|
||||
*
|
||||
* @package Engines
|
||||
*
|
||||
* @todo Remove global $cache variable
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @version $Id: engines.php,v 1.45 2010/10/15 08:13:01 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/httpclient.php'; // include for all engines
|
||||
require_once './core/encoding.php';
|
||||
|
||||
/**
|
||||
* Determine the default engine
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetDefault()
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!empty($config['enginedefault']))
|
||||
{
|
||||
$engine = $config['enginedefault'];
|
||||
}
|
||||
elseif (count($engine_list = array_keys($config['engines'])))
|
||||
{
|
||||
// first valid engine from list
|
||||
$engine = $engine_list[0];
|
||||
}
|
||||
else $engine = 'imdb'; // last resort
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine engine from id
|
||||
*
|
||||
* @todo Enhance DB schema to store engine type explicitly
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetEngine($id)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// recognize engine from id
|
||||
if ($id)
|
||||
{
|
||||
// engine prefixed (imdb:081547)
|
||||
// currently working for imdb, amazon, amazoncom and tvcom
|
||||
if (preg_match('/^(\w+):/', $id, $match)) $engine = $match[1];
|
||||
elseif (preg_match('/^[0-9A-Z]{10,}$/', $id)) $engine = 'amazonaws'; // Amazon
|
||||
}
|
||||
if (empty($engine)) $engine = 'imdb';
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and retrieve item data
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @param string engine name
|
||||
* @return array item data
|
||||
*/
|
||||
function engineGetData($id, $engine = 'imdb')
|
||||
{
|
||||
global $lang, $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Data';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$cache = true;
|
||||
$result = $func($id);
|
||||
}
|
||||
|
||||
// make sure all engines properly return the encoding type
|
||||
if (empty($result['encoding'])) errorpage('Engine Error', 'Engine '.$engine.' does not properly return encoding');
|
||||
|
||||
// set default encoding iso-8859-1
|
||||
$source_encoding = ($result['encoding']) ? $result['encoding'] : $lang['encoding'];
|
||||
$target_encoding = 'utf-8';
|
||||
unset($result['encoding']);
|
||||
|
||||
// convert to unicode
|
||||
if ($source_encoding != $target_encoding)
|
||||
{
|
||||
$result = iconv_array($source_encoding, $target_encoding, $result);
|
||||
}
|
||||
engine_clean_input($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and execute item search
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string search string
|
||||
* @param string engine name
|
||||
* @return array list of item data
|
||||
*/
|
||||
function engineSearch($find, $engine = 'imdb', $para1 = null, $para2 = null)
|
||||
{
|
||||
global $lang, $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Search';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$cache = true;
|
||||
// check if additional parameters given to avoid overriding default values
|
||||
$result = (isset($para1)) ? $func($find, $para1, $para2) : $func($find);
|
||||
}
|
||||
|
||||
// make sure all engines properly return the encoding type
|
||||
# if (empty($result['encoding'])) errorpage('Engine Error', 'Engine does not properly return encoding');
|
||||
|
||||
// set default encoding iso-8859-1
|
||||
$source_encoding = ($result['encoding']) ? $result['encoding'] : $lang['encoding'];
|
||||
$target_encoding = 'utf-8';
|
||||
unset($result['encoding']);
|
||||
|
||||
// convert to unicode
|
||||
if ($source_encoding != $target_encoding)
|
||||
{
|
||||
#dump("Converting from $source_encoding to $target_encoding");
|
||||
$result = iconv_array($source_encoding, $target_encoding, $result);
|
||||
}
|
||||
|
||||
// obtain unique entries
|
||||
$result = engine_deduplicate_result($result);
|
||||
|
||||
engine_clean_input($result);
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get item details URL in external site
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string item id
|
||||
* @param string engine name
|
||||
* @return string item details url
|
||||
*/
|
||||
function engineGetContentUrl($id, $engine = 'imdb')
|
||||
{
|
||||
if (empty($id)) return '';
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
|
||||
$func = $engine.'ContentUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$result = $func($id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recommendations for a specific movie that meets the requirements
|
||||
* of rating and release year.
|
||||
*
|
||||
* @author Klaus Christiansen <klaus_edwin@hotmail.com>
|
||||
* @param int $id The external movie id.
|
||||
* @param float $rating The minimum rating for the recommended movies.
|
||||
* @param int $year The minimum year for the recommended movies.
|
||||
* @return array Associative array with: id, title, rating, year.
|
||||
*/
|
||||
function engineGetRecommendations($id, $rating, $year, $engine = 'imdb')
|
||||
{
|
||||
if (empty($id)) return '';
|
||||
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'Recommendations';
|
||||
|
||||
if (function_exists($func))
|
||||
{
|
||||
return $func($id, $rating, $year);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get complete search URL for external site
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string search string
|
||||
* @param string engine name
|
||||
* @return string item search url
|
||||
*/
|
||||
function engineGetSearchUrl($find, $engine = 'imdb')
|
||||
{
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'SearchUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$result = $func($find);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is used internally by setup and engines to add meta-engine of the engine's capability type
|
||||
* e.g. if the youtube engine provides 'trailer' capability, this will add $config[engine][trailer] = (youtube)
|
||||
*/
|
||||
function engine_setup_meta($engine, $meta)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (array_key_exists('capabilities', $meta) && is_array($meta['capabilities'])) {
|
||||
foreach ($meta['capabilities'] as $caps) {
|
||||
$config['engine'][$caps][] = $engine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve meta information about all available engines
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @return array engines array containing engine names
|
||||
*/
|
||||
function engineMeta()
|
||||
{
|
||||
$engines = array();
|
||||
|
||||
if ($dh = @opendir(__DIR__))
|
||||
{
|
||||
while (($file = readdir($dh)) !== false)
|
||||
{
|
||||
if ((preg_match("/(.*)\.php$/", $file, $matches)) && ($matches[1] != 'engines'))
|
||||
{
|
||||
// engine file
|
||||
$engine = $matches[1];
|
||||
|
||||
// get meta data
|
||||
engine_load_engine($engine);
|
||||
|
||||
$func = $engine.'Meta';
|
||||
|
||||
if (function_exists($func))
|
||||
{
|
||||
$meta = $func();
|
||||
$engines[$engine] = $meta;
|
||||
|
||||
// required php version present?
|
||||
if (array_key_exists( 'php', $engines[$engine] ) && (version_compare(phpversion(), $engines[$engine]['php']) < 0))
|
||||
{
|
||||
unset($engines[$engine]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir($dh);
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine actor engine from actor id, defaults to imdb
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor id
|
||||
* @return string engine name
|
||||
*/
|
||||
function engineGetActorEngine($id)
|
||||
{
|
||||
// recognize engine from id
|
||||
if ($id)
|
||||
{
|
||||
// actor engine prefixed, too? (imdb:nm0347149)
|
||||
if (preg_match('/^(\w+):/', $id, $match)) $engine = $match[1];
|
||||
elseif (preg_match('/^tv\d+$/', $id)) $engine = 'tvcom';
|
||||
}
|
||||
if (empty($engine)) $engine = 'imdb';
|
||||
|
||||
return $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get actors details URL in external site
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor name
|
||||
* @param string actor id
|
||||
* @param string engine name
|
||||
* @return string actor details url
|
||||
*/
|
||||
function engineGetActorUrl($name, $id, $engine = 'imdb')
|
||||
{
|
||||
if (!engine_load_engine($engine)) return '';
|
||||
$func = $engine.'ActorUrl';
|
||||
|
||||
$result = '';
|
||||
if (function_exists($func))
|
||||
{
|
||||
$id = preg_replace('|^'.$engine.':|', '', $id);
|
||||
$result = $func($name, $id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Include engine file and execute item search
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string actor name
|
||||
* @param string actor id
|
||||
* @param string engine name
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function engineActor($name, $id, $engine = 'imdb')
|
||||
{
|
||||
global $cache;
|
||||
|
||||
if (!engine_load_engine($engine)) return array();
|
||||
$func = $engine.'Actor';
|
||||
|
||||
$result = array();
|
||||
if (function_exists($func))
|
||||
{
|
||||
$id = preg_replace('|^'.$engine.':|', '', $id);
|
||||
|
||||
$cache = true;
|
||||
$result = $func($name, $id);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function for validating if an engine has a certain capability
|
||||
*/
|
||||
function engine_get_capability($engine, $searchtype)
|
||||
{
|
||||
global $config;
|
||||
|
||||
// get the meta information
|
||||
$engine = $config['engines'][$engine];
|
||||
|
||||
if (array_key_exists( 'capabilities', $engine) && is_array($engine['capabilities']))
|
||||
{
|
||||
return in_array($searchtype, $engine['capabilities']);
|
||||
}
|
||||
else
|
||||
{
|
||||
return $searchtype == 'movie';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of engines which have certain capability
|
||||
*
|
||||
* 'movie' search capability is assumed as default, either if
|
||||
* $searchtype is empty or engine does not maintain specific capability
|
||||
*
|
||||
* @return array list of capable engines
|
||||
*/
|
||||
function engine_get_capable_engines($searchtype)
|
||||
{
|
||||
global $config;
|
||||
|
||||
if (!$searchtype) $searchtype = 'movie';
|
||||
|
||||
$engines = array();
|
||||
foreach ($config['engines'] as $engine => $meta)
|
||||
{
|
||||
$enabled = $config['engine'][$engine];
|
||||
if ($enabled && engine_get_capability($engine, $searchtype)) $engines[$engine] = $enabled;
|
||||
}
|
||||
|
||||
return $engines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean HTML tags from hierarchical associative array
|
||||
*
|
||||
* @param array $data string or hierarchical array to convert
|
||||
*/
|
||||
function engine_clean_input(&$data)
|
||||
{
|
||||
if (is_array($data)) foreach ($data as $key => $val)
|
||||
{
|
||||
if (is_array($val))
|
||||
engine_clean_input($data[$key]);
|
||||
else
|
||||
{
|
||||
$val = html_to_text($val);
|
||||
$data[$key] = html_clean_utf8($val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter result set for unique engine ids.
|
||||
* This avoids deduplication of search results inside every single engine.
|
||||
*/
|
||||
function engine_deduplicate_result($data)
|
||||
{
|
||||
$keys = array();
|
||||
for ($i=0; $i<count($data); $i++)
|
||||
{
|
||||
$id = $data[$i]['id'];
|
||||
// early exit if engine (e.g. google images) doesn't return ids
|
||||
if (!$id) return $data;
|
||||
// exclude duplicates
|
||||
if (in_array($id, $keys))
|
||||
unset($data[$i]);
|
||||
else
|
||||
$keys[] = $id;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the selected engine without errors
|
||||
*
|
||||
* @param string $engine
|
||||
* @return bool
|
||||
*/
|
||||
function engine_load_engine($engine) {
|
||||
if (file_exists(__DIR__ . '/' . $engine.'.php')) {
|
||||
include_once __DIR__ . '/' . $engine.'.php';
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
333
videodb/engines/filmweb.php
Normal file
333
videodb/engines/filmweb.php
Normal file
@@ -0,0 +1,333 @@
|
||||
<?php
|
||||
/**
|
||||
* FilmWeb Parser (pl)
|
||||
*
|
||||
* Parses data from the Polish FilmWeb site
|
||||
*
|
||||
* @package Engines
|
||||
* @author Marek Domaniuk <domanm@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @desc Original filmweb.php by Marek Domaniuk, rewritten by Victor La
|
||||
* @desc using Andreas Goetz's imdb.php as a template
|
||||
* @link https://www.filmweb.com Internet Movie Database
|
||||
* @version $Id: filmweb.php,v 1.4 2007/08/08 18:28:15 andig2 Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['filmwebServer'] = 'https://www.filmweb.pl';
|
||||
$GLOBALS['filmwebIdPrefix'] = 'filmweb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function filmwebMeta()
|
||||
{
|
||||
return array('name' => 'FilmWeb (pl)', 'stable' => 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to search FilmWeb for a movie
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function filmwebSearchUrl($title)
|
||||
{
|
||||
global $filmwebServer;
|
||||
return $filmwebServer.'/Find?query='.urlencode($title).'&category=1&submit=szukaj';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit FilmWeb for a specific movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function filmwebContentUrl($id)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
$id = preg_replace('/^'.$filmwebIdPrefix.'/', '', $id);
|
||||
return $filmwebServer.'/Film?id='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url for actor on FilmWeb
|
||||
*
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $name Name of the Actor
|
||||
* @return string The actor URL (GET)
|
||||
*/
|
||||
function filmwebActorUrl($name, $actorid)
|
||||
{
|
||||
global $filmwebServer;
|
||||
$url = ($actorid) ? '/Person,id='.urlencode($actorid) : '/szukaj?q='.urlencode($name).'&alias=person';
|
||||
return $filmwebServer.$url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the FilmWeb and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function filmwebSearch($title)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$resp = httpClient(filmwebSearchUrl($title), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
preg_match_all('/<a class="searchResultTitle" href="(.+?)">(.+?)<\/a>.+?\((.+?)\)/si', $resp['data'], $data, PREG_SET_ORDER);
|
||||
foreach ($data as $row)
|
||||
{
|
||||
$info['id'] = trim($row[1]);
|
||||
|
||||
$row[2] = preg_replace('/<b>/','', $row[2]);
|
||||
$row[2] = preg_replace('/<\/b>/','', $row[2]);
|
||||
$info['title'] = trim($row[2]);
|
||||
|
||||
// add year (helpful in case of multiple matches)
|
||||
$info['title'] = $info['title'].' ('.$row[3].')';
|
||||
|
||||
//Check URL to see if the movie ID is in it, if not, load the page and grab it from that new page
|
||||
if (preg_match('/id=(\d+)/', $info['id'], $single))
|
||||
{
|
||||
$info['id'] = $single[1];
|
||||
}
|
||||
elseif ((strpos($info['id'], 'id=')) != true)
|
||||
{
|
||||
$subResp = httpClient($info['id'],1);
|
||||
if (!$subResp['success']) $CLIENTERROR .= $subResp['error']."\n";
|
||||
//<a class="n" href="https://www.filmweb.pl/AddFilmFavourite?film.id=108130">dodaj do ulubionych</a>
|
||||
preg_match('/,id=(\d+)">/i', $subResp['data'], $single);
|
||||
$info['id'] = $single[1];
|
||||
}
|
||||
$info['id'] = $filmwebIdPrefix.$info['id'];
|
||||
|
||||
$ary[] = $info;
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given FilmWeb-ID
|
||||
*
|
||||
* @author Marek Domaniuk <domark@o2.pl>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param int FilmWeb-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function filmwebData($filmwebID)
|
||||
{
|
||||
global $filmwebServer;
|
||||
global $filmwebIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$filmwebID = preg_replace('/^'.$filmwebIdPrefix.'/', '', $filmwebID);
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient(filmwebContentUrl($filmwebID), 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Titles - Fixed
|
||||
preg_match('/<div id="filmTitle">(.*?)<span class="otherTitle">(.+?)<\/span>/is', $resp['data'], $ary);
|
||||
$data['title'] = trim($ary[1]);
|
||||
|
||||
//DOUBLE CHECK THIS SECTION OF CODE FOR THE SUBTITLE!
|
||||
if (!preg_match('/<a href/i', $ary[2], $tempary)) {
|
||||
$data['subtitle'] = trim($ary[2]);
|
||||
}
|
||||
if (preg_match('/\(AKA (.+?)\)/i', $ary[2], $tempary)) {
|
||||
$data['subtitle'] = trim($tempary[1]);
|
||||
}
|
||||
|
||||
// Year - Fixed
|
||||
preg_match('/\(([1-2][0-9][0-9][0-9])\)/i', $resp['data'], $ary);
|
||||
$data['year'] = trim($ary[1]);
|
||||
|
||||
// Cover-URL - Fixed
|
||||
//<img src="https://gfx.filmweb.pl/f/94745/po.6954459.jpg"
|
||||
//https://gfx.filmweb.pl/f/520/520.jpg
|
||||
preg_match('/<div id="filmPhoto">.+?<img border="0" src="(.+?)"/si', $resp['data'], $ary);
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
|
||||
// MPAA Rating
|
||||
$data['mpaa'] = '';
|
||||
|
||||
// UK BBFC Rating
|
||||
$data['bbfc'] = '';
|
||||
|
||||
// Runtime
|
||||
preg_match('/czas trwania.+?([0-9,]+)\s/si', $resp['data'], $ary);
|
||||
$data['runtime'] = preg_replace('/,/', '', trim($ary[1]));
|
||||
|
||||
// Director - Fixed
|
||||
//re¿yseria <a class="n" title="Kerry Conran: filmografia [Filmweb.pl]" //href="https://www.filmweb.pl/Kerry,Conran,filmografia,Person,id=138676">Kerry Conran</a>
|
||||
preg_match('/re.yseria.+?title="(.+?)- filmografia.+?"/i', $resp['data'], $ary);
|
||||
$data['director'] = trim($ary[1]);
|
||||
|
||||
// Rating - Fixed
|
||||
preg_match('/<b class="rating">(.+?)<\/b>\/10/i', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
// Countries - Fixed
|
||||
preg_match_all('/<a href="https:\/\/www.filmweb.pl\/szukaj\/film\?countryids=\d.+?">(.+?)<\/A>/i', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
|
||||
// Languages - DOES THIS NEED TO BE FIXED?
|
||||
//$data['language'] = '';
|
||||
|
||||
// Plot (movies in their early stages have the plot here but not yet in plotsummary?) - Fixed 4-5-07
|
||||
// Not necessary for FilmWeb?
|
||||
|
||||
// Genres (as Array) - Fixed
|
||||
$genres = array(
|
||||
'Przygodowy' => 'Adventure',
|
||||
'Akcja' => 'Action',
|
||||
'Komedia' => 'Comedy',
|
||||
'Familijny' => 'Family',
|
||||
'Muzyka' => 'Music',
|
||||
'Western' => 'Western',
|
||||
'Dla doros³ych' => 'Adult',
|
||||
'Krymina³' => 'Crime',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Musical' => 'Musical',
|
||||
'Muzyczny' => 'Musical',
|
||||
'Krótkometra¿owy' => 'Short',
|
||||
'Dokumentalny' => 'Documentary',
|
||||
'Film-Noir' => 'Film-Noir',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Dreszczowiec' => 'Thriller',
|
||||
'Animacja' => 'Animation',
|
||||
'Dramat' => 'Drama',
|
||||
'Melodramat' => 'Drama',
|
||||
'Dramat historyczny' => 'History',
|
||||
'Historyczny' => 'History',
|
||||
'Dramat obyczajowy' => 'Drama',
|
||||
'Dramat s±dowy' => 'Drama',
|
||||
'Dramat spo³eczny' => 'Drama',
|
||||
'Horror' => 'Horror',
|
||||
'Romans' => 'Romance',
|
||||
'Wojenny' => 'War',
|
||||
'Biograficzny' => 'Biographic',
|
||||
'Erotyczny' => 'Adult',
|
||||
'Komedia kryminalna' => 'Comedy',
|
||||
'Komedia obycz.' => 'Comedy',
|
||||
'Komedia rom.' => 'Comedy',
|
||||
'Komedia' => 'Comedy',
|
||||
'Czarna komedia' => 'Comedy',
|
||||
'Dla dzieci' => '',
|
||||
'Obyczajowy' => '',
|
||||
'Bibilijny' => '',
|
||||
'Sensacja' => 'Action',
|
||||
'Sensacyjny' => 'Action',
|
||||
'Fabularyzowany dok.' => 'Documentary',
|
||||
'Psychologiczny' => ''
|
||||
);
|
||||
preg_match_all('/genreIds=\d.+?">(.+?)</i', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
foreach($ary[1] as $genre)
|
||||
{
|
||||
$genre = trim($genre);
|
||||
if (!($genre)) continue;
|
||||
if (isset($genres[$genre])) $genre = $genres[$genre];
|
||||
if (!($genre)) continue;
|
||||
$data['genres'][] = $genre;
|
||||
}
|
||||
|
||||
// Cast - Fixed
|
||||
preg_match_all('/<a class="filmActor" HREF="(.+?)".+?>(.+?)<\/a>.+?((<br\/>).|(<div class="filmRoleSeparator">:<\/div>.+?<div class="filmRole">(.+?)<\/div>))/si', $resp['data'], $ary,PREG_PATTERN_ORDER);
|
||||
$count = 0;
|
||||
$cast = '';
|
||||
while (isset($ary[1][$count]))
|
||||
{
|
||||
$actor = trim(strip_tags($ary[2][$count]));
|
||||
$role = trim(strip_tags($ary[6][$count]));
|
||||
$role = preg_replace('/ /',' ', $role);
|
||||
$role = trim($role);
|
||||
|
||||
//$actorid= $ary[1][$count]; //, $m)) ? $m[1] : '';
|
||||
preg_match('/.+?Person\,id=(\d+)/i', $ary[1][$count], $ary2);
|
||||
|
||||
if (!empty($ary2[1]))
|
||||
{
|
||||
$actorid= $ary2[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
$resp = httpClient($ary[1][$count], 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
preg_match('/,Person.+?,id=(\d+)">/i', $resp['data'], $ary2);
|
||||
if (!empty($ary2[1])) $actorid = $ary2[1];
|
||||
}
|
||||
|
||||
|
||||
$cast .= "$actor::$role::$filmwebIdPrefix$actorid\n";
|
||||
$count++;
|
||||
}
|
||||
$data['cast'] = trim($cast);
|
||||
|
||||
// fetch Plot
|
||||
$resp = httpClient($filmwebServer.'/FilmDescriptions?id='.$filmwebID, 1);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Plot
|
||||
preg_match('/<li><div.+?">(.+?)<\/div><\/li>/is', $resp['data'], $ary);
|
||||
if (!empty($ary[1])) $data['plot'] = trim($ary[1]);
|
||||
$data['plot'] = preg_replace('/[\n\r]/',' ', $data['plot']);
|
||||
$data['plot'] = preg_replace('/ /',' ', $data['plot']);
|
||||
$data['plot'] = trim($data['plot']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process?
|
||||
*
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function filmwebActor($name, $actorid)
|
||||
{
|
||||
global $filmwebServer;
|
||||
|
||||
// search directly by id or via name?
|
||||
$resp = httpClient(filmwebActorUrl($name, $actorid), 1);
|
||||
|
||||
$ary = array();
|
||||
|
||||
if (preg_match('/<a class="searchResultTitle" href="(.+?)">/i', $resp['data'], $m)) {
|
||||
$resp = httpClient($m[1], true);
|
||||
}
|
||||
|
||||
// now we should have loaded the best match
|
||||
if (preg_match('/<img src="https:\/\/gfx.filmweb.pl\/p\/(.+?)"/i', $resp['data'], $m))
|
||||
{
|
||||
$ary[0][0] = 'https://gfx.filmweb.pl/p/'.$m[1];
|
||||
$ary[0][1] = 'https://gfx.filmweb.pl/p/'.$m[1];
|
||||
return $ary;
|
||||
}
|
||||
else return null;
|
||||
}
|
||||
|
||||
98
videodb/engines/google.php
Normal file
98
videodb/engines/google.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
// DEFUNCT, no clue if this is alternative: https://developers.google.com/custom-search/v1/reference/rest/v1/cse/list
|
||||
/**
|
||||
* Google Image Parser
|
||||
*
|
||||
* Lookup cover images from Google
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Götz <cpuidle@gmx.de>
|
||||
*
|
||||
* @link http://images.google.com Google image search
|
||||
* @link http://code.google.com/apis/ajaxsearch/documentation/ API doc
|
||||
*
|
||||
* @version $Id: google.php,v 1.13 2013/03/16 14:29:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function googleMeta()
|
||||
{
|
||||
return array('name' => 'Google', 'stable' => 1, 'capabilities' => array('image'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Search an image on Google
|
||||
*
|
||||
* Searches for a given title on the google and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function googleSearch($title)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $config;
|
||||
global $savedata_for_errorpage;
|
||||
|
||||
$page = 1;
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
|
||||
do
|
||||
{
|
||||
$url = "http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=large&q=".urlencode($title)."&start=".count($data);
|
||||
|
||||
if ( $config['debug'] )
|
||||
{
|
||||
// save data to pass to functions.php - erropage
|
||||
// if url fails in httpclient it can go directly to errorpage which loses
|
||||
// message set in httpCLient
|
||||
// this is a cause of not finding cover url
|
||||
$savedata_for_errorpage = 'Module->google.php, Message->';
|
||||
}
|
||||
|
||||
$resp = httpClient($url, $cache);
|
||||
|
||||
if ( $config['debug'] )
|
||||
{
|
||||
unset($savedata_for_errorpage);
|
||||
}
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$json = json_decode($resp['data']);
|
||||
# dump($resp['data']);
|
||||
# dump($page);
|
||||
# dump($json);
|
||||
|
||||
// prevent caching invalid responses
|
||||
if ($json->responseStatus != 200 && $cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
|
||||
foreach ($json->responseData->results as $row)
|
||||
{
|
||||
# dump($row);
|
||||
$res = array();
|
||||
$res['title'] = $row->width.'x'.$row->height; // width x height
|
||||
$res['imgsmall']= $row->tbUrl; // small thumbnail url
|
||||
$res['coverurl']= $row->url; // resulting target url
|
||||
$data[] = $res;
|
||||
}
|
||||
}
|
||||
// Google does not return more than 4 pages of results. Limiting to 2 for performance
|
||||
while ($page++ < 3);
|
||||
|
||||
# dump($data);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
?>
|
||||
804
videodb/engines/imdb.php
Normal file
804
videodb/engines/imdb.php
Normal file
@@ -0,0 +1,804 @@
|
||||
<?php
|
||||
/**
|
||||
* IMDB Parser
|
||||
*
|
||||
* Parses data from the Internet Movie Database
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Gohr <a.gohr@web.de>
|
||||
* @link http://www.imdb.com Internet Movie Database
|
||||
* @version $Id: imdb.php,v 1.76 2013/04/10 18:11:43 andig2 Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['imdbServer'] = 'https://www.imdb.com';
|
||||
$GLOBALS['imdbIdPrefix'] = 'imdb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function imdbMeta()
|
||||
{
|
||||
return array('name' => 'IMDB', 'stable' => 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to search IMDB for a movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function imdbSearchUrl($title)
|
||||
{
|
||||
global $imdbServer;
|
||||
return $imdbServer.'/find?s=all&q='.urlencode($title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url to visit IMDB for a specific movie
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function imdbContentUrl($id)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
$id = preg_replace('/^'.$imdbIdPrefix.'/', '', $id);
|
||||
return $imdbServer.'/title/tt'.$id.'/';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IMDB recommendations for a specific movie that meets the requirements
|
||||
* of rating and release year.
|
||||
*
|
||||
* @author Klaus Christiansen <klaus_edwin@hotmail.com>
|
||||
* @param int $id The external movie id.
|
||||
* @param float $rating The minimum rating for the recommended movies.
|
||||
* @param int $year The minimum year for the recommended movies.
|
||||
* @return array Associative array with: id, title, rating, year.
|
||||
* If error: $CLIENTERROR contains the http error and blank is returned.
|
||||
*/
|
||||
// Only used in contrib/add_recommended_movies.php
|
||||
function imdbRecommendations($id, $required_rating, $required_year)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
|
||||
$url = imdbContentUrl($id);
|
||||
$resp = httpClient($url, true);
|
||||
|
||||
$recommendations = array();
|
||||
preg_match_all('/<div class="rec_item" data-info=".*?" data-spec=".*?" data-tconst="tt(\d+)">/si', $resp['data'], $ary, PREG_SET_ORDER);
|
||||
|
||||
foreach ($ary as $recommended_id) {
|
||||
$rec_resp = getRecommendationData($recommended_id[1]);
|
||||
$imdbId = $recommended_id[1];
|
||||
$title = $rec_resp['title'];
|
||||
$year = $rec_resp['year'];
|
||||
$rating = $rec_resp['rating'];
|
||||
|
||||
// matching at least required rating?
|
||||
if (empty($required_rating) || (float) $rating < $required_rating) continue;
|
||||
|
||||
// matching at least required year?
|
||||
if (empty($required_year) || (int) $year < $required_year) continue;
|
||||
|
||||
$data = array();
|
||||
$data['id'] = $imdbId;
|
||||
$data['rating'] = $rating;
|
||||
$data['title'] = $title;
|
||||
$data['year'] = $year;
|
||||
|
||||
$recommendations[] = $data;
|
||||
}
|
||||
return $recommendations;
|
||||
}
|
||||
|
||||
function getRecommendationData($imdbID) {
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
|
||||
$imdbID = preg_replace('/^'.$imdbIdPrefix.'/', '', $imdbID);
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($imdbServer.'/title/tt'.$imdbID.'/', true); // added trailing / to avoid redirect
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Titles and Year
|
||||
// See for different formats. https://contribute.imdb.com/updates/guide/title_formats
|
||||
if ($data['istv']) { // @todo this is always false
|
||||
if (preg_match('/<title>"(.+?)"(.+?)\(TV Episode (\d+)\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles one episode of a TV serie
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = $ary[3];
|
||||
} else if (preg_match('/<title>(.+?)\(TV Series (\d+).+?<\/title>/si', $resp['data'], $ary)){
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
} else {
|
||||
preg_match('/<title>(.+?)\((\d+)\).+?<\/title>/si', $resp['data'], $ary);
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
preg_match('/<span class="AggregateRatingButton__RatingScore-.+?">(.+?)<\/span>/si', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the IMDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Charles Morgan <cmorgan34@yahoo.com>
|
||||
* @param string title The search string
|
||||
* @param boolean aka Use AKA search for foreign language titles
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function imdbSearch($title, $aka=null)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$url = $imdbServer.'/find?q='.urlencode($title);
|
||||
if ($aka) $url .= ';s=tt;site=aka';
|
||||
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$data = array();
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// direct match (redirecting to individual title)?
|
||||
// @todo i don't think this gets called anymore, investigate
|
||||
if (preg_match('/^'.preg_quote($imdbServer,'/').'\/[Tt]itle(\?|\/tt)([0-9?]+)\/?/', $resp['url'], $single))
|
||||
{
|
||||
$info = array();
|
||||
$info['id'] = $imdbIdPrefix.$single[2];
|
||||
|
||||
// Title
|
||||
preg_match('/<title>(.*?) \([1-2][0-9][0-9][0-9].*?\)<\/title>/i', $resp['data'], $m);
|
||||
list($t, $s) = explode(' - ', trim($m[1]), 2);
|
||||
$info['title'] = trim($t);
|
||||
$info['subtitle'] = trim($s);
|
||||
|
||||
$data[] = $info;
|
||||
}
|
||||
|
||||
// multiple matches
|
||||
else if (preg_match_all('#div class="ipc-metadata-list-summary-item__tc".*href="/title/tt(\d+)/.*>([^\<]+)</a>.*<ul.*>(.*)</ul>.*</div>#Uism', $resp['data'], $multi, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($multi as $row)
|
||||
{
|
||||
$info = [
|
||||
'id' => $imdbIdPrefix.$row[1],
|
||||
'title' => $row[2],
|
||||
'year' => null
|
||||
];
|
||||
if (preg_match_all('#<label.*>([^\<]+)</label>#Uism', $row[3], $labels, PREG_PATTERN_ORDER))
|
||||
{
|
||||
foreach ($labels[1] as $label)
|
||||
{
|
||||
if (preg_match('#^(\d{4})$#i', $label)) $info['year'] = $label;
|
||||
if (preg_match('#^.*(episode|series)$#i', $label)) $info['title'] .= ' ('.$label.')';
|
||||
}
|
||||
}
|
||||
$data[] = $info;
|
||||
}
|
||||
} elseif (preg_match_all('/<div class="col-title">.+?<a href="\/title\/tt(\d+)\/\?ref_=adv_li_tt".+?>(.+?)<\/a>.+?<span .+?>\((\d+).*?\)<\/span>/is', $resp['data'], $ary, PREG_SET_ORDER)) {
|
||||
foreach ($ary as $row) {
|
||||
$info = array();
|
||||
$info['id'] = $imdbIdPrefix.$row[1];
|
||||
$info['title'] = $row[2];
|
||||
$info['year'] = $row[3];
|
||||
$data[] = $info;
|
||||
}
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given IMDB-ID
|
||||
*
|
||||
* @author Tiago Fonseca <t_r_fonseca@yahoo.co.uk>
|
||||
* @author Victor La <cyridian@users.sourceforge.net>
|
||||
* @author Roland Obermayer <robelix@gmail.com>
|
||||
* @param int IMDB-ID
|
||||
* @return array Result data
|
||||
*/
|
||||
function imdbData($imdbID)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$imdbID = preg_replace('/^'.$imdbIdPrefix.'/', '', $imdbID);
|
||||
$data= array(); // result
|
||||
$ary = array(); // temp
|
||||
|
||||
// fetch mainpage
|
||||
$resp = httpClient($imdbServer.'/title/tt'.$imdbID.'/', $cache); // added trailing / to avoid redirect
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_title.html', $resp['data']); // write page data to file
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// extract json data from page
|
||||
if (preg_match('#(\<script id\="__NEXT_DATA__".*?\>)(.*?)(\</script\>)#',$resp['data'],$matches))
|
||||
{
|
||||
#file_put_contents('./cache/nextdata.json', $matches[2]); // write json data to file
|
||||
$json_data = json_decode($matches[2],true);
|
||||
#file_put_contents('./cache/nextdata-decoded.json', print_r($json_data, true)); // write formated json data to file
|
||||
}
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// Check if it is a TV series episode
|
||||
if (preg_match('/<title>.+?\(TV (Episode|Series|Mini-Series).*?<\/title>/si', $resp['data'])) {
|
||||
$data['istv'] = 1;
|
||||
|
||||
# find id of Series
|
||||
preg_match('/<meta property="imdb:pageConst" content="tt(\d+)"\/>/si', $resp['data'], $ary);
|
||||
$data['tvseries_id'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Titles and Year
|
||||
// See for different formats. https://contribute.imdb.com/updates/guide/title_formats
|
||||
if ($data['istv']) {
|
||||
if (preg_match('/<title>"(.+?)"(.+?)\(TV Episode (\d+)\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles one episode of a TV serie
|
||||
$data['title'] = trim($ary[1]);
|
||||
$data['subtitle'] = trim($ary[2]);
|
||||
$data['year'] = $ary[3];
|
||||
} else if (preg_match('/<title>(.+?)\(TV (?:Series|Mini-Series) (\d+).+?\) - IMDb<\/title>/si', $resp['data'], $ary)) {
|
||||
# handles a TV series.
|
||||
# split title - subtitle
|
||||
list($t, $s) = explode(' - ', $ary[1], 2);
|
||||
# no dash, lets try colon
|
||||
if ($s == false) {
|
||||
list($t, $s) = explode(': ', $ary[1], 2);
|
||||
}
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
$data['year'] = trim($ary[2]);
|
||||
}
|
||||
} else {
|
||||
preg_match('/<title>(.+?)\(.*?(\d+)\).+?<\/title>/si', $resp['data'], $ary);
|
||||
$data['year'] = trim($ary[2]);
|
||||
# split title - subtitle
|
||||
list($t, $s) = explode(' - ', $ary[1], 2);
|
||||
# no dash, lets try colon
|
||||
if ($s == false) {
|
||||
list($t, $s) = explode(': ', $ary[1], 2);
|
||||
}
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
}
|
||||
# orig. title
|
||||
preg_match('/<div class="originalTitle">(.+?)<span class="description"> \(original title\)<\/span><\/div>/si', $resp['data'], $ary);
|
||||
$data['origtitle'] = trim($ary[1]);
|
||||
|
||||
// Cover URL
|
||||
$data['coverurl'] = imdbGetCoverURL($resp['data'], $json_data);
|
||||
|
||||
// MPAA Rating
|
||||
$data['mpaa'] = "";
|
||||
$data['mpaa'] = $json_data["props"]["pageProps"]["aboveTheFoldData"]["certificate"]["rating"];
|
||||
|
||||
// Runtime
|
||||
if (filter_var($json_data["props"]["pageProps"]["aboveTheFoldData"]["runtime"]["seconds"], FILTER_SANITIZE_NUMBER_INT) > 0) {
|
||||
# use the runtime from the next_data json data
|
||||
$data['runtime'] = filter_var($json_data["props"]["pageProps"]["aboveTheFoldData"]["runtime"]["seconds"], FILTER_SANITIZE_NUMBER_INT) / 60;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+(?:h|s).*?(?:(?:<!-- --> ?)+(\d+)(?:<!-- --> ?)+.+?)?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handles Hours and maybe minutes. Some movies are exactly 1 hours.
|
||||
$minutes = intval($ary[2]);
|
||||
if (is_numeric($ary[1])) {
|
||||
$minutes += intval($ary[1]) * 60;
|
||||
}
|
||||
|
||||
$data['runtime'] = $minutes;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+m.*?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
$data['runtime'] = $ary[1];
|
||||
} else if (preg_match('/<div class="ipc-metadata-list-item__content-container">(\d+)(?:<!-- --> ?)+m.*?<\/div>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
# Handles the case where runtime is only in the technical spec section.
|
||||
$data['runtime'] = $ary[1];
|
||||
}
|
||||
|
||||
// Rating
|
||||
preg_match('/<div data-testid="hero-rating-bar__aggregate-rating__score" class="sc-.+?"><span class="sc-.+?">(.+?)<\/span><span>\/<!-- -->10<\/span><\/div>/si', $resp['data'], $ary);
|
||||
$data['rating'] = trim($ary[1]);
|
||||
|
||||
// Countries
|
||||
preg_match_all('/href="\/search\/title\/\?country_of_origin.+?>(.+?)<\/a>/si', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
|
||||
// Languages
|
||||
$data['language'] = '';
|
||||
if (isset( $json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"]) &&
|
||||
is_array($json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"]))
|
||||
{
|
||||
foreach ($json_data["props"]["pageProps"]["mainColumnData"]["spokenLanguages"]["spokenLanguages"] as $languagedata)
|
||||
{
|
||||
$languagearray[] = trim($languagedata["text"]);
|
||||
}
|
||||
$data['language'] = trim(strtolower(join(', ',$languagearray)));
|
||||
}
|
||||
|
||||
// Genres (as Array)
|
||||
preg_match_all('/class="ipc-chip__text">(.+?)<\/span><\/a>/si', $resp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
foreach($ary[1] as $genre) {
|
||||
$data['genres'][] = trim($genre);
|
||||
}
|
||||
|
||||
// for Episodes - try to get some missing stuff from the main series page
|
||||
if ( $data['istv'] and (!$data['runtime'] or !$data['country'] or !$data['language'] or !$data['coverurl'])) {
|
||||
$sresp = httpClient($imdbServer.'/title/tt'.$data['tvseries_id'].'/', $cache);
|
||||
if (!$sresp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
# runtime
|
||||
if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+(?:h|s).*?(?:(?:<!-- --> ?)+(\d+)(?:<!-- --> ?)+.+?)?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handles Hours and maybe minutes. Some movies are exactly 1 hours.
|
||||
$minutes = intval($ary[2]);
|
||||
if (is_numeric($ary[1])) {
|
||||
$minutes += intval($ary[1]) * 60;
|
||||
}
|
||||
|
||||
$data['runtime'] = $minutes;
|
||||
} else if (preg_match('/<li role="presentation" class="ipc-inline-list__item">(\d+)(?:<!-- --> ?)+m.*?<\/li>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
$data['runtime'] = $ary[1];
|
||||
} else if (preg_match('/<div class="ipc-metadata-list-item__content-container">(\d+)(?:<!-- --> ?)+m.*?<\/div>/si', $resp['data'], $ary)) {
|
||||
# handle only minutes
|
||||
# Handles the case where runtime is only in the technical spec section.
|
||||
$data['runtime'] = $ary[1];
|
||||
}
|
||||
|
||||
# country
|
||||
if (!$data['country']) {
|
||||
preg_match_all('/href="\/search\/title\/\?country_of_origin.+?>(.+?)<\/a>/si', $sresp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['country'] = trim(join(', ', $ary[1]));
|
||||
}
|
||||
|
||||
# language
|
||||
if (!$data['language']) {
|
||||
preg_match_all('/<a class=".+?" rel="" href="\/search\/title\?title_type=feature&primary_language=.+?&sort=moviemeter,asc&ref_=tt_dt_ln">(.+?)<\/a>/', $sresp['data'], $ary, PREG_PATTERN_ORDER);
|
||||
$data['language'] = trim(strtolower(join(', ', $ary[1])));
|
||||
}
|
||||
|
||||
# cover
|
||||
if (!$data['coverurl']) {
|
||||
$data['coverurl'] = imdbGetCoverURL($sresp['data']);
|
||||
}
|
||||
}
|
||||
|
||||
// Plot
|
||||
if (array_key_exists('plainText', $json_data["props"]["pageProps"]["aboveTheFoldData"]["plot"]["plotText"]) )
|
||||
{
|
||||
$data['plot'] = stripslashes($json_data["props"]["pageProps"]["aboveTheFoldData"]["plot"]["plotText"]["plainText"]);
|
||||
}
|
||||
|
||||
// Fetch credits
|
||||
$resp = imdbFixEncoding($data, httpClient($imdbServer.'/title/tt'.$imdbID.'/fullcredits', $cache));
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Cast
|
||||
// Directors
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_cast.html', $resp['data']); // write page data to file
|
||||
|
||||
// Increase the PCRE backtrack limit for a potentially large regex operation
|
||||
$origBacktrackLimit = ini_get('pcre.backtrack_limit');
|
||||
$newBacktrackLimit = '10000000';
|
||||
ini_set('pcre.backtrack_limit', $newBacktrackLimit);
|
||||
|
||||
// extract json data from page
|
||||
if (preg_match('#(\<script id\="__NEXT_DATA__".*?\>)(.*?)(\</script\>)#s',$resp['data'],$matches))
|
||||
{
|
||||
#file_put_contents('./cache/nextdata.json-cast', $matches[2]); // write json data to file
|
||||
$json_data_cast = json_decode($matches[2],true);
|
||||
#file_put_contents('./cache/nextdata-decoded.json-cast', print_r($json_data_cast, true)); // write formated json data to file
|
||||
}
|
||||
//revert the PCRE limits back to their original values after regex operation,
|
||||
ini_set('pcre.backtrack_limit', $origBacktrackLimit);
|
||||
|
||||
// cast and directors
|
||||
$data['cast'] = "";
|
||||
$data['director'] = "";
|
||||
$cast_done = false;
|
||||
$directors_done = false;
|
||||
|
||||
if (isset($json_data_cast['props']['pageProps']['contentData']['categories']) &&
|
||||
is_array($json_data_cast['props']['pageProps']['contentData']['categories']))
|
||||
{
|
||||
foreach ($json_data_cast['props']['pageProps']['contentData']['categories'] as $category)
|
||||
{
|
||||
if (!isset($category['name']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
switch (strtolower($category['name']))
|
||||
{
|
||||
case "cast":
|
||||
$cast = imdbGetCast($category, $imdbID);
|
||||
$data['cast'] = $cast;
|
||||
$cast_done = true;
|
||||
break;
|
||||
case "directors":
|
||||
case "director":
|
||||
$dirs = imdbGetDirectors($category);
|
||||
$data['director'] = $dirs;
|
||||
$directors_done = true;
|
||||
break;
|
||||
default:
|
||||
// Other categories can be handled here if needed
|
||||
break;
|
||||
}
|
||||
if ($cast_done && $directors_done)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch plot
|
||||
$resp = $resp = imdbFixEncoding($data, httpClient($imdbServer.'/title/tt'.$imdbID.'/plotsummary', $cache));
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Plot
|
||||
//<li class="ipl-zebra-list__item" id="summary-ps0695557">
|
||||
// <p>A nameless first person narrator (<a href="/name/nm0001570/">Edward Norton</a>) attends support groups in attempt to subdue his emotional state and relieve his insomniac state. When he meets Marla (<a href="/name/nm0000307/">Helena Bonham Carter</a>), another fake attendee of support groups, his life seems to become a little more bearable. However when he associates himself with Tyler (<a href="/name/nm0000093/">Brad Pitt</a>) he is dragged into an underground fight club and soap making scheme. Together the two men spiral out of control and engage in competitive rivalry for love and power. When the narrator is exposed to the hidden agenda of Tyler's fight club, he must accept the awful truth that Tyler may not be who he says he is.</p>
|
||||
// <div class="author-container">
|
||||
// <em>—<a href="/search/title?plot_author=Rhiannon&view=simple&sort=alpha&ref_=ttpl_pl_0">Rhiannon</a></em>
|
||||
// </div>
|
||||
//</li>
|
||||
preg_match('/<li class="ipl-zebra-list__item" id="summary-p.\d+">\s+<p>(.+?)<\/p>/is', $resp['data'], $ary);
|
||||
if ($ary[1])
|
||||
{
|
||||
$data['plot'] = trim($ary[1]);
|
||||
$data['plot'] = preg_replace('/"/', '"', $data['plot']); //Replace HTML " with "
|
||||
|
||||
// removed linked actors like: <a href="/name/nm0001570?ref_=tt_stry_pl">Edward Norton</a>
|
||||
$data['plot'] = preg_replace('/<a href="\/name\/nm\d+.+?">/', '', $data['plot']);
|
||||
$data['plot'] = preg_replace('/<\/a>/', '', $data['plot']);
|
||||
$data['plot'] = preg_replace('/\s+/s', ' ', $data['plot']);
|
||||
}
|
||||
|
||||
$data['plot'] = html_clean_utf8($data['plot']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* At the moment - oct 2010 - most imdb-pages were changed to utf8,
|
||||
* but e.g. fullcredits are still iso-8859-1
|
||||
* so data is recoded here
|
||||
*/
|
||||
function imdbFixEncoding($data, $resp)
|
||||
{
|
||||
$result = $resp;
|
||||
$pageEncoding = $resp['encoding'];
|
||||
|
||||
if ($pageEncoding != $data['encoding'])
|
||||
{
|
||||
$result['data'] = iconv($pageEncoding, $data['encoding'], html_entity_decode_all($resp['data']));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Url of Cover Image
|
||||
*
|
||||
* @author Roland Obermayer <robelix@gmail.com>
|
||||
* @param string $data IMDB Page data
|
||||
* @param string $jsondata IMDB json Data
|
||||
* @return string Cover Image URL
|
||||
*/
|
||||
function imdbGetCoverURL($data, $jsondata = null) {
|
||||
global $imdbServer;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
if ($jsondata !== null)
|
||||
{
|
||||
$url = '';
|
||||
if (isset($jsondata["props"]["pageProps"]["aboveTheFoldData"]["primaryImage"]))
|
||||
{
|
||||
$url = $jsondata["props"]["pageProps"]["aboveTheFoldData"]["primaryImage"]["url"];
|
||||
// If you want the image to scaled to a certain size you can do this.
|
||||
// UX800 sets the width of the image to 800 with correct aspect ratio with regard to height.
|
||||
// UY800 set the height to 800 with correct aspect ratio with regard to width.
|
||||
// $url= str_replace('.jpg', 'UY800_.jpg', $url);
|
||||
}
|
||||
return $url;
|
||||
}
|
||||
|
||||
// find cover image url
|
||||
if (preg_match('/<a class="ipc-lockup-overlay ipc-focusable.*?" href="(\/title\/tt\d+\/mediaviewer\/\??rm.+?)" aria-label=".*?Poster.*?"><div class="ipc-lockup-overlay__screen"><\/div><\/a>/s', $data, $ary))
|
||||
{
|
||||
// Fetch the image page
|
||||
$resp = httpClient($imdbServer.$ary[1], $cache);
|
||||
|
||||
if ($resp['success'])
|
||||
{
|
||||
// get big cover image.
|
||||
preg_match('/<div style=".+?" class=".+?"><img src="(.+?)"/si', $resp['data'], $ary);
|
||||
// If you want the image to scaled to a certain size you can do this.
|
||||
// UX800 sets the width of the image to 800 with correct aspect ratio with regard to height.
|
||||
// UY800 set the height to 800 with correct aspect ratio with regard to width.
|
||||
// return str_replace('.jpg', 'UY800_.jpg', $ary[1]);
|
||||
return trim($ary[1]);
|
||||
}
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return '';
|
||||
}
|
||||
// src look somthing like: src="https://images-na.ssl-images-amazon.com/images/M/MV5BMTc0MDMyMzI2OF5BMl5BanBnXkFtZTcwMzM2OTk1MQ@@._V1_UX214_CR0,0,214,317_AL_.jpg"
|
||||
// The last part ._V1_UX214.....jpg seams to be an function that scales the image. Just remove that we want the full size.
|
||||
else if (preg_match('/<div.*?class="poster".*?<img.*?src="(.*?\.)_v.*?"/si', $data, $ary))
|
||||
{
|
||||
$img_url = $ary[1]."jpg";
|
||||
// Replace the https wtih http.
|
||||
$img_url = str_replace("https://images-na.ssl-images-amazon.com", "http://ecx.images-amazon.com", $img_url);
|
||||
return $img_url;
|
||||
}
|
||||
else
|
||||
{
|
||||
# no image
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit IMDB for a specific actor
|
||||
*
|
||||
* @author Michael Kollmann <acidity@online.de>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function imdbActorUrl($name, $id)
|
||||
{
|
||||
global $imdbServer;
|
||||
|
||||
$path = ($id) ? 'name/'.urlencode($id).'/' : 'Name?'.urlencode(html_entity_decode_all($name));
|
||||
|
||||
return $imdbServer.'/'.$path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor, not sure if this can be made
|
||||
* a one-step process?
|
||||
*
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @param string $name Name of the Actor
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function imdbActor($name, $actorid)
|
||||
{
|
||||
global $imdbServer;
|
||||
global $cache;
|
||||
|
||||
// search directly by id or via name?
|
||||
$resp = httpClient(imdbActorUrl($name, $actorid), $cache);
|
||||
//testing code save resp data from imdb
|
||||
//$file_path = './cache/httpclient-php_imdbActor_call_1.html';
|
||||
//file_put_contents($file_path, $resp['data']);
|
||||
|
||||
// if not direct match load best match
|
||||
if (preg_match('#<b>Popular Names</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m) ||
|
||||
preg_match('#<b>Names \(Exact Matches\)</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m) ||
|
||||
preg_match('#<b>Names \(Approx Matches\)</b>.+?<a\s+href="(.*?)">#i', $resp['data'], $m))
|
||||
{
|
||||
if (!preg_match('/http/i', $m[1]))
|
||||
{
|
||||
$m[1] = $imdbServer.$m[1];
|
||||
}
|
||||
$resp = httpClient($m[1], true);
|
||||
//testing code save resp data from imdb
|
||||
//$file_path = './cache/httpclient-php_/_imdbActor_call_2.html';
|
||||
//file_put_contents($file_path, $resp['data']);
|
||||
}
|
||||
|
||||
// now we should have loaded the best match
|
||||
|
||||
// only search in img_primary <td> - or we get far to many useless images
|
||||
preg_match('/<div class="ipc-poster.*?>(.*?)<\/a><\/div>/si', $resp['data'], $match);
|
||||
|
||||
$ary = array();
|
||||
if (preg_match('/.+?src="(.+?)".+?<a.*?href="(\/name\/nm\d+\/).+?/si', $match[1], $m))
|
||||
{
|
||||
$ary[0][0] = $m[2];
|
||||
$ary[0][1] = $m[1];
|
||||
}
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function imdbGetCast(array $category, string $imdbID)
|
||||
{
|
||||
$cast = [];
|
||||
if (isset($category['section']['items']) && is_array($category['section']['items'])) {
|
||||
$pageSize = $category['pagination']['queryVariables']['first'];
|
||||
$total_cast = $category['section']['total'];
|
||||
|
||||
if ($total_cast > $pageSize) {
|
||||
$cast = imdbCastExtra($imdbID);
|
||||
} else {
|
||||
$cast = imdbCast($category['section']['items']);
|
||||
}
|
||||
}
|
||||
return $cast;
|
||||
}
|
||||
|
||||
function imdbGetDirectors(array $category)
|
||||
{
|
||||
$directors = [];
|
||||
if (isset($category['section']['items']) && is_array($category['section']['items'])) {
|
||||
foreach ($category['section']['items'] as $item) {
|
||||
if (isset($item['rowTitle'])) {
|
||||
$directors[] = $item['rowTitle'];
|
||||
}
|
||||
}
|
||||
}
|
||||
$dirs = implode(', ', $directors);
|
||||
$dirs = substr($dirs, 0, 250);
|
||||
|
||||
return $dirs;
|
||||
}
|
||||
|
||||
function imdbCast(array $items)
|
||||
{
|
||||
global $imdbIdPrefix;
|
||||
|
||||
// Loop through each item in the items array
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// Check if the required keys exist.
|
||||
$actorid = isset($item['id']) ? $item['id'] : "";
|
||||
$actor = isset($item['rowTitle']) ? $item['rowTitle'] : "";
|
||||
// Build the $character string from characters and attributes
|
||||
if (isset($item['characters']) && is_array($item['characters']) && !empty($item['characters']))
|
||||
{
|
||||
// Join all characters if available
|
||||
$character = implode(" / ", $item['characters']);
|
||||
// Append attributes if present
|
||||
if (isset($item['attributes']) && !empty($item['attributes']))
|
||||
{
|
||||
$character .= " " . $item['attributes'];
|
||||
}
|
||||
}
|
||||
elseif (isset($item['attributes']) && !empty($item['attributes']))
|
||||
{
|
||||
// Use only attributes if characters are not set or empty
|
||||
$character = $item['attributes'];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to an empty string if neither field is available
|
||||
$character = "";
|
||||
}
|
||||
// Append episodic credit data if available
|
||||
if (isset($item['episodicCreditData']) && is_array($item['episodicCreditData']))
|
||||
{
|
||||
$episodicParts = [];
|
||||
if (isset($item['episodicCreditData']['episodesText']) && !empty($item['episodicCreditData']['episodesText'])) {
|
||||
$episodicParts[] = $item['episodicCreditData']['episodesText'];
|
||||
}
|
||||
if (isset($item['episodicCreditData']['tenureText']) && !empty($item['episodicCreditData']['tenureText'])) {
|
||||
$episodicParts[] = $item['episodicCreditData']['tenureText'];
|
||||
}
|
||||
if (!empty($episodicParts)) {
|
||||
$character .= " " . implode(", ", $episodicParts);
|
||||
}
|
||||
}
|
||||
// Append the current actor's details
|
||||
$cast .= "$actor::$character::$imdbIdPrefix$actorid\n";
|
||||
}
|
||||
|
||||
return $cast;
|
||||
}
|
||||
|
||||
function imdbCastExtra($imdbID)
|
||||
{
|
||||
global $imdbIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
$param = ['header' => ['Accept' => 'application/json',
|
||||
'User-Agent' => 'Mozilla/5.0',
|
||||
'Content-Type' => 'application/json',
|
||||
]
|
||||
];
|
||||
$after = '';
|
||||
$cast = '';
|
||||
|
||||
do
|
||||
{
|
||||
$url = 'https://caching.graphql.imdb.com/?operationName=TitleCreditSubPagePagination&variables={"after":"'.$after.'","category":"cast","const":"tt'.$imdbID.'","first":250,"locale":"en-US","originalTitleText":false,"tconst":"tt'.$imdbID.'"}&extensions={"persistedQuery":{"sha256Hash":"716fbcc1b308c56db263f69e4fd0499d4d99ce1775fb6ca75a75c63e2c86e89c","version":1}}';
|
||||
|
||||
$resp = httpClient($url, $cache, $param);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// Cast
|
||||
#testing code save resp data from imdb
|
||||
#file_put_contents('./cache/httpclient-php_imdbData_castextra.html', $resp['data']); // write page data to file
|
||||
#file_put_contents('./cache/json-castextra', $resp['data']); // write json data to file
|
||||
$json_data_castextra = json_decode( $resp['data'],true);
|
||||
#file_put_contents('./cache/jsonDecoded-castextra', print_r($json_data_castextra, true)); // write formated json data to file
|
||||
|
||||
if (isset($json_data_castextra['data']['title']['credits']) &&
|
||||
is_array($json_data_castextra['data']['title']['credits']))
|
||||
{
|
||||
$credits = $json_data_castextra['data']['title']['credits'];
|
||||
// Loop through each item in the items array
|
||||
foreach ($credits['edges'] as $edge)
|
||||
{
|
||||
// Check if the required keys exist.
|
||||
$actorId = isset($edge['node']['name']['id']) ? $edge['node']['name']['id'] : "";
|
||||
$actor = isset($edge['node']['name']['nameText']['text']) ? $edge['node']['name']['nameText']['text'] : "";
|
||||
// Build the $character string from characters and attributes
|
||||
|
||||
if (is_array($edge['node']['characters']))
|
||||
{
|
||||
$characterNames = array_map(function ($char)
|
||||
{
|
||||
return $char['name'];
|
||||
}, $edge['node']['characters']);
|
||||
$role = implode(' / ', $characterNames);
|
||||
|
||||
if ($edge['node']['attributes'])
|
||||
{
|
||||
foreach($edge['node']['attributes'] as $attr)
|
||||
{
|
||||
$role .= " (" . $attr['text'] . ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$role = $edge['node']['attributes']['text'];
|
||||
}
|
||||
if ($edge['node']['episodeCredits'] && $edge['node']['episodeCredits']['total'] > 0)
|
||||
{
|
||||
$total = $edge['node']['episodeCredits']['total'];
|
||||
$from = $edge['node']['episodeCredits']['yearRange']['year'];
|
||||
$to = $edge['node']['episodeCredits']['yearRange']['endYear'];
|
||||
|
||||
$role .= ", $total episodes, $from";
|
||||
if ($to)
|
||||
{
|
||||
$role .= "-$to";
|
||||
}
|
||||
}
|
||||
// Append the current actor's details
|
||||
$cast .= "$actor::$role::$imdbIdPrefix$actorId\n";
|
||||
}
|
||||
}
|
||||
|
||||
$after = $credits['pageInfo']['endCursor'];
|
||||
} while ($credits['pageInfo']['hasNextPage']);
|
||||
|
||||
return $cast;
|
||||
}
|
||||
698
videodb/engines/ofdb.php
Executable file
698
videodb/engines/ofdb.php
Executable file
@@ -0,0 +1,698 @@
|
||||
<?php
|
||||
/**
|
||||
* OFDB Parser
|
||||
*
|
||||
* Parses data from the OFDB
|
||||
*
|
||||
* @package Engines
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @link http://www.ofdb.de
|
||||
* @version $Id: ofdb.php,v 1.27 2013/03/16 14:29:47 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/xml.core.php';
|
||||
|
||||
$GLOBALS['ofdbServer'] = 'https://www.ofdb.de';
|
||||
$GLOBALS['ofdbGW'] = 'http://www.ofdbgw.org'; // defunct
|
||||
$GLOBALS['ofdbIdPrefix'] = 'ofdb:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function ofdbMeta()
|
||||
{
|
||||
return array(
|
||||
'name' => 'OFDB (de)'
|
||||
, 'stable' => 1
|
||||
, 'supportsEANSearch' => 1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search Url for OfDB
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function ofdbSearchUrl($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbServer;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
$url = $ofdbServer.'/view.php?page=suchergebnis&SText='.urlencode($title);
|
||||
switch($searchType)
|
||||
{
|
||||
default :
|
||||
case 'text': {
|
||||
$url = $url.'&Kat=All'; break;
|
||||
}
|
||||
case 'ean' : {
|
||||
$url = $url.'&Kat=EAN'; break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content overview URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbContentUrl($id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
return $ofdbServer.'/view.php?page=film&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content detail URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbDetailUrl($id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=film_detail&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get explicit version URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $vid The movie's version id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbVersionUrl($id, $vid)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=fassung&fid='.$id.'&vid='.$vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content description URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $sid The movie's description id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbDescriptionUrl($id, $sid)
|
||||
{
|
||||
global $ofdbServer;
|
||||
return $ofdbServer.'/view.php?page=inhalt&fid='.$id.'&sid='.$sid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the OfDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function ofdbSearch($title, $searchType = 'title')
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $ofdbServer;
|
||||
global $ofdbGW;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
$url = $ofdbGW.'/search/'.$title;
|
||||
$resp = httpClient($url, $cache);
|
||||
# dump($resp);
|
||||
|
||||
if (!$resp['success']) {
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$xml = load_xml($resp['data']);
|
||||
# dump($xml);
|
||||
|
||||
if ((int) $xml->status->rcode > 0) {
|
||||
// prevent caching bad data
|
||||
if ($cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
|
||||
if ($resp['source']) {
|
||||
// TODO make sure redirects are deleted as well
|
||||
$url = $resp['source'];
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
}
|
||||
$CLIENTERROR .= ((string) $xml->status->rcodedesc)."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
|
||||
foreach($xml->resultat->eintrag as $item)
|
||||
{
|
||||
$data = array();
|
||||
|
||||
// Id
|
||||
$data['id'] = $ofdbIdPrefix.((string) $item->id);
|
||||
|
||||
// Title
|
||||
$data['title'] = (string) $item->titel;
|
||||
$data['orgtitle'] = (string) $item->titel_orig;
|
||||
list($data['title'], $data['subtitle']) = explode(" - ", $data['title'], 2);
|
||||
|
||||
// Year
|
||||
$data['year'] = (string) $item->jahr;
|
||||
|
||||
// cover url for image lookup
|
||||
$data['coverurl'] = (string) $item->bild;
|
||||
|
||||
$result[] = $data;
|
||||
}
|
||||
# dump($data);
|
||||
|
||||
return($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given OfDB id
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param int OfDB id
|
||||
* @return array Result data
|
||||
*/
|
||||
function ofdbData($id)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
global $ofdbServer;
|
||||
global $ofdbGW;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
// Languages
|
||||
$map_laguages = array(
|
||||
'arabisch' => 'arabic',
|
||||
'bulgarisch' => 'bulgarian',
|
||||
'chinesisch' => 'chinese',
|
||||
'tschechisch' => 'czech',
|
||||
'dänisch' => 'danish',
|
||||
'holländisch' => 'dutch',
|
||||
'englisch' => 'english',
|
||||
'französisch' => 'french',
|
||||
'deutsch' => 'german',
|
||||
'griechisch' => 'greek',
|
||||
'ungarisch' => 'hungarian',
|
||||
'isländisch' => 'icelandic',
|
||||
'indisch' => 'indian',
|
||||
'israelisch' => 'israeli',
|
||||
'italienisch' => 'italian',
|
||||
'japanisch' => 'japanese',
|
||||
'koreanisch' => 'korean',
|
||||
'norwegisch' => 'norwegian',
|
||||
'polnisch' => 'polish',
|
||||
'portugisisch' => 'portuguese',
|
||||
'rumänisch' => 'romanian',
|
||||
'russisch' => 'russian',
|
||||
'serbisch' => 'serbian',
|
||||
'spanisch' => 'spanish',
|
||||
'schwedisch' => 'swedish',
|
||||
'thailändisch' => 'thai',
|
||||
'türkisch' => 'turkish',
|
||||
'vietnamesisch' => 'vietnamese',
|
||||
'kantonesisch' => 'cantonese',
|
||||
'katalanisch' => 'catalan',
|
||||
'zypriotisch' => 'cypriot',
|
||||
'zyprisch' => 'cypriot',
|
||||
'esperanto' => 'esperanto',
|
||||
'gälisch' => 'gaelic',
|
||||
'hebräisch' => 'hebrew',
|
||||
'hindi' => 'hindi',
|
||||
'jüdisch' => 'jewish',
|
||||
'lateinisch' => 'latin',
|
||||
'mandarin' => 'mandarin',
|
||||
'serbokroatisch' => 'serbo-croatian',
|
||||
'somalisch' => 'somali'
|
||||
);
|
||||
|
||||
// Genres
|
||||
$map_genres = array(
|
||||
'Amateur' => '',
|
||||
'Eastern' => '',
|
||||
'Experimentalfilm' => '',
|
||||
'Mondo' => '',
|
||||
'Kampfsport' => 'Sport',
|
||||
'Biographie' => 'Biography',
|
||||
'Katastrophen' => 'Thriller',
|
||||
'Krimi' => 'Crime',
|
||||
'Science-Fiction' => 'Sci-Fi',
|
||||
'Kinder-/Familienfilm' => 'Family',
|
||||
'Dokumentation' => 'Documentary',
|
||||
'Action' => 'Action',
|
||||
'Drama' => 'Drama',
|
||||
'Abenteuer' => 'Adventure',
|
||||
'Historienfilm' => 'History',
|
||||
'Kurzfilm' => 'Short',
|
||||
'Liebe/Romantik' => 'Romance',
|
||||
'Heimatfilm' => 'Romance',
|
||||
'Grusel' => 'Horror',
|
||||
'Horror' => 'Horror',
|
||||
'Erotik' => 'Adult',
|
||||
'Hardcore' => 'Adult',
|
||||
'Sex' => 'Adult',
|
||||
'Musikfilm' => 'Musical',
|
||||
'Animation' => 'Animation',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Trash' => 'Horror',
|
||||
'Komödie' => 'Comedy',
|
||||
'Krieg' => 'War',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Tierfilm' => 'Documentary',
|
||||
'Western' => 'Western',
|
||||
'TV-Serie' => '',
|
||||
'TV-Mini-Serie' => '',
|
||||
'Sportfilm' => 'Sport',
|
||||
'Splatter' => 'Horror',
|
||||
'Manga/Anime' => 'Animation'
|
||||
);
|
||||
|
||||
$data = array();
|
||||
$data['encoding'] = 'utf-8';
|
||||
$data['imdbID'] = $id;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
|
||||
$url = $ofdbGW.'/movie/'.$id;
|
||||
# dump($url);
|
||||
$resp = httpClient($url, $cache);
|
||||
|
||||
if (!$resp['success']) {
|
||||
$CLIENTERROR .= $resp['error']."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
$xml = load_xml($resp['data']);
|
||||
# dump($xml);
|
||||
|
||||
if ((int) $xml->status->rcode > 0) {
|
||||
// prevent caching bad data
|
||||
if ($cache) {
|
||||
$cache_file = cache_get_filename($url, CACHE_HTML);
|
||||
@unlink($cache_file);
|
||||
}
|
||||
$CLIENTERROR .= ((string) $xml->status->rcodedesc)."\n";
|
||||
return(false);
|
||||
}
|
||||
|
||||
// set root
|
||||
$item = $xml->resultat;
|
||||
|
||||
// Title
|
||||
$data['title'] = (string) $item->titel;
|
||||
$data['orgtitle'] = (string) $item->alternativ;
|
||||
list($data['title'], $data['subtitle']) = explode(" - ", $data['title'], 2);
|
||||
|
||||
// Year
|
||||
$data['year'] = (string) $item->jahr;
|
||||
|
||||
// Cover url for image lookup
|
||||
$data['coverurl'] = (string) $item->bild;
|
||||
|
||||
// Plot
|
||||
$data['plot'] = (string) $item->beschreibung;
|
||||
if (!$data['plot']) $data['plot'] = (string) $item->kurzbeschreibung;
|
||||
|
||||
// Rating
|
||||
$data['rating'] = round((float) $item->bewertung->note);
|
||||
|
||||
// Cast
|
||||
foreach ($item->besetzung->person as $cast) {
|
||||
$data['cast'] .= "\n";
|
||||
$data['cast'] .= ((string) $cast->name);
|
||||
if ((string) $cast->rolle) $data['cast'] .= '::'.((string) $cast->rolle);
|
||||
if ((string) $cast->id) $data['cast'] .= '::'.((string) $cast->id);
|
||||
}
|
||||
|
||||
// Director
|
||||
foreach ($item->regie->person as $director) {
|
||||
if ($data['director']) $data['director'] .= ', ';
|
||||
$data['director'] .= (string) $director->name;
|
||||
}
|
||||
|
||||
// Country
|
||||
foreach ($item->produktionsland as $country) {
|
||||
if ($data['country']) $data['country'] .= ', ';
|
||||
$data['country'] .= (string) $country->name;
|
||||
}
|
||||
|
||||
// Genre
|
||||
$data['genres'] = array();
|
||||
foreach ($item->genre->titel as $genre) {
|
||||
$genre = (string) $genre;
|
||||
// mapping
|
||||
if ($map_genres[$genre]) $data['genres'][] = $map_genres[$genre];
|
||||
}
|
||||
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid) {
|
||||
foreach ($item->fassungen->titel as $fassung) {
|
||||
$vid = (string) $fassung->id; // 1545;210858
|
||||
break;
|
||||
}
|
||||
if ($vid) {
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbIdPrefix.preg_replace('/;/', '-', $vid);
|
||||
}
|
||||
}
|
||||
|
||||
# dump($data);
|
||||
return($data);
|
||||
/*
|
||||
$data = array(); //result
|
||||
$ary = array(); //temp
|
||||
$ary2 = array(); //temp2
|
||||
|
||||
// Fetch Mainpage
|
||||
$resp = httpClient(ofdbContentUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// add engine ID -> important for non edit.php refetch
|
||||
$data['imdbID'] = $ofdbIdPrefix.$id;
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Titles / Year
|
||||
preg_match('/<title>(.*?)<\/title>/i', $resp['data'], $ary);
|
||||
$ary[1] = preg_replace('/^OFDb[\s-]*!!!!!!!!!!!/', '', $ary[1]);
|
||||
$ary[1] = preg_replace('/\[.*\]/', ' ', $ary[1]);
|
||||
if (preg_match('/\(([0-9]*)\)/i',$ary[1],$ary2))
|
||||
{
|
||||
$data['year'] = trim($ary2[1]);
|
||||
}
|
||||
$ary[1] = preg_replace('/\([0-9]*\)/', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
|
||||
// check if there is a comma sperated article at the end
|
||||
if (preg_match('#(.*),\s*(A|The|Der|Die|Das|Ein|Eine|Einer)\s*$#i',$ary[1],$subRes)) {
|
||||
$ary[1] = $subRes[2].' '.$subRes[1];
|
||||
}
|
||||
|
||||
list($t,$s) = explode(" - ",trim($ary[1]),2);
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
|
||||
// Original Title
|
||||
if (preg_match('/Originaltitel.*?<b>(.*?)</i', $resp['data'], $ary))
|
||||
{
|
||||
$data['orgtitle'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Country
|
||||
if (preg_match('/>Herstellungsland:.*?<b><a.*?>(.*?)<\/a>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['country'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
if (preg_match('/<br>Note:\s*([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
$data['rating'] = $ary[1];
|
||||
}
|
||||
|
||||
// Cover URL
|
||||
if (preg_match('#<img src="(http://img.ofdb.de/film/.*?\.jpg)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid)
|
||||
{
|
||||
if (preg_match_all('/view\.php\?page=fassung&fid='.$id.'&vid=([0-9]+)".*?class="Klein">(.*?)</i', $resp['data'], $ary, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary as $row)
|
||||
{
|
||||
if (trim($row[2]) == "K" || trim($row[2]) == "KV") // Check if there is a good result
|
||||
{
|
||||
$vid=$row[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$vid) // Still empty -> Take the first one
|
||||
{
|
||||
$vid=$ary[1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbIdPrefix."$id-$vid";
|
||||
|
||||
// Fetch Plot
|
||||
if (preg_match('#href="(plot/[^"]+)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$subresp = httpClient($ofdbServer.'/'.$ary[1], $cache);
|
||||
|
||||
if (!$resp['success']) $CLIENTERROR .= $subresp['error']."\n";
|
||||
$subresp['data'] = preg_replace('/[\r\n\t]/',' ', $subresp['data']);
|
||||
|
||||
if (preg_match('#</b><br><br>(.*?)</font></p>#i', $subresp['data'], $ary))
|
||||
{
|
||||
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('#<(br|p)[ /]*>#i', "\n", $ary[1]);
|
||||
$data['plot'] = trim($ary[1]);
|
||||
//$data['plot'] = "aeääääaaaä";
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Details
|
||||
$resp = httpClient(ofdbDetailUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Director
|
||||
if (preg_match('/<b><i>Regie<\/i><\/b>.*?<table.*?>(.*?)<\/table>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/class="Daten"><a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$data['director'] .= trim($row[1]).', ';
|
||||
}
|
||||
$data['director'] = preg_replace('/, $/', '', $data['director']);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if (preg_match('/<b><i>Darsteller<\/i><\/b>.*?<table.*?>(.*)<\/table>/', $resp['data'], $ary))
|
||||
{
|
||||
// dirty workaround for (.*?) failed on very long match groups issue (tested at PHP 5.2.5.5)
|
||||
// e.g.: ofdb:7749-111320 (Angel - Jäger der Finsternis)
|
||||
$ary[1] = preg_replace('#</table.*#','',$ary[1]);
|
||||
|
||||
if (preg_match_all('/class="Daten"><a(.*?)">(.*?)<\/a>.*?<\/td> <td.*?<\/td> <td[^>]*>(.*?)<\/td>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$actor = trim(strip_tags($row[2]));
|
||||
|
||||
$actorid = "";
|
||||
if (!empty($row[1]))
|
||||
{
|
||||
if (preg_match('#href="view.php\?page=person&id=([0-9]*)#i', $row[1], $idAry))
|
||||
{
|
||||
$actorid = $ofdbIdPrefix.$idAry[1];
|
||||
}
|
||||
}
|
||||
|
||||
$character = "";
|
||||
if (!empty($row[3]))
|
||||
{
|
||||
if (preg_match('#class="Normal">... ([^<]*)<#i', $row[3], $charAry))
|
||||
{
|
||||
$character = trim(strip_tags($charAry[1]));
|
||||
}
|
||||
}
|
||||
$data['cast'] .= "$actor::$character::$actorid\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (preg_match('/>Genre\(s\)\:.*?<b>(.*?)<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/<a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary2 as $row) {
|
||||
$genre = trim(html_entity_decode($row[1]));
|
||||
$genre = strip_tags($genre);
|
||||
if (!$genre) continue;
|
||||
if (isset($map_genres[$genre])) $data['genres'][] = $map_genres[$genre];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Version
|
||||
$resp = httpClient(ofdbVersionUrl($id, $vid), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// FSK
|
||||
$fsks = array(
|
||||
'FSK o.A.' => '0',
|
||||
'FSK 6' => '6',
|
||||
'FSK 12' => '12',
|
||||
'FSK 16' => '16',
|
||||
'FSK 18' => '18',
|
||||
'Keine Jugendfreigabe' => '18',
|
||||
'SPIO/JK' => '18',
|
||||
'juristisch geprüft' => '',
|
||||
'ungeprüft' => ''
|
||||
);
|
||||
if (preg_match('/>Freigabe:<.*?<b>(.*?)<\/tr>/i', $resp['data'], $ary))
|
||||
{
|
||||
$fsk = trim(html_entity_decode($ary[1]));
|
||||
$fsk = strip_tags($fsk);
|
||||
if (isset($fsks[$fsk])) $data['fsk'] = $fsks[$fsk];
|
||||
}
|
||||
|
||||
$lang_list = array();
|
||||
if (preg_match('/>Tonformat:(.*?)<\/tr>/i', $resp['data'], $ary) &&
|
||||
preg_match_all('/<a.*?>(\w+?)(\s\().*?a>/si', $ary[1], $langs, PREG_PATTERN_ORDER))
|
||||
{
|
||||
foreach($langs[1] as $language) {
|
||||
$language = trim(strtolower($language));
|
||||
$language = html_entity_decode(strip_tags($language));
|
||||
$language = preg_replace('/\s+$/','',$language);
|
||||
if (!$language) continue;
|
||||
if (isset($map_laguages[$language])) $language = $map_laguages[$language];
|
||||
else continue;
|
||||
if (!$language) continue;
|
||||
$lang_list[] = $language;
|
||||
}
|
||||
$data['language'] = trim(join(', ', array_unique($lang_list)));
|
||||
}
|
||||
|
||||
// Runtime
|
||||
if (preg_match('/>Laufzeit:<.*?<b>(.*?)\s*Min/i', $resp['data'], $ary))
|
||||
{
|
||||
$ary[1] = preg_replace('/:.*!!!!!!!/','', $ary[1]);
|
||||
$data['runtime'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// EAN-Code
|
||||
if (preg_match('/>EAN\/UPC<\/a>:.*?<b>\s*([0-9]+)\s*<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['barcode'] = $ary[1];
|
||||
}
|
||||
|
||||
return $data;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit OFDB for a specific actor
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbActorUrl($name, $id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
return ($id) ? $ofdbServer.'/view.php?page=person&id='.$id : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name Name of the actor
|
||||
* @param string $id Prefixed ofdb actor id
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function ofdbActor($name, $id)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $ofdbIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
$folderId = ($id < 1000) ? 0 : substr($id,0,strlen($id)-3);
|
||||
|
||||
$imgUrl = $ofdbServer.'/images/person/'.$folderId.'/'.$id.'.jpg';
|
||||
|
||||
$ary = array();
|
||||
$ary[0][0] = ofdbActorUrl($name, $id);
|
||||
$ary[0][1] = $imgUrl;
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function ofdbGetActorId($name)
|
||||
{
|
||||
global $ofdbServer;
|
||||
global $CLIENTERROR;
|
||||
|
||||
// try to guess the id -> first actor found with this name
|
||||
$url = $ofdbServer.'/view.php?page=liste&Name='.urlencode(html_entity_decode_all($name));
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
return (preg_match('#view.php?page=person&id=([0-9]+)#i', $resp['data'], $ary)) ? $ary[1] : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an array of all previous prefixes for the ImdbId
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @return array Associative array with ImdbId prefixes
|
||||
*/
|
||||
function ofdbImdbIdPrefixes()
|
||||
{
|
||||
global $ofdbIdPrefix;
|
||||
return array($ofdbIdPrefix);
|
||||
}
|
||||
|
||||
?>
|
||||
564
videodb/engines/ofdbscraper.php
Executable file
564
videodb/engines/ofdbscraper.php
Executable file
@@ -0,0 +1,564 @@
|
||||
<?php
|
||||
/**
|
||||
* OFDB Parser
|
||||
*
|
||||
* Parses data from the OFDB
|
||||
*
|
||||
* @package Engines
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @link http://www.ofdb.de
|
||||
* @version $Id: ofdb.php,v 1.24 2011/06/18 21:28:01 robelix Exp $
|
||||
*/
|
||||
|
||||
$GLOBALS['ofdbscraperServer'] = 'https://www.ofdb.de';
|
||||
$GLOBALS['ofdbscraperIdPrefix'] = 'ofdbscraper:';
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*
|
||||
* @todo Include image search capabilities etc in meta information
|
||||
*/
|
||||
function ofdbscraperMeta()
|
||||
{
|
||||
return array(
|
||||
'name' => 'OFDB (de) Scraper'
|
||||
, 'stable' => 1
|
||||
, 'supportsEANSearch' => 0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get search Url for OfDB
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return string The search URL (GET)
|
||||
*/
|
||||
function ofdbscraperSearchUrl($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
$url = $ofdbscraperServer.'/view.php?page=suchergebnis&SText='.urlencode($title);
|
||||
switch($searchType)
|
||||
{
|
||||
default :
|
||||
case 'text': {
|
||||
$url = $url.'&Kat=All'; break;
|
||||
}
|
||||
case 'ean' : {
|
||||
$url = $url.'&Kat=EAN'; break;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content overview URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperContentUrl($id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
return $ofdbscraperServer.'/view.php?page=film&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content detail URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperDetailUrl($id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=film_detail&fid='.$id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get explicit version URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $vid The movie's version id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperVersionUrl($id, $vid)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=fassung&fid='.$id.'&vid='.$vid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content description URL
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $id The movie's external id
|
||||
* @param string $sid The movie's description id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperDescriptionUrl($id, $sid)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
return $ofdbscraperServer.'/view.php?page=inhalt&fid='.$id.'&sid='.$sid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search a Movie
|
||||
*
|
||||
* Searches for a given title on the OfDB and returns the found links in
|
||||
* an array
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string The search string
|
||||
* @return array Associative array with id and title
|
||||
*/
|
||||
function ofdbscraperSearch($title, $searchType = 'title')
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
global $CLIENTERROR;
|
||||
global $cache;
|
||||
|
||||
// auto switch to ean Mode if title is exactly 13 digits
|
||||
if (preg_match('#^\s*[0-9]{13}\s*$#',$title)) $searchType = 'ean';
|
||||
|
||||
// search for series
|
||||
$resp = httpClient(ofdbscraperSearchUrl($title, $searchType), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
# dump($resp);
|
||||
|
||||
// add encoding
|
||||
$ary['encoding'] = $resp['encoding'];
|
||||
|
||||
if (preg_match_all('/<br>[0-9]+\.\s*<a href="film\/([0-9]+),[^"]*" onmouseover="[^"]*"[^>]*>([^<]*)<font.*?\/font> \(([\/\-0-9]+)\)<\/a>/', $resp['data'], $data, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($data as $row) {
|
||||
$info['id'] = $ofdbscraperIdPrefix.$row[1];
|
||||
$info['title'] = trim($row[2]).' ('.$row[3].')';
|
||||
$ary[] = $info;
|
||||
}
|
||||
}
|
||||
if (preg_match_all('/<br>[0-9]+\.\s*<a href="film\/([0-9]+),[^"]*" onmouseover="[^"]*"><b>([^<]*)<.*?<a href="view\.php\?page=fassung.*?fid=[0-9]+.*?vid=([0-9]+)" onmouseover="[^"]*">([^<]*)</i', $resp['data'], $data, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($data as $row) {
|
||||
$info['id'] = $ofdbscraperIdPrefix.$row[1]."-".$row[3];
|
||||
$info['title'] = trim($row[2]).' - '.$row[4];
|
||||
$ary[] = $info;
|
||||
}
|
||||
}
|
||||
// do not return an array which contains only an encoding attribute
|
||||
if (count($ary) < 2) return array();
|
||||
|
||||
return $ary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the data for a given OfDB id
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param int OfDB id
|
||||
* @return array Result data
|
||||
*/
|
||||
function ofdbscraperData($id)
|
||||
{
|
||||
global $CLIENTERROR;
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
global $cache;
|
||||
global $config;
|
||||
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
list($id, $vid) = explode("-", $id, 2);
|
||||
|
||||
$data = array(); //result
|
||||
$ary = array(); //temp
|
||||
$ary2 = array(); //temp2
|
||||
|
||||
// Fetch Mainpage
|
||||
$resp = httpClient(ofdbscraperContentUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
// add encoding
|
||||
$data['encoding'] = $resp['encoding'];
|
||||
|
||||
// add engine ID -> important for non edit.php refetch
|
||||
$data['imdbID'] = $ofdbscraperIdPrefix.$id;
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Titles / Year
|
||||
preg_match('/<title>(.*?)<\/title>/i', $resp['data'], $ary);
|
||||
$ary[1] = preg_replace('/^OFDb[\s-]*/', '', $ary[1]);
|
||||
$ary[1] = preg_replace('/\[.*\]/', ' ', $ary[1]);
|
||||
if (preg_match('/\(([0-9]*)\)/i',$ary[1],$ary2))
|
||||
{
|
||||
$data['year'] = trim($ary2[1]);
|
||||
}
|
||||
$ary[1] = preg_replace('/\([0-9]*\)/', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
|
||||
// check if there is a comma sperated article at the end
|
||||
if (preg_match('#(.*),\s*(A|The|Der|Die|Das|Ein|Eine|Einer)\s*$#i',$ary[1],$subRes)) {
|
||||
$ary[1] = $subRes[2].' '.$subRes[1];
|
||||
}
|
||||
|
||||
list($t,$s) = explode(" - ",trim($ary[1]),2);
|
||||
$data['title'] = trim($t);
|
||||
$data['subtitle'] = trim($s);
|
||||
|
||||
// Original Title
|
||||
if (preg_match('/Originaltitel.*?<b>(.*?)</i', $resp['data'], $ary))
|
||||
{
|
||||
$data['orgtitle'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Country
|
||||
if (preg_match('/>Herstellungsland:.*?<b><a.*?>(.*?)<\/a>/i', $resp['data'], $ary))
|
||||
{
|
||||
$data['country'] .= trim($ary[1]);
|
||||
}
|
||||
|
||||
// Rating
|
||||
if (preg_match('/Note: <span itemprop="ratingValue">([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
// if (preg_match('/<br>Note:\s*([0-9\.]+)/', $resp['data'], $ary)) {
|
||||
$data['rating'] = $ary[1];
|
||||
}
|
||||
|
||||
// Cover URL
|
||||
if (preg_match('#<img src="(http://img.ofdb.de/film/na.gif)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = "";
|
||||
}
|
||||
else if (preg_match('#<img src="(http://img.ofdb.de/film/.*?\.jpg)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$data['coverurl'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
// Fetch first VID if none already selected
|
||||
if (!$vid)
|
||||
{
|
||||
if (preg_match_all('/view\.php\?page=fassung&fid='.$id.'&vid=([0-9]+)".*?class="Klein">(.*?)</i', $resp['data'], $ary, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary as $row)
|
||||
{
|
||||
if (trim($row[2]) == "K" || trim($row[2]) == "KV") // Check if there is a good result
|
||||
{
|
||||
$vid=$row[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!$vid) // Still empty -> Take the first one
|
||||
{
|
||||
$vid=$ary[1][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMDB ID
|
||||
$data['imdbID'] = $ofdbscraperIdPrefix."$id-$vid";
|
||||
|
||||
// Fetch Plot
|
||||
if (preg_match('#href="(plot/[^"]+)"#i', $resp['data'], $ary))
|
||||
{
|
||||
$subresp = httpClient($ofdbscraperServer.'/'.$ary[1], $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $subresp['error']."\n";
|
||||
$subresp['data'] = preg_replace('/[\r\n\t]/',' ', $subresp['data']);
|
||||
//ofdbDbg($subresp['data'],false);
|
||||
if (preg_match('#</b><br><br>(.*?)</font></p>#i', $subresp['data'], $ary))
|
||||
{
|
||||
|
||||
$ary[1] = preg_replace('/\s{2,}/s', ' ', $ary[1]);
|
||||
$ary[1] = preg_replace('#<(br|p)[ /]*>#i', "\n", $ary[1]);
|
||||
$data['plot'] = trim($ary[1]);
|
||||
//$data['plot'] = "aeääääaaaä";
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Details
|
||||
$resp = httpClient(ofdbscraperDetailUrl($id), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// Director
|
||||
if (preg_match('/<b><i>Regie<\/i><\/b>.*?<table.*?>(.*?)<\/table>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/class="Daten"><a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$data['director'] .= trim($row[1]).', ';
|
||||
}
|
||||
$data['director'] = preg_replace('/, $/', '', $data['director']);
|
||||
}
|
||||
}
|
||||
|
||||
// Cast
|
||||
if (preg_match('/<b><i>Darsteller<\/i><\/b>.*?<table.*?>(.*)<\/table>/', $resp['data'], $ary))
|
||||
{
|
||||
// dirty workaround for (.*?) failed on very long match groups issue (tested at PHP 5.2.5.5)
|
||||
// e.g.: ofdb:7749-111320 (Angel - Jäger der Finsternis)
|
||||
$ary[1] = preg_replace('#</table.*#','',$ary[1]);
|
||||
|
||||
if (preg_match_all('/class="Daten"><a(.*?)">(.*?)<\/a>.*?<\/td> <td.*?<\/td> <td[^>]*>(.*?)<\/td>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach ($ary2 as $row)
|
||||
{
|
||||
$actor = trim(strip_tags($row[2]));
|
||||
|
||||
$actorid = "";
|
||||
if (!empty($row[1]))
|
||||
{
|
||||
if (preg_match('#href="view.php\?page=person&id=([0-9]*)#i', $row[1], $idAry))
|
||||
{
|
||||
$actorid = $ofdbscraperIdPrefix.$idAry[1];
|
||||
}
|
||||
}
|
||||
|
||||
$character = "";
|
||||
if (!empty($row[3]))
|
||||
{
|
||||
if (preg_match('#class="Normal">... ([^<]*)<#i', $row[3], $charAry))
|
||||
{
|
||||
$character = trim(strip_tags($charAry[1]));
|
||||
}
|
||||
}
|
||||
$data['cast'] .= "$actor::$character::$actorid\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Genres
|
||||
$genres = array(
|
||||
'Amateur' => '',
|
||||
'Eastern' => '',
|
||||
'Experimentalfilm' => '',
|
||||
'Mondo' => '',
|
||||
'Kampfsport' => 'Sport',
|
||||
'Biographie' => 'Biography',
|
||||
'Katastrophen' => 'Thriller',
|
||||
'Krimi' => 'Crime',
|
||||
'Science-Fiction' => 'Sci-Fi',
|
||||
'Kinder-/Familienfilm' => 'Family',
|
||||
'Dokumentation' => 'Documentary',
|
||||
'Action' => 'Action',
|
||||
'Drama' => 'Drama',
|
||||
'Abenteuer' => 'Adventure',
|
||||
'Historienfilm' => 'History',
|
||||
'Kurzfilm' => 'Short',
|
||||
'Liebe/Romantik' => 'Romance',
|
||||
'Heimatfilm' => 'Romance',
|
||||
'Grusel' => 'Horror',
|
||||
'Horror' => 'Horror',
|
||||
'Erotik' => 'Adult',
|
||||
'Hardcore' => 'Adult',
|
||||
'Sex' => 'Adult',
|
||||
'Musikfilm' => 'Musical',
|
||||
'Animation' => 'Animation',
|
||||
'Fantasy' => 'Fantasy',
|
||||
'Trash' => 'Horror',
|
||||
'Komödie' => 'Comedy',
|
||||
'Krieg' => 'War',
|
||||
'Mystery' => 'Mystery',
|
||||
'Thriller' => 'Thriller',
|
||||
'Tierfilm' => 'Documentary',
|
||||
'Western' => 'Western',
|
||||
'TV-Serie' => '',
|
||||
'TV-Mini-Serie' => '',
|
||||
'Sportfilm' => 'Sport',
|
||||
'Splatter' => 'Horror',
|
||||
'Manga/Anime' => 'Animation'
|
||||
);
|
||||
if (preg_match('/>Genre\(s\)\:.*?<b>(.*?)<\/b>/i', $resp['data'], $ary))
|
||||
{
|
||||
if (preg_match_all('/<a.*?>(.*?)<\/a>/i',$ary[1],$ary2, PREG_SET_ORDER))
|
||||
{
|
||||
foreach($ary2 as $row) {
|
||||
$genre = trim(html_entity_decode($row[1]));
|
||||
$genre = strip_tags($genre);
|
||||
if (!$genre) continue;
|
||||
if (isset($genres[$genre])) $data['genres'][] = $genres[$genre];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch Version
|
||||
$resp = httpClient(ofdbscraperVersionUrl($id, $vid), $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
// FSK
|
||||
$fsks = array(
|
||||
'FSK o.A.' => '0',
|
||||
'FSK 6' => '6',
|
||||
'FSK 12' => '12',
|
||||
'FSK 16' => '16',
|
||||
'FSK 18' => '18',
|
||||
'Keine Jugendfreigabe' => '18',
|
||||
'SPIO/JK' => '18',
|
||||
'juristisch geprüft' => '',
|
||||
'ungeprüft' => ''
|
||||
);
|
||||
if (preg_match('/>Freigabe:<.*?<b>(.*?)<\/tr>/i', $resp['data'], $ary))
|
||||
{
|
||||
$fsk = trim(html_entity_decode($ary[1]));
|
||||
$fsk = strip_tags($fsk);
|
||||
if (isset($fsks[$fsk])) $data['fsk'] = $fsks[$fsk];
|
||||
}
|
||||
|
||||
// Languages
|
||||
// Languages (as Array)
|
||||
$laguages = array(
|
||||
'arabisch' => 'arabic',
|
||||
'bulgarisch' => 'bulgarian',
|
||||
'chinesisch' => 'chinese',
|
||||
'tschechisch' => 'czech',
|
||||
'dänisch' => 'danish',
|
||||
'holändisch' => 'dutch',
|
||||
'englisch' => 'english',
|
||||
'französisch' => 'french',
|
||||
'deutsch' => 'german',
|
||||
'griechisch' => 'greek',
|
||||
'ungarisch' => 'hungarian',
|
||||
'isländisch' => 'icelandic',
|
||||
'indisch' => 'indian',
|
||||
'israelisch' => 'israeli',
|
||||
'italienisch' => 'italian',
|
||||
'japanisch' => 'japanese',
|
||||
'koreanisch' => 'korean',
|
||||
'norwegisch' => 'norwegian',
|
||||
'polnisch' => 'polish',
|
||||
'portugisisch' => 'portuguese',
|
||||
'rumänisch' => 'romanian',
|
||||
'russisch' => 'russian',
|
||||
'serbisch' => 'serbian',
|
||||
'spanisch' => 'spanish',
|
||||
'schwedisch' => 'swedish',
|
||||
'thailändisch' => 'thai',
|
||||
'türkisch' => 'turkish',
|
||||
'vietnamesisch' => 'vietnamese',
|
||||
'kantonesisch' => 'cantonese',
|
||||
'katalanisch' => 'catalan',
|
||||
'zypriotisch' => 'cypriot',
|
||||
'zyprisch' => 'cypriot',
|
||||
'esperanto' => 'esperanto',
|
||||
'gälisch' => 'gaelic',
|
||||
'hebräisch' => 'hebrew',
|
||||
'hindi' => 'hindi',
|
||||
'jüdisch' => 'jewish',
|
||||
'lateinisch' => 'latin',
|
||||
'mandarin' => 'mandarin',
|
||||
'serbokroatisch' => 'serbo-croatian',
|
||||
'somalisch' => 'somali'
|
||||
);
|
||||
$lang_list = array();
|
||||
|
||||
// Runtime
|
||||
if (preg_match('/>Laufzeit:<.*?<b>(.*?)\s*Min/i', $resp['data'], $ary))
|
||||
{
|
||||
$ary[1] = preg_replace('/:.*/','', $ary[1]);
|
||||
$data['runtime'] = trim($ary[1]);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Url to visit OFDB for a specific actor
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name The actor's name
|
||||
* @param string $id The actor's external id
|
||||
* @return string The visit URL
|
||||
*/
|
||||
function ofdbscraperActorUrl($name, $id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
global $ofdbscraperIdPrefix;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbscraperGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
return ($id!=0) ? $ofdbscraperServer.'/view.php?page=person&id='.$id : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses Actor-Details
|
||||
*
|
||||
* Find image and detail URL for actor.
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @param string $name Name of the actor
|
||||
* @param string $id Prefixed ofdb actor id
|
||||
* @return array array with Actor-URL and Thumbnail
|
||||
*/
|
||||
function ofdbscraperActor($name, $id)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
if ($id) {
|
||||
$id = preg_replace('/^'.$ofdbscraperIdPrefix.'/', '', $id);
|
||||
} else {
|
||||
$id = ofdbscraperGetActorId($name);
|
||||
}
|
||||
|
||||
// now we have for shure an id
|
||||
$folderId = ($id < 1000) ? 0 : substr($id,0,strlen($id)-3);
|
||||
|
||||
$imgUrl = $ofdbscraperServer.'/images/person/'.$folderId.'/'.$id.'.jpg';
|
||||
|
||||
$ary = array();
|
||||
$ary[0][0] = ofdbscraperActorUrl($name, $id);
|
||||
$ary[0][1] = $imgUrl;
|
||||
return $ary;
|
||||
}
|
||||
|
||||
function ofdbscraperGetActorId($name)
|
||||
{
|
||||
global $ofdbscraperServer;
|
||||
|
||||
// try to guess the id -> first actor found with this name
|
||||
$url = $ofdbscraperServer.'/view.php?page=liste&Name='.urlencode(html_entity_decode_all($name));
|
||||
$resp = httpClient($url, $cache);
|
||||
if (!$resp['success']) $CLIENTERROR .= $resp['error']."\n";
|
||||
|
||||
$resp['data'] = preg_replace('/[\r\n\t]/',' ', $resp['data']);
|
||||
|
||||
return (preg_match('#view.php?page=person&id=([0-9]+)#i', $resp['data'], $ary)) ? $ary[1] : 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get an array of all previous prefixes for the ImdbId
|
||||
*
|
||||
* @author Chinamann <chinamann@users.sourceforge.net>
|
||||
* @return array Associative array with ImdbId prefixes
|
||||
*/
|
||||
function ofdbscraperImdbIdPrefixes()
|
||||
{
|
||||
global $ofdbscraperIdPrefix;
|
||||
return array($ofdbscraperIdPrefix);
|
||||
}
|
||||
|
||||
function ofdbscraperDbg($text,$append = true)
|
||||
{
|
||||
file_append('debug.txt', $text, $append);
|
||||
}
|
||||
?>
|
||||
74
videodb/engines/youtube.php
Normal file
74
videodb/engines/youtube.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
// DEFUNCT, maybe implement new api since current code doesn't work anymore: https://developers.google.com/youtube/v3/docs/search
|
||||
|
||||
/**
|
||||
* youtube.com trailer search
|
||||
*
|
||||
* Search trailers on youtube.com
|
||||
*
|
||||
* @package Engines
|
||||
* @author Andreas Goetz <cpuidle@gmx.de>
|
||||
* @author Adam Benson <precarious_panther@bigpond.com>
|
||||
* @link http://www.youtube.com YouTube
|
||||
* @version $Id: youtube.php,v 1.9 2012/08/10 16:07:53 andig2 Exp $
|
||||
*/
|
||||
|
||||
require_once './core/functions.php';
|
||||
require_once './core/httpclient.php';
|
||||
|
||||
define('YOUTUBE_CLIENT_ID', 'ytapi-AndreasGoetz-videodb-g7dk2dh6-0');
|
||||
define('YOUTUBE_DEVELOPER_KEY', 'AI39si7znfvxGu-6OfT-PIPHxUJbAy429l63_jnWSThlJ7Hitv_gmCpJ9cE_HCnH7PDvSLgthw4wEZ5wSrw139DPLbbmLb50GQ');
|
||||
|
||||
// http://gdata.youtube.com/feeds/api/videos?client=ytapi-AndreasGoetz-videodb-g7dk2dh6-0&key=AI39si7znfvxGu-6OfT-PIPHxUJbAy429l63_jnWSThlJ7Hitv_gmCpJ9cE_HCnH7PDvSLgthw4wEZ5wSrw139DPLbbmLb50GQ&v=2&start-index=1&max-results=10&q=alien
|
||||
|
||||
/**
|
||||
* Get meta information about the engine
|
||||
*/
|
||||
function youtubeMeta()
|
||||
{
|
||||
return array('name' => 'YouTube', 'stable' => 1, 'php' => '5.0', 'capabilities' => array('trailer'));
|
||||
}
|
||||
|
||||
function youtubeHasTrailer($title)
|
||||
{
|
||||
return count(youtubeSearch($title)) > 0;
|
||||
}
|
||||
|
||||
function normalize($str)
|
||||
{
|
||||
return preg_replace('/[^a-zäöüA-ZÄÖÜ0-9\s]/', '', $str);
|
||||
}
|
||||
|
||||
function youtubeSearch($title)
|
||||
{
|
||||
$trailers = array();
|
||||
$title = normalize($title);
|
||||
$trailerquery = $title." trailer";
|
||||
|
||||
$youtubeurl = "http://gdata.youtube.com/feeds/api/videos?client=".YOUTUBE_CLIENT_ID."&key=".YOUTUBE_DEVELOPER_KEY."&v=2&".
|
||||
"q=".urlencode($trailerquery)."&start-index=1&max-results=10";
|
||||
|
||||
$resp = httpClient($youtubeurl, true);
|
||||
if (!$resp['success']) return $trailers;
|
||||
|
||||
$xml = simplexml_load_string($resp['data']);
|
||||
|
||||
// obtain namespaces
|
||||
$namespaces = $xml->getNameSpaces(true);
|
||||
|
||||
foreach ($xml->entry as $trailer)
|
||||
{
|
||||
$media = $trailer->children($namespaces['media']);
|
||||
$yt = $media->group->children($namespaces['yt']);
|
||||
$id = $yt->videoid;
|
||||
|
||||
// API filtering code removed
|
||||
$trailers[] = array('id' => (string) $id,
|
||||
'src' => (string) $trailer->content['src'],
|
||||
'title' => (string) $trailer->title);
|
||||
if (count($trailers) >= 10) break;
|
||||
}
|
||||
|
||||
return $trailers;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user