mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-09-01 18:58:56 +00:00
519 lines
13 KiB
PHP
519 lines
13 KiB
PHP
<?php
|
|
|
|
use newznab\Capabilities;
|
|
use newznab\Category;
|
|
use newznab\Releases;
|
|
use newznab\db\Settings;
|
|
use newznab\utility\Utility;
|
|
|
|
// API functions.
|
|
$function = 's';
|
|
if (isset($_GET['t'])) {
|
|
switch ($_GET['t']) {
|
|
case 'd':
|
|
case 'details':
|
|
$function = 'd';
|
|
break;
|
|
case 'g':
|
|
case 'get':
|
|
$function = 'g';
|
|
break;
|
|
case 's':
|
|
case 'search':
|
|
$function = 's';
|
|
break;
|
|
case 'c':
|
|
case 'caps':
|
|
$function = 'c';
|
|
break;
|
|
case 'tv':
|
|
case 'tvsearch':
|
|
$function = 'tv';
|
|
break;
|
|
case 'm':
|
|
case 'movie':
|
|
$function = 'm';
|
|
break;
|
|
case 'r':
|
|
case 'register':
|
|
$function = 'r';
|
|
break;
|
|
default:
|
|
showApiError(202, 'No such function (' . $_GET['t'] . ')');
|
|
}
|
|
} else {
|
|
showApiError(200, 'Missing parameter (t)');
|
|
}
|
|
|
|
$uid = $apiKey = '';
|
|
$catExclusions = [];
|
|
$maxRequests = 0;
|
|
// Page is accessible only by the apikey, or logged in users.
|
|
if ($page->users->isLoggedIn()) {
|
|
$uid = $page->userdata['id'];
|
|
$apiKey = $page->userdata['rsstoken'];
|
|
$catExclusions = $page->userdata['categoryexclusions'];
|
|
$maxRequests = $page->userdata['apirequests'];
|
|
} else {
|
|
if ($function != 'c' && $function != 'r') {
|
|
if (!isset($_GET['apikey'])) {
|
|
showApiError(200, 'Missing parameter (apikey)');
|
|
} else {
|
|
$res = $page->users->getByRssToken($_GET['apikey']);
|
|
$apiKey = $_GET['apikey'];
|
|
|
|
if (!$res) {
|
|
showApiError(100, 'Incorrect user credentials (wrong API key)');
|
|
}
|
|
|
|
$uid = $res['id'];
|
|
$catExclusions = $page->users->getCategoryExclusion($uid);
|
|
$maxRequests = $res['apirequests'];
|
|
}
|
|
}
|
|
}
|
|
|
|
$page->smarty->assign('uid', $uid);
|
|
$page->smarty->assign('rsstoken', $apiKey);
|
|
|
|
// Record user access to the api, if its been called by a user (i.e. capabilities request do not require a user to be logged in or key provided).
|
|
if ($uid != '') {
|
|
$page->users->updateApiAccessed($uid);
|
|
$apiRequests = $page->users->getApiRequests($uid);
|
|
if ($apiRequests > $maxRequests) {
|
|
showApiError(500, 'Request limit reached (' . $apiRequests . '/' . $maxRequests . ')');
|
|
}
|
|
}
|
|
|
|
$releases = new Releases(['Settings' => $page->settings]);
|
|
|
|
$page->smarty->assign('extended', (isset($_GET['extended']) && $_GET['extended'] == 1 ? '1' : '0'));
|
|
$page->smarty->assign('del', (isset($_GET['del']) && $_GET['del'] == 1 ? '1' : '0'));
|
|
|
|
// Output is either json or xml.
|
|
$outputXML = (isset($_GET['o']) && $_GET['o'] == 'json' ? false : true);
|
|
|
|
switch ($function) {
|
|
// Search releases.
|
|
case 's':
|
|
verifyEmptyParameter('q');
|
|
$maxAge = maxAge();
|
|
$page->users->addApiRequest($uid, $_SERVER['REQUEST_URI']);
|
|
$categoryID = categoryID();
|
|
$limit = limit();
|
|
$offset = offset();
|
|
|
|
if (isset($_GET['q'])) {
|
|
$relData = $releases->search(
|
|
$_GET['q'], -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, $offset, $limit, '', $maxAge, $catExclusions,
|
|
"basic", $categoryID
|
|
);
|
|
} else {
|
|
$totalRows = $releases->getBrowseCount($categoryID, $maxAge, $catExclusions);
|
|
$relData = $releases->getBrowseRange($categoryID, $offset, $limit, '', $maxAge, $catExclusions);
|
|
}
|
|
|
|
printOutput($relData, $outputXML, $page, $offset);
|
|
break;
|
|
|
|
// Search tv releases.
|
|
case 'tv':
|
|
verifyEmptyParameter('q');
|
|
verifyEmptyParameter('vid');
|
|
verifyEmptyParameter('tvdbid');
|
|
verifyEmptyParameter('traktid');
|
|
verifyEmptyParameter('rid');
|
|
verifyEmptyParameter('tvmazeid');
|
|
verifyEmptyParameter('imdbid');
|
|
verifyEmptyParameter('tmdbid');
|
|
verifyEmptyParameter('season');
|
|
verifyEmptyParameter('ep');
|
|
$maxAge = maxAge();
|
|
$page->users->addApiRequest($uid, $_SERVER['REQUEST_URI']);
|
|
$offset = offset();
|
|
|
|
$siteIdArr = [
|
|
'id' => (isset($_GET['vid']) ? $_GET['vid'] : '0'),
|
|
'tvdb' => (isset($_GET['tvdbid']) ? $_GET['tvdbid'] : '0'),
|
|
'trakt' => (isset($_GET['traktid']) ? $_GET['traktid'] : '0'),
|
|
'tvrage' => (isset($_GET['rid']) ? $_GET['rid'] : '0'),
|
|
'tvmaze' => (isset($_GET['tvmazeid']) ? $_GET['tvmazeid'] : '0'),
|
|
'imdb' => (isset($_GET['imdbid']) ? $_GET['imdbid'] : '0'),
|
|
'tmdb' => (isset($_GET['tmdbid']) ? $_GET['tmdbid'] : '0')
|
|
];
|
|
|
|
if (isset($_GET['season']) && isset($_GET['ep'])) {
|
|
if (preg_match('#\d{4}#i', $_GET['season'], $year) && stripos($_GET['ep'], '/') !== false) {
|
|
$airdate = $year[0] . '/' . $_GET['ep'];
|
|
} else {
|
|
$series = $_GET['season'];
|
|
$episode = $_GET['ep'];
|
|
}
|
|
}
|
|
|
|
$relData = $releases->searchShows(
|
|
$siteIdArr,
|
|
(isset($series) ? $series : ''),
|
|
(isset($episode) ? $episode : ''),
|
|
(isset($airdate) ? $airdate : ''),
|
|
$offset,
|
|
limit(),
|
|
(isset($_GET['q']) ? $_GET['q'] : ''),
|
|
categoryID(),
|
|
$maxAge
|
|
);
|
|
|
|
addLanguage($relData, $page->settings);
|
|
printOutput($relData, $outputXML, $page, $offset);
|
|
break;
|
|
|
|
// Search movie releases.
|
|
case 'm':
|
|
verifyEmptyParameter('q');
|
|
verifyEmptyParameter('imdbid');
|
|
$maxAge = maxAge();
|
|
$page->users->addApiRequest($uid, $_SERVER['REQUEST_URI']);
|
|
$offset = offset();
|
|
|
|
$imdbId = (isset($_GET['imdbid']) ? $_GET['imdbid'] : '-1');
|
|
|
|
$relData = $releases->searchbyImdbId(
|
|
$imdbId,
|
|
$offset,
|
|
limit(),
|
|
(isset($_GET['q']) ? $_GET['q'] : ''),
|
|
categoryID(),
|
|
$maxAge
|
|
);
|
|
|
|
addCoverURL($relData,
|
|
function($release) {
|
|
return Utility::getCoverURL(['type' => 'movies', 'id' => $release['imdbid']]);
|
|
}
|
|
);
|
|
|
|
addLanguage($relData, $page->settings);
|
|
printOutput($relData, $outputXML, $page, $offset);
|
|
break;
|
|
|
|
// Get NZB.
|
|
case 'g':
|
|
if (!isset($_GET['id'])) {
|
|
showApiError(200, 'Missing parameter (id is required for downloading an NZB)');
|
|
}
|
|
|
|
$relData = $releases->getByGuid($_GET['id']);
|
|
if ($relData) {
|
|
header(
|
|
'Location:' .
|
|
WWW_TOP .
|
|
'/getnzb?i=' .
|
|
$uid .
|
|
'&r=' .
|
|
$apiKey .
|
|
'&id=' .
|
|
$relData['guid'] .
|
|
((isset($_GET['del']) && $_GET['del'] == '1') ? '&del=1' : '')
|
|
);
|
|
} else {
|
|
showApiError(300, 'No such item (the guid you provided has no release in our database)');
|
|
}
|
|
break;
|
|
|
|
// Get individual NZB details.
|
|
case 'd':
|
|
if (!isset($_GET['id'])) {
|
|
showApiError(200, 'Missing parameter (id is required for downloading an NZB)');
|
|
}
|
|
|
|
$page->users->addApiRequest($uid, $_SERVER['REQUEST_URI']);
|
|
$data = $releases->getByGuid($_GET['id']);
|
|
|
|
$relData = [];
|
|
if ($data) {
|
|
$relData[] = $data;
|
|
}
|
|
|
|
printOutput($relData, $outputXML, $page, offset());
|
|
break;
|
|
|
|
// Capabilities request.
|
|
case 'c':
|
|
//get categories
|
|
$category = new Category(['Settings' => $page->settings]);
|
|
$cats = $category->getForMenu();
|
|
|
|
//insert cats into template variable
|
|
$page->smarty->assign('parentcatlist', $cats);
|
|
|
|
if ($outputXML) { //use apicaps.tpl if xml is requested
|
|
$response = $page->smarty->fetch('apicaps.tpl');
|
|
header('Content-type: text/xml');
|
|
header('Content-Length: ' . strlen($response) );
|
|
echo $response;
|
|
} else { //otherwise construct array of capabilities and categories
|
|
//get capabilities
|
|
$caps = (new Capabilities(['Settings' => $page->settings]))->getForMenu();
|
|
$caps['categories'] = $category->getForMenu();
|
|
//use json_encode
|
|
$response = encodeAsJSON($caps);
|
|
header('Content-type: application/json');
|
|
header('Content-Length: ' . strlen($response) );
|
|
echo $response;
|
|
}
|
|
break;
|
|
// Register request.
|
|
case 'r':
|
|
verifyEmptyParameter('email');
|
|
|
|
if (!in_array((int)$page->settings->getSetting('registerstatus'), [Settings::REGISTER_STATUS_OPEN, Settings::REGISTER_STATUS_API_ONLY])) {
|
|
showApiError(104);
|
|
}
|
|
|
|
// Check email is valid format.
|
|
if (!$page->users->isValidEmail($_GET['email'])) {
|
|
showApiError(106);
|
|
}
|
|
|
|
// Check email isn't taken.
|
|
$ret = $page->users->getByEmail($_GET['email']);
|
|
if (isset($ret['id'])) {
|
|
showApiError(105);
|
|
}
|
|
|
|
// Create username/pass and register.
|
|
$username = $page->users->generateUsername($_GET['email']);
|
|
$password = $page->users->generatePassword();
|
|
|
|
// Register.
|
|
$userDefault = $page->users->getDefaultRole();
|
|
$uid = $page->users->signUp(
|
|
$username, $password, $_GET['email'], $_SERVER['REMOTE_ADDR'], $userDefault['id'], $userDefault['defaultinvites']
|
|
);
|
|
|
|
// Check if it succeeded.
|
|
$userData = $page->users->getById($uid);
|
|
if (!$userData) {
|
|
showApiError(107);
|
|
}
|
|
|
|
$response =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
|
|
'<register username="' . $username .
|
|
'" password="' . $password .
|
|
'" apikey="' . $userdata['rsstoken'] .
|
|
"\"/>\n";
|
|
header('Content-type: text/xml');
|
|
header('Content-Length: ' . strlen($response) );
|
|
echo $response;
|
|
break;
|
|
}
|
|
|
|
/**
|
|
* Display error/error code.
|
|
* @param int $errorCode
|
|
* @param string $errorText
|
|
*/
|
|
function showApiError($errorCode = 900, $errorText = '')
|
|
{
|
|
if ($errorText === '') {
|
|
switch ($errorCode) {
|
|
case 100:
|
|
$errorText = 'Incorrect user credentials';
|
|
break;
|
|
case 101:
|
|
$errorText = 'Account suspended';
|
|
break;
|
|
case 102:
|
|
$errorText = 'Insufficient privileges/not authorized';
|
|
break;
|
|
case 103:
|
|
$errorText = 'Registration denied';
|
|
break;
|
|
case 104:
|
|
$errorText = 'Registrations are closed';
|
|
break;
|
|
case 105:
|
|
$errorText = 'Invalid registration (Email Address Taken)';
|
|
break;
|
|
case 106:
|
|
$errorText = 'Invalid registration (Email Address Bad Format)';
|
|
break;
|
|
case 107:
|
|
$errorText = 'Registration Failed (Data error)';
|
|
break;
|
|
case 200:
|
|
$errorText = 'Missing parameter';
|
|
break;
|
|
case 201:
|
|
$errorText = 'Incorrect parameter';
|
|
break;
|
|
case 202:
|
|
$errorText = 'No such function';
|
|
break;
|
|
case 203:
|
|
$errorText = 'Function not available';
|
|
break;
|
|
case 300:
|
|
$errorText = 'No such item';
|
|
break;
|
|
case 500:
|
|
$errorText = 'Request limit reached';
|
|
break;
|
|
case 501:
|
|
$errorText = 'Download limit reached';
|
|
break;
|
|
default:
|
|
$errorText = 'Unknown error';
|
|
break;
|
|
}
|
|
}
|
|
|
|
$response =
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
|
|
'<error code="' . $errorCode . '" description="' . $errorText . "\"/>\n";
|
|
header('Content-type: text/xml');
|
|
header('Content-Length: ' . strlen($response) );
|
|
header('X-nZEDb: API ERROR [' . $errorCode . '] ' . $errorText);
|
|
|
|
exit($response);
|
|
}
|
|
|
|
/**
|
|
* Verify maxage parameter.
|
|
* @return int
|
|
*/
|
|
function maxAge()
|
|
{
|
|
$maxAge = -1;
|
|
if (isset($_GET['maxage'])) {
|
|
if ($_GET['maxage'] == '') {
|
|
showApiError(201, 'Incorrect parameter (maxage must not be empty)');
|
|
} elseif (!is_numeric($_GET['maxage'])) {
|
|
showApiError(201, 'Incorrect parameter (maxage must be numeric)');
|
|
} else {
|
|
$maxAge = (int)$_GET['maxage'];
|
|
}
|
|
}
|
|
return $maxAge;
|
|
}
|
|
|
|
/**
|
|
* Verify cat parameter.
|
|
* @return array
|
|
*/
|
|
function categoryID()
|
|
{
|
|
$categoryID[] = -1;
|
|
if (isset($_GET['cat'])) {
|
|
$categoryIDs = urldecode($_GET['cat']);
|
|
// Append Web-DL category ID if HD present for SickBeard / Sonarr compatibility.
|
|
if (strpos($categoryIDs, (string)Category::CAT_TV_HD) !== false &&
|
|
strpos($categoryIDs, (string)Category::CAT_TV_WEBDL) === false) {
|
|
$categoryIDs .= (',' . Category::CAT_TV_WEBDL);
|
|
}
|
|
$categoryID = explode(',', $categoryIDs);
|
|
}
|
|
return $categoryID;
|
|
}
|
|
|
|
/**
|
|
* Verify limit parameter.
|
|
* @return int
|
|
*/
|
|
function limit()
|
|
{
|
|
$limit = 100;
|
|
if (isset($_GET['limit']) && is_numeric($_GET['limit']) && $_GET['limit'] < 100) {
|
|
$limit = (int)$_GET['limit'];
|
|
}
|
|
return $limit;
|
|
}
|
|
|
|
/**
|
|
* Verify offset parameter.
|
|
* @return int
|
|
*/
|
|
function offset()
|
|
{
|
|
$offset = 0;
|
|
if (isset($_GET['offset']) && is_numeric($_GET['offset'])) {
|
|
$offset = (int)$_GET['offset'];
|
|
}
|
|
return $offset;
|
|
}
|
|
|
|
/**
|
|
* Print XML or JSON output.
|
|
* @param array $data Data to print.
|
|
* @param bool $xml True: Print as XML False: Print as JSON.
|
|
* @param BasePage $page
|
|
* @param int $offset Offset for limit.
|
|
*/
|
|
function printOutput($data, $xml = true, $page, $offset = 0)
|
|
{
|
|
if ($xml) {
|
|
$page->smarty->assign('offset', $offset);
|
|
$page->smarty->assign('releases', $data);
|
|
$response = trim($page->smarty->fetch('apiresult.tpl'));
|
|
header('Content-type: text/xml');
|
|
header('Content-Length: ' . strlen($response) );
|
|
echo $response;
|
|
} else {
|
|
$response = encodeAsJSON($data);
|
|
header('Content-type: application/json');
|
|
header('Content-Length: ' . strlen($response));
|
|
echo $response;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if a parameter is empty.
|
|
* @param string $parameter
|
|
*/
|
|
function verifyEmptyParameter($parameter)
|
|
{
|
|
if (isset($_GET[$parameter]) && $_GET[$parameter] == '') {
|
|
showApiError(201, 'Incorrect parameter (' . $parameter . ' must not be empty)');
|
|
}
|
|
}
|
|
|
|
function addCoverURL(&$releases, callable $getCoverURL)
|
|
{
|
|
if ($releases && count($releases)) {
|
|
foreach ($releases as $key => $release) {
|
|
$coverURL = $getCoverURL($release);
|
|
$releases[$key]['coverurl'] = $coverURL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add language from media info XML to release search names.
|
|
* @param array $releases
|
|
* @param newznab\db\Settings $settings
|
|
* @return array
|
|
*/
|
|
function addLanguage(&$releases, Settings $settings)
|
|
{
|
|
if ($releases && count($releases)) {
|
|
foreach ($releases as $key => $release) {
|
|
if (isset($release['id'])) {
|
|
$language = $settings->queryOneRow(sprintf('SELECT audiolanguage FROM releaseaudio WHERE releaseid = %d', $release['id']));
|
|
if ($language !== false) {
|
|
$releases[$key]['searchname'] = $releases[$key]['searchname'] . ' ' . $language['audiolanguage'];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function encodeAsJSON($data)
|
|
{
|
|
$json = json_encode(Utility::encodeAsUTF8($data));
|
|
if ($json === false) {
|
|
showApiError(201);
|
|
}
|
|
return $json;
|
|
}
|