diff --git a/libs/JPinkney/README.md b/libs/JPinkney/README.md index 77e234817..8436bed51 100644 --- a/libs/JPinkney/README.md +++ b/libs/JPinkney/README.md @@ -11,7 +11,7 @@ At the current version this wrapper supports all of TVMaze's endpoints except fo Pre-reqs -------- -Before attempting to use this wrapper make sure you require 'TVMazeIncludes.php'; at the top of your php file. +- Before attempting to use this wrapper make sure you require 'TVMazeIncludes.php'; at the top of your php file. Supported Methods ----------------- @@ -42,8 +42,5 @@ getCrewCreditsByID -> Return an array of all the positions a particular actor ha Open Source Projects using this ------------------------------- nZEDb -Website Link: http://www.nzedb.com +Website Link: http://www.nzedb.com Github Link: https://github.com/nZEDb/nZEDb - -newznab-tmux -Github Link: https://github.com/DariusIII/newznab-tmux diff --git a/libs/JPinkney/TVMaze/Client.php b/libs/JPinkney/TVMaze/Client.php index 7dcde0866..4f87c8683 100644 --- a/libs/JPinkney/TVMaze/Client.php +++ b/libs/JPinkney/TVMaze/Client.php @@ -21,7 +21,7 @@ class Client { */ public function __construct($options = array()) { - $this->embed = $options['embed']; + ; } /** @@ -32,13 +32,14 @@ class Client { * * @return array */ - function search($show_name){ - $url = self::APIURL . "/search/shows?q=" . $show_name; + function search($show_name) + { + $url = self::APIURL . "/search/shows?q=" . urlencode($show_name); $shows = $this->getFile($url); $relevant_shows = array(); - foreach($shows as $series){ + foreach($shows as $series) { $TVShow = new TVShow($series['show']); array_push($relevant_shows, $TVShow); } @@ -46,20 +47,20 @@ class Client { } /** - * Takes in a show name with optional modifiers (episodes) - * Outputs array of the MOST related shows for that given name + * Takes in a show name with optional modifiers (akas) + * Outputs array of the MOST related show for that given name * * @param $show_name * * @return array */ - function singleSearch($show_name){ - - $url = self::APIURL."/singlesearch/shows?q=".$show_name.'&embed=episodes'; + function singleSearch($show_name) + { + $url = self::APIURL . "/singlesearch/shows?q=" . urlencode($show_name) . '&embed=akas'; $shows = $this->getFile($url); $episode_list = array(); - foreach($shows['_embedded']['episodes'] as $episode){ + foreach($shows['_embedded']['episodes'] as $episode) { $ep = new Episode($episode); print_r($episode); array_push($episode_list, $ep); @@ -79,7 +80,8 @@ class Client { * * @return TVShow */ - function getShowBySiteID($site, $ID){ + function getShowBySiteID($site, $ID) + { $site = strtolower($site); $url = self::APIURL . '/lookup/shows?' . $site . '=' . $ID; $show = $this->getFile($url); @@ -94,14 +96,15 @@ class Client { * * @return array */ - function getPersonByName($name){ + function getPersonByName($name) + { $name = strtolower($name); $url = self::APIURL . '/search/people?q=' . $name; $person = $this->getFile($url); $people = array(); - foreach($person as $peeps){ - array_push($people, new Actor($peeps['person'])); + foreach($person as $peeps) { + array_push($people, new Actor($peeps['person'])); } return $people; @@ -115,21 +118,21 @@ class Client { * * @return array */ - function getSchedule($country=null, $date=null){ - if($country != null && $date != null){ + function getSchedule($country=null, $date=null) { + if($country != null && $date != null) { $url = self::APIURL . '/schedule?country=' . $country .'&date='. $date; - }else if($country == null && $date != null){ + } else if ($country == null && $date != null) { $url = self::APIURL . '/schedule?date=' . $date; - }else if($country != null && $date == null){ + } else if ($country != null && $date == null) { $url = self::APIURL . '/schedule?country=' . $country; - }else{ + } else { $url = self::APIURL . '/schedule'; } $schedule = $this->getFile($url); $show_list = array(); - foreach($schedule as $episode){ + foreach($schedule as $episode) { $ep = new Episode($episode); $show = new TVShow($episode['show']); array_push($show_list, $show, $ep); @@ -146,17 +149,18 @@ class Client { * * @return array */ - function getShowByShowID($ID, $embed_cast=null){ - if($embed_cast === true){ + function getShowByShowID($ID, $embed_cast=null) + { + if($embed_cast === true) { $url = self::APIURL . '/shows/'. $ID . '?embed=cast'; - }else{ + } else { $url = self::APIURL . '/shows/' . $ID; } $show = $this->getFile($url); $cast = array(); - foreach($show['_embedded']['cast'] as $person){ + foreach($show['_embedded']['cast'] as $person) { $actor = new Actor($person['person']); $character = new Character($person['character']); array_push($cast, array($actor, $character)); @@ -174,14 +178,15 @@ class Client { * * @return array */ - function getEpisodesByShowID($ID){ + function getEpisodesByShowID($ID) + { $url = self::APIURL . '/shows/' . $ID . '/episodes'; $episodes = $this->getFile($url); $allEpisodes = array(); - foreach($episodes as $episode){ + foreach($episodes as $episode) { $ep = new Episode($episode); array_push($allEpisodes, $ep); } @@ -208,6 +213,29 @@ class Client { return $episode; } + /** + * Returns episodes for a given show ID and ISO 8601 airdate + * + * @param $ID + * @param $season + * @param $episode + * + * @return Episode|mixed + */ + function getEpisodesByAirdate($ID, $airdate) + { + $url = self::APIURL . '/shows/' . $ID . '/episodesbydate?date=' . date('Y-m-d', strtotime($airdate)); + $episodes = $this->getFile($url); + + $allEpisodes = array(); + foreach($episodes as $episode) { + $ep = new Episode($episode); + array_push($allEpisodes, $ep); + } + + return $allEpisodes; + } + /** * Takes in a show ID and outputs all of the cast members in the form (actor, character) * @@ -215,12 +243,13 @@ class Client { * * @return array */ - function getCastByShowID($ID){ + function getCastByShowID($ID) + { $url = self::APIURL . '/shows/' . $ID . '/cast'; $people = $this->getFile($url); $cast = array(); - foreach($people as $person){ + foreach($people as $person) { $actor = new Actor($person['person']); $character = new Character($person['character']); array_push($cast, array($actor, $character)); @@ -236,7 +265,8 @@ class Client { * * @return array */ - function getAllShowsByPage($page=null){ + function getAllShowsByPage($page=null) + { if($page == null){ $url = self::APIURL . '/shows'; }else{ @@ -260,7 +290,8 @@ class Client { * * @return Actor */ - function getPersonByID($ID){ + function getPersonByID($ID) + { $url = self::APIURL . '/people/' . $ID; $show = $this->getFile($url); return new Actor($show); @@ -273,12 +304,13 @@ class Client { * * @return array */ - function getCastCreditsByID($ID){ + function getCastCreditsByID($ID) + { $url = self::APIURL . '/people/' . $ID . '/castcredits?embed=show'; $castCredit = $this->getFile($url); $shows_appeared = array(); - foreach($castCredit as $series){ + foreach($castCredit as $series) { $TVShow = new TVShow($series['_embedded']['show']); array_push($shows_appeared, $TVShow); } @@ -292,12 +324,13 @@ class Client { * * @return array */ - function getCrewCreditsByID($ID){ + function getCrewCreditsByID($ID) + { $url = self::APIURL . '/people/' . $ID . '/crewcredits?embed=show'; $crewCredit = $this->getFile($url); $shows_appeared = array(); - foreach($crewCredit as $series){ + foreach($crewCredit as $series) { $position = $series['type']; $TVShow = new TVShow($series['_embedded']['show']); array_push($shows_appeared, array($position, $TVShow)); @@ -312,9 +345,17 @@ class Client { * * @return mixed */ - private function getFile($url){ - $json = file_get_contents($url); - $response = json_decode($json, TRUE); + private function getFile($url) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_HEADER, false); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + $result = curl_exec($ch); + curl_close($ch); + + $response = json_decode($result, TRUE); if ($response) { return $response; @@ -322,7 +363,6 @@ class Client { return false; } } - }; ?> \ No newline at end of file diff --git a/libs/JPinkney/TVMaze/TVShow.php b/libs/JPinkney/TVMaze/TVShow.php index 4836cb9cd..8cd04a44d 100644 --- a/libs/JPinkney/TVMaze/TVShow.php +++ b/libs/JPinkney/TVMaze/TVShow.php @@ -9,10 +9,11 @@ namespace libs\JPinkney\TVMaze; //Check back here if we can move the episode data to the episode class later + /** * Class TVShow * - * @package JPinkney\TVMaze + * @package libs\JPinkney\TVMaze */ class TVShow extends TVProduction{ @@ -81,6 +82,11 @@ class TVShow extends TVProduction{ */ public $airDay; + /** + * @var string + */ + public $country; + /** * @param $show_data */ @@ -96,9 +102,11 @@ class TVShow extends TVProduction{ $this->weight = $show_data['weight']; $this->network_array = $show_data['network']; $this->network = $show_data['network']['name']; + $this->country = $show_data['network']['country']['code']; $this->webChannel = $show_data['webChannel']; $this->externalIDs = $show_data['externals']; $this->summary = strip_tags($show_data['summary']); + $this->akas = (isset($show_data['_embedded']['akas']) ? $show_data['_embedded']['akas'] : null); $current_date = date("Y-m-d"); foreach($show_data['_embedded']['episodes'] as $episode){ @@ -120,7 +128,8 @@ class TVShow extends TVProduction{ /** * @return bool */ - function isEmpty(){ + function isEmpty() + { return($this->id == null || $this->id == 0 && $this->url == null && $this->name == null); } diff --git a/newznab/Releases.php b/newznab/Releases.php index ce175d521..cc2a759dd 100755 --- a/newznab/Releases.php +++ b/newznab/Releases.php @@ -173,7 +173,7 @@ class Releases WHERE r.nzbstatus = %d AND r.passwordstatus %s %s %s %s %s', - ($groupName != '' ? 'INNER JOIN groups g ON g.id = r.groupid' : ''), + ($groupName != '' ? 'LEFT JOIN groups g ON g.id = r.groupid' : ''), NZB::NZB_ADDED, $this->showPasswords, ($groupName != '' ? sprintf(' AND g.name = %s', $this->pdo->escapeString($groupName)) : ''), @@ -214,7 +214,7 @@ class Releases ( SELECT r.*, g.name AS group_name FROM releases r - INNER JOIN groups g ON g.id = r.groupid + LEFT JOIN groups g ON g.id = r.groupid WHERE r.nzbstatus = %d AND r.passwordstatus %s %s %s %s %s @@ -1209,7 +1209,7 @@ class Releases CONCAT(cp.title, ' > ', c.title) AS category_name, CONCAT(cp.id, ',', c.id) AS category_ids, g.name AS group_name, - v.title AS showtitle, v.tvdb, v.trakt, v.tvrage, v.source, + v.title AS showtitle, v.tvdb, v.trakt, v.tvrage, v.tvmaze, v.source, tvi.summary, tvi.image, tve.title, tve.firstaired, tve.se_complete FROM releases r @@ -1570,7 +1570,7 @@ class Releases return $this->pdo->query( "SELECT r.videos_id, r.guid, r.name, r.searchname, r.size, r.completion, r.postdate, r.categoryid, r.comments, r.grabs, - v.id AS tvid, v.title AS tvtitle, v.tvdb, v.tvrage, + v.id AS tvid, v.title AS tvtitle, v.tvdb, v.trakt, v.tvrage, v.tvmaze, v.imdb, v.tmdb, tvi.image FROM releases r INNER JOIN videos v ON r.videos_id = v.id diff --git a/newznab/processing/PostProcess.php b/newznab/processing/PostProcess.php index 5e75de1ed..1758f7e92 100755 --- a/newznab/processing/PostProcess.php +++ b/newznab/processing/PostProcess.php @@ -14,6 +14,7 @@ use newznab\Nfo; use newznab\Sharing; //use newznab\processing\tv\TvRage; use newznab\processing\tv\TVDB; +use newznab\processing\tv\TVMaze; use newznab\XXX; use newznab\ReleaseFiles; use newznab\db\Settings; @@ -260,6 +261,7 @@ class PostProcess if ($processTV > 0) { (new TVDB(['Echo' => $this->echooutput, 'Settings' => $this->pdo]))->processTVDB($groupID, $guidChar, $processTV); //(new TvRage(['Echo' => $this->echooutput, 'Settings' => $this->pdo]))->processTvRage($groupID, $guidChar, $processTV); + (new TVMaze(['Echo' => $this->echooutput, 'Settings' => $this->pdo]))->processTVMaze($groupID, $guidChar, $processTV); } } diff --git a/newznab/processing/tv/TV.php b/newznab/processing/tv/TV.php index 36062bf83..ae0ce192f 100644 --- a/newznab/processing/tv/TV.php +++ b/newznab/processing/tv/TV.php @@ -38,7 +38,12 @@ abstract class TV extends Videos /** * @var int */ - public $rageqty; + public $tvqty; + + /** + * @string Path to Save Images + */ + public $imgSavePath; /** * @param array $options Class instances / Echo to CLI. @@ -55,6 +60,7 @@ abstract class TV extends Videos $this->echooutput = ($options['Echo'] && NN_ECHOCLI); $this->catWhere = 'categoryid BETWEEN 5000 AND 5999 AND categoryid NOT IN (5070)'; $this->tvqty = ($this->pdo->getSetting('maxrageprocessed') != '') ? $this->pdo->getSetting('maxrageprocessed') : 75; + $this->imgSavePath = NN_COVERS . 'tvshows' . DS; } /** @@ -191,7 +197,7 @@ abstract class TV extends Videos */ public function add($showArr = array()) { - if ($showArr['country'] !== '') { + if ($showArr['country'] !== '' && strlen($showArr['country']) > 2) { $showArr['country'] = $this->countryCode($showArr['country']); } @@ -534,8 +540,7 @@ abstract class TV extends Videos sprintf(' SELECT id FROM countries - WHERE country = %s - OR iso3 = %1\$s', + WHERE country = %1\$s', $this->pdo->escapeString($country) ) ); @@ -859,4 +864,42 @@ abstract class TV extends Videos } return $date; } + + /** + * Checks API response returns have all REQUIRED attributes set + * Returns true or false + * + * @param array $array + * @param int $type + * + * @return bool + */ + public function checkRequired($array = array(), $type) + { + $required = ['failedToMatchType']; + + switch ($type) { + case 'tvdbS': + $required = ['id', 'name', 'overview', 'firstAired']; + break; + case 'tvdbE': + $required = ['name', 'season', 'number', 'firstAired', 'overview']; + break; + case 'tvmazeS': + $required = ['id', 'name', 'summary', 'premiered', 'country']; + break; + case 'tvmazeE': + $required = ['name', 'season', 'number', 'airdate', 'summary']; + break; + } + + if (is_array($required)) { + foreach ($required as $req) { + if (!isset($array->$req)) { + return false; + } + } + } + return true; + } } diff --git a/newznab/processing/tv/TVDB.php b/newznab/processing/tv/TVDB.php index 02d658a05..3a86666db 100644 --- a/newznab/processing/tv/TVDB.php +++ b/newznab/processing/tv/TVDB.php @@ -28,11 +28,6 @@ class TVDB extends TV */ public $fanartUrl; - /** - * @string Path to Save Images - */ - public $imgSavePath; - /** * @string The Timestamp of the TVDB Server */ @@ -57,7 +52,6 @@ class TVDB extends TV $this->client = new Client(self::TVDB_URL, self::TVDB_API_KEY); $this->posterUrl = self::TVDB_URL . DS . 'banners/_cache/posters/%s-1.jpg'; $this->fanartUrl = self::TVDB_URL . DS . 'banners/_cache/fanart/original/%s-1.jpg'; - $this->imgSavePath = NN_COVERS . 'tvshows' . DS; $this->serverTime = $this->client->getServerTime(); $this->timeZone = new \DateTimeZone('UTC'); @@ -73,7 +67,7 @@ class TVDB extends TV * @param $processTV * @param bool|false $local */ - public function processTVDB ($groupID, $guidChar, $processTV, $local = false) + public function processTVDB($groupID, $guidChar, $processTV, $local = false) { $res = $this->getTvReleases($groupID, $guidChar, $processTV, parent::PROCESS_TVDB); @@ -110,16 +104,16 @@ class TVDB extends TV // If it doesnt exist locally and lookups are allowed lets try to get it. if ($this->echooutput) { - echo $this->pdo->log->primaryOver("Video ID for ") . - $this->pdo->log->headerOver($release['cleanname']) . - $this->pdo->log->primary(" not found in local db, checking web."); + echo $this->pdo->log->primaryOver("Video ID for ") . + $this->pdo->log->headerOver($release['cleanname']) . + $this->pdo->log->primary(" not found in local db, checking web."); } // Get the show from TVDB $tvdbShow = $this->getShowInfo((string)$release['cleanname']); if (is_array($tvdbShow)) { - $tvdbShow['country'] = (isset($release['country']) && strlen($release['country']) == 2 + $tvdbShow['country'] = (isset($release['country']) && $release['country'] !== 2 ? (string)$release['country'] : '' ); @@ -127,9 +121,9 @@ class TVDB extends TV $tvdbid = (int)$tvdbShow['tvdbid']; } } else if ($this->echooutput) { - echo $this->pdo->log->primaryOver("Video ID for ") . - $this->pdo->log->headerOver($release['cleanname']) . - $this->pdo->log->primary(" found in local db, attempting episode match."); + echo $this->pdo->log->primaryOver("Video ID for ") . + $this->pdo->log->headerOver($release['cleanname']) . + $this->pdo->log->primary(" found in local db, attempting episode match."); } if (is_numeric($videoId) && $videoId > 0 && is_numeric($tvdbid) && $tvdbid > 0) { @@ -210,13 +204,14 @@ class TVDB extends TV $highestMatch = 0; try { $response = (array)$this->client->getSeries($cleanName, 'en'); - } catch (\Exception $error) { } + } catch (\Exception $error) { + } sleep(1); if (is_array($response)) { foreach ($response as $show) { - if ($this->checkRequired($show, 1)) { + if ($this->checkRequired($show, 'tvdbS')) { // Check for exact title match first and then terminate if found if ($show->name === $cleanName) { $highest = $show; @@ -248,6 +243,7 @@ class TVDB extends TV $return = $this->formatShowArr($highest); } } + return $return; } @@ -255,7 +251,7 @@ class TVDB extends TV * Retrieves the poster art for the processed show * * @param int $videoId -- the local Video ID - * @param int $showId -- the TVDB ID + * @param int $showId -- the TVDB ID * * @return null */ @@ -280,11 +276,11 @@ class TVDB extends TV * Gets the specific episode info for the parsed release after match * Returns a formatted array of episode data or false if no match * - * @param integer $tvdbid - * @param integer $season - * @param integer $episode - * @param string $airdate - * @param integer $videoId + * @param integer $tvdbid + * @param integer $season + * @param integer $episode + * @param string $airdate + * @param integer $videoId * * @return array|bool */ @@ -312,16 +308,17 @@ class TVDB extends TV sleep(1); if (is_object($response)) { - if ($this->checkRequired($response, 2)) { + if ($this->checkRequired($response, 'tvdbE')) { $return = $this->formatEpisodeArr($response); } } else if (is_array($response) && isset($response['episodes']) && $videoId > 0) { - foreach($response['episodes'] as $singleEpisode) { - if ($this->checkRequired($singleEpisode, 2)) { + foreach ($response['episodes'] as $singleEpisode) { + if ($this->checkRequired($singleEpisode, 'tvdbE')) { $this->addEpisode($videoId, $this->formatEpisodeArr($singleEpisode)); } } } + return $return; } @@ -338,7 +335,7 @@ class TVDB extends TV $show->firstAired->setTimezone($this->timeZone); preg_match('/tt(?P\d{6,7})$/i', $show->imdbId, $imdb); - return [ + return [ 'tvdbid' => (int)$show->id, 'column' => 'tvdb', 'siteid' => (int)$show->id, @@ -348,10 +345,10 @@ class TVDB extends TV 'publisher' => (string)$show->network, 'source' => (int)parent::SOURCE_TVDB, 'imdbid' => (int)(isset($imdb['imdbid']) ? $imdb['imdbid'] : 0), - 'traktid' => 0, - 'tvrageid' => 0, - 'tvmazeid' => 0, - 'tmdbid' => 0 + 'traktid' => 0, + 'tvrageid' => 0, + 'tvmazeid' => 0, + 'tmdbid' => 0 ]; } @@ -376,36 +373,4 @@ class TVDB extends TV 'summary' => (string)$episode->overview ]; } - - /** - * Checks API response returns have all REQUIRED attributes set - * Returns true or false - * - * @param array $array - * @param int $type - * - * @return bool - */ - private function checkRequired($array = array(), $type) - { - $required = false; - - switch ($type) { - case 1: - $required = ['id', 'name', 'overview', 'firstAired']; - break; - case 2: - $required = ['name', 'season', 'number', 'firstAired', 'overview']; - break; - } - - if (is_array($required)) { - foreach ($required as $req) { - if (!isset($array->$req)) { - return false; - } - } - } - return true; - } } diff --git a/newznab/processing/tv/TVMaze.php b/newznab/processing/tv/TVMaze.php index 94e188d8e..323dbe58f 100644 --- a/newznab/processing/tv/TVMaze.php +++ b/newznab/processing/tv/TVMaze.php @@ -1,6 +1,8 @@ getTvReleases($groupID, $guidChar, $processTV, parent::PROCESS_TVMAZE); + + $tvcount = $res->rowCount(); + + if ($this->echooutput && $tvcount > 1) { + echo $this->pdo->log->header("Processing TVMaze lookup for " . number_format($tvcount) . " release(s)."); + } + + if ($res instanceof \Traversable) { + foreach ($res as $row) { + + $tvmazeid = false; + $this->posterUrl = ''; + + // Clean the show name for better match probability + $release = $this->parseNameEpSeason($row['searchname']); + if (is_array($release) && $release['name'] != '') { + + // Find the Video ID if it already exists by checking the title. + $videoId = $this->getByTitle($release['cleanname']); + + if ($videoId !== false) { + $tvmazeid = $this->getSiteByID('tvmaze', $videoId); + } + + // Force local lookup only + if ($local == true) { + $lookupSetting = false; + } else { + $lookupSetting = true; + } + + if ($tvmazeid === false && $lookupSetting) { + + // If it doesnt exist locally and lookups are allowed lets try to get it. + if ($this->echooutput) { + echo $this->pdo->log->primaryOver("Video ID for ") . + $this->pdo->log->headerOver($release['cleanname']) . + $this->pdo->log->primary(" not found in local db, checking web."); + } + + // Get the show from TVDB + $tvmazeShow = $this->getShowInfo((string)$release['cleanname']); + + if (is_array($tvmazeShow)) { + $videoId = $this->add($tvmazeShow); + $tvmazeid = (int)$tvmazeShow['tvmazeid']; + } + } else if ($this->echooutput) { + echo $this->pdo->log->primaryOver("Video ID for ") . + $this->pdo->log->headerOver($release['cleanname']) . + $this->pdo->log->primary(" found in local db, attempting episode match."); + } + + if (is_numeric($videoId) && $videoId > 0 && is_numeric($tvmazeid) && $tvmazeid > 0) { + // Now that we have valid video and tvmaze ids, try to get the poster + $this->getPoster($videoId, $tvmazeid); + + $seasonNo = preg_replace('/^S0*/i', '', $release['season']); + $episodeNo = preg_replace('/^E0*/i', '', $release['episode']); + + if ($episodeNo === 'all') { + // Set the video ID and leave episode 0 + $this->setVideoIdFound($videoId, $row['id'], 0); + echo $this->pdo->log->primary("Found TVDB Match for Full Season!"); + continue; + } + + // Download all episodes if new show to reduce API/bandwidth usage + if ($this->countEpsByVideoID($videoId) === false) { + $this->getEpisodeInfo($tvmazeid, -1, -1, '', $videoId); + } + + // Check if we have the episode for this video ID + $episode = $this->getBySeasonEp($videoId, $seasonNo, $episodeNo, $release['airdate']); + + if ($episode === false && $lookupSetting) { + // Send the request for the episode to TVDB + $tvmazeEpisode = $this->getEpisodeInfo( + $tvmazeid, + $seasonNo, + $episodeNo, + $release['airdate'] + ); + + if ($tvmazeEpisode) { + $episode = $this->addEpisode($videoId, $tvmazeEpisode); + } + } + + if ($episode !== false && is_numeric($episode) && $episode > 0) { + // Mark the releases video and episode IDs + $this->setVideoIdFound($videoId, $row['id'], $episode); + if ($this->echooutput) { + echo $this->pdo->log->primary("Found TVMaze Match!"); + } + continue; + } + } + } //Processing failed, set the episode ID to the next processing group + $this->setVideoNotFound(parent::PROCESS_IMDB, $row['id']); + } + } + } + /** + * Calls the API to perform initial show name match to TVDB title + * Returns a formatted array of show data or false if no match + * + * @param $cleanName + * + * @return array|bool + */ + protected function getShowInfo($cleanName) + { + $return = $response = false; + + try { + //Try for the best match with AKAs embedded + $response = $this->client->singleSearch($cleanName); + } catch (\Exception $error) { + } + + sleep(1); + + if (is_array($response)) { + $return = $this->processResponse($response, $cleanName); + } + if ($return === false) { + try { + //Try for the best match via full search (no AKAs can be returned) + $response = $this->client->search($cleanName); + } catch (\Exception $error) { + } + if (is_array($response)) { + foreach ($response as $show) { + $return = $this->processResponse($show, $cleanName); + } + } + } + return $return; } /** - * Retrieve poster image for TV episode from site using its API. + * @param $show + * @param $cleanName * - * @param integer $videoId ID from videos table. - * @param integer $siteId ID that this site uses for the programme. + * @return array|bool + */ + private function processResponse ($show, $cleanName) + { + $return = false; + + if ($this->checkRequired($show, 'tvmazeS')) { + // Check for exact title match first and then terminate if found + if ($show->name === $cleanName) { + $return = $this->formatShowArr($show); + } else { + $return = $this->matchShowInfo($show, $cleanName); + } + } + return $return; + } + + private function matchShowInfo($show, $cleanName) + { + $return = false; + $highestMatch = 0; + + // Check each show title for similarity and then find the highest similar value + $matchPercent = $this->checkMatch($show->name, $cleanName, self::MATCH_PROBABILITY); + + // If new match has a higher percentage, set as new matched title + if ($matchPercent > $highestMatch) { + $highestMatch = $matchPercent; + $highest = $show; + } + + // Check for show aliases and try match those too + if (is_array($show->akas) && !empty($show->akas)) { + foreach ($show->akas as $key => $name) { + $matchPercent = $this->checkMatch($name, $cleanName, $matchPercent); + if ($matchPercent > $highestMatch) { + $highestMatch = $matchPercent; + $highest = $show; + } + } + } + if (isset($highest)) { + $return = $this->formatShowArr($highest); + } + return $return; + } + + /** + * Retrieves the poster art for the processed show + * + * @param int $videoId -- the local Video ID + * @param int $showId -- the TVDB ID * * @return null */ - public function getPoster($videoId, $siteId) + protected function getPoster($videoId, $showId = 0) { - return false; + $ri = new ReleaseImage($this->pdo); + + // Try to get the Poster + $hascover = $ri->saveImage($videoId, sprintf($this->posterUrl), $this->imgSavePath, '', ''); + + // Mark it retrieved if we saved an image + if ($hascover == 1) { + $this->setCoverFound($videoId); + } } /** - * Retrieve info of TV programme from site using it's API. + * Gets the specific episode info for the parsed release after match + * Returns a formatted array of episode data or false if no match * - * @param string $name Title of programme to look up. Usually a cleaned up version from releases table. + * @param integer $tvmazeid + * @param integer $season + * @param integer $episode + * @param string $airdate + * @param integer $videoId * - * @return array|false False on failure, an array of information fields otherwise. + * @return array|bool */ - public function getShowInfo($name) + protected function getEpisodeInfo($tvmazeid, $season, $episode, $airdate = '', $videoId = 0) { - return false; + $return = $response = false; + + if ($airdate !== '') { + try { + $response = $this->client->getEpisodesByAirdate($tvmazeid, $airdate); + } catch (\Exception $error) { + } + } else if ($videoId > 0) { + try { + $response = $this->client->getEpisodesByShowID($tvmazeid); + } catch (\Exception $error) { + } + } else { + try { + $response = $this->client->getEpisodeByNumber($tvmazeid, $season, $episode); + } catch (\Exception $error) { + } + } + + sleep(1); + + //Handle Single Episode Lookups + if (is_object($response)) { + if ($this->checkRequired($response, 'tvmazeE')) { + $return = $this->formatEpisodeArr($response); + } + } else if (is_array($response)) { + //Handle new show/all episodes + if ($videoId > 0) { + foreach ($response as $singleEpisode) { + if ($this->checkRequired($singleEpisode, 'tvmazeE')) { + $this->addEpisode($videoId, $this->formatEpisodeArr($singleEpisode)); + } + } + //Handle airdate lookups -- return first response + } else { + if ($this->checkRequired($response[0], 'tvmazeE')) { + $return = $this->formatEpisodeArr($response[0]); + } + } + } + return $return; } -} + + /** + * Assigns API show response values to a formatted array for insertion + * Returns the formatted array + * + * @param $show + * + * @return array + */ + private function formatShowArr($show) + { + $this->posterUrl = (string)(isset($show->mediumImage) ? $show->mediumImage : ''); + + return [ + 'tvmazeid' => (int)$show->id, + 'column' => 'tvmaze', + 'siteid' => (int)$show->id, + 'title' => (string)$show->name, + 'summary' => (string)$show->summary, + 'started' => (string)$show->premiered, + 'publisher' => (string)$show->network, + 'country' => (string)$show->country, + 'source' => (int)parent::SOURCE_TVMAZE, + 'imdbid' => 0, + 'tvdbid' => (int)(isset($show->externalIDs['thetvdb']) ? $show->externalIDs['thetvdb'] : 0), + 'traktid' => 0, + 'tvrageid' => (int)(isset($show->externalIDs['tvrage']) ? $show->externalIDs['tvrage'] : 0), + 'tmdbid' => 0 + ]; + } + + /** + * Assigns API episode response values to a formatted array for insertion + * Returns the formatted array + * + * @param $episode + * + * @return array + */ + private function formatEpisodeArr($episode) + { + return [ + 'title' => (string)$episode->name, + 'series' => (int)$episode->season, + 'episode' => (int)$episode->number, + 'se_complete' => (string)'S' . sprintf('%02d', $episode->season) . 'E' . sprintf('%02d', $episode->number), + 'firstaired' => (string)$episode->airdate, + 'summary' => (string)$episode->summary + ]; + } +} \ No newline at end of file diff --git a/www/pages/details.php b/www/pages/details.php index b396d96ab..3ae38c52d 100644 --- a/www/pages/details.php +++ b/www/pages/details.php @@ -45,25 +45,9 @@ if (isset($_GET["id"])) $page->userdata['categoryexclusions']); $failed = $df->getFailedCount($data['guid']); - $criteria = ''; - if ($data['videos_id'] != 0) { + $$showInfo = ''; + if ($data['videos_id'] > 0) { $showInfo = (new Videos(['Settings' => $page->settings]))->getByVideoID($data['videos_id']); - if (count($showInfo) > 0) { - $criteria = ['title' => '', 'summary' => '', 'countries_id' => '', 'image' => '', 'id' => '']; - $done = 1; - $needed = count($criteria); - foreach ($showInfo as $info) { - foreach($criteria as $key => $value) { - if (empty($value) && !empty($info[$key])) { - $criteria[$key] = $info[$key]; - $done++; - } - } - if ($done == $needed) { - break; - } - } - } } $episodeArray = ''; @@ -164,7 +148,7 @@ if (isset($_GET["id"])) $page->smarty->assign('reAudio',$reAudio); $page->smarty->assign('reSubs',$reSubs); $page->smarty->assign('nfo',$nfo); - $page->smarty->assign('show',$criteria); + $page->smarty->assign('show',$showInfo); $page->smarty->assign('movie',$mov); $page->smarty->assign('xxx', $xxx); $page->smarty->assign('episode',$episodeArray); diff --git a/www/themes/omicron/templates/frontend/viewnzb.tpl b/www/themes/omicron/templates/frontend/viewnzb.tpl index fe03dad75..8e8009e95 100644 --- a/www/themes/omicron/templates/frontend/viewnzb.tpl +++ b/www/themes/omicron/templates/frontend/viewnzb.tpl @@ -51,14 +51,22 @@ class="label label-success">Add to My Shows View all episodes - {if $release.source = 1} - {if $release.tvdb > 0}TheTVDB{/if} - {elseif $release.source = 3} + {if show.source == 1} + title="View at TheTVDB">TheTVDB + {elseif $show.source == 2} + + title="View at TraktTv">Trakt + {elseif $show.source == 3} + TV Rage + {elseif $show.source == 4} + TVMaze {/if} {/if} {if $con && $con.url != ""} -

TV Series > List

+

Series > List