diff --git a/lib/Rlses.php b/lib/Rlses.php deleted file mode 100644 index 759db2e28..000000000 --- a/lib/Rlses.php +++ /dev/null @@ -1,3052 +0,0 @@ -echooutput = ($echooutput && nZEDb_ECHOCLI); - $this->db = new DB(); - $this->s = new Sites(); - $this->site = $this->s->get(); - $this->groups = new Groups($this->db); - $this->releaseCleaning = new ReleaseCleaning(); - $this->consoleTools = new ConsoleTools(); - $this->stage5limit = (isset($this->site->maxnzbsprocessed)) ? (int)$this->site->maxnzbsprocessed : 1000; - $this->completion = (isset($this->site->releasecompletion)) ? (int)$this->site->releasecompletion : 0; - $this->crosspostt = (isset($this->site->crossposttime)) ? (int)$this->site->crossposttime : 2; - $this->updategrabs = ($this->site->grabstatus == '0') ? false : true; - $this->requestids = $this->tmux->lookup_reqids; - $this->delaytimet = (isset($this->site->delaytime)) ? (int)$this->site->delaytime : 2; - $this->c = new ColorCLI(); - } - - /** - * @return array - */ - public function get() - { - return $this->db->query( - ' - SELECT releases.*, g.name AS group_name, c.title AS category_name - FROM releases - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN groups g ON g.ID = releases.groupID - WHERE nzbstatus = 1' - ); - } - - /** - * @param $start - * @param $num - * - * @return array - */ - public function getRange($start, $num) - { - return $this->db->query( - sprintf( - " - SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name - FROM releases - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - WHERE nzbstatus = 1 - ORDER BY postdate DESC %s", - ($start === false ? '' : 'LIMIT ' . $num . ' OFFSET ' . $start) - ) - ); - } - - /** - * Used for paginator. - * - * @param $cat - * @param $maxage - * @param array $excludedcats - * @param string $grp - * - * @return mixed - */ - public function getBrowseCount($cat, $maxage = -1, $excludedcats = array(), $grp = '') - { - $catsrch = $this->categorySQL($cat); - - $exccatlist = $grpjoin = $grpsql = ''; - - $maxagesql = ( - $maxage > 0 - ? " AND postdate > NOW() - INTERVAL " . - (DB_TYPE === 'mysql' ? $maxage . ' DAY ' : "'" . $maxage . " DAYS' ") - : '' - ); - - if ($grp != '') { - $grpjoin = 'INNER JOIN groups ON groups.ID = releases.groupID'; - $grpsql = sprintf(' AND groups.name = %s ', $this->db->escapeString($grp)); - } - - if (count($excludedcats) > 0) { - $exccatlist = ' AND categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $res = $this->db->queryOneRow( - sprintf( - ' - SELECT COUNT(releases.ID) AS num - FROM releases %s - WHERE nzbstatus = 1 - AND releases.passwordstatus <= %d %s %s %s %s', - $grpjoin, $this->showPasswords(), $catsrch, $maxagesql, $exccatlist, $grpsql - ) - ); - - return ($res === false ? 0 : $res['num']); - } - - /** - * Used for browse results. - * - * @param $cat - * @param $start - * @param $num - * @param $orderby - * @param $maxage - * @param array $excludedcats - * @param string $grp - * - * @return array - */ - public function getBrowseRange($cat, $start, $num, $orderby, $maxage = -1, $excludedcats = array(), $grp = '') - { - $limit = ($start === false ? '' : ' LIMIT ' . $num . ' OFFSET ' . $start); - - $catsrch = $this->categorySQL($cat); - - $grpsql = $exccatlist = ''; - $maxagesql = ( - $maxage > 0 - ? " AND postdate > NOW() - INTERVAL " . - (DB_TYPE === 'mysql' ? $maxage . ' DAY ' : "'" . $maxage . " DAYS' ") - : '' - ); - - if ($grp != '') { - $grpsql = sprintf(' AND groups.name = %s ', $this->db->escapeString($grp)); - } - - if (count($excludedcats) > 0) { - $exccatlist = ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $order = $this->getBrowseOrder($orderby); - - return $this->db->query( - sprintf( - " - SELECT releases.*, - CONCAT(cp.title, ' > ', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, - groups.name AS group_name, - rn.ID AS nfoid, - re.releaseID AS reid - FROM releases - INNER JOIN groups ON groups.ID = releases.groupID - LEFT OUTER JOIN releasevideo re ON re.releaseID = releases.ID - LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID - AND rn.nfo IS NOT NULL - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - WHERE nzbstatus = 1 - AND releases.passwordstatus <= %d %s %s %s %s - ORDER BY %s %s %s", - $this->showPasswords(), $catsrch, $maxagesql, $exccatlist, $grpsql, $order[0], $order[1], $limit - ), true - ); - } - - /** - * Return site setting for hiding/showing passworded releases. - * - * @return int - */ - public function showPasswords() - { - $res = $this->db->queryOneRow("SELECT value FROM site WHERE setting = 'showpasswordedrelease'"); - - return ($res === false ? 0 : $res['value']); - } - - /** - * Use to order releases on site. - * - * @param string $orderby - * - * @return array - */ - public function getBrowseOrder($orderby) - { - $order = ($orderby == '') ? 'posted_desc' : $orderby; - $orderArr = explode('_', $order); - switch ($orderArr[0]) { - case 'cat': - $orderfield = 'categoryID'; - break; - case 'name': - $orderfield = 'searchname'; - break; - case 'size': - $orderfield = 'size'; - break; - case 'files': - $orderfield = 'totalpart'; - break; - case 'stats': - $orderfield = 'grabs'; - break; - case 'posted': - default: - $orderfield = 'postdate'; - break; - } - $ordersort = (isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1])) ? $orderArr[1] : 'desc'; - - return array($orderfield, $ordersort); - } - - /** - * Return ordering types usable on site. - * - * @return array - */ - public function getBrowseOrdering() - { - return array( - 'name_asc', - 'name_desc', - 'cat_asc', - 'cat_desc', - 'posted_asc', - 'posted_desc', - 'size_asc', - 'size_desc', - 'files_asc', - 'files_desc', - 'stats_asc', - 'stats_desc' - ); - } - - /** - * Get list of releases avaible for export. - * - * @param string $postfrom (optional) Date in this format : 01/01/2014 - * @param string $postto (optional) Date in this format : 01/01/2014 - * @param string $group (optional) Group ID. - * - * @return array - */ - public function getForExport($postfrom = '', $postto = '', $group = '') - { - if ($postfrom != '') { - $dateparts = explode('/', $postfrom); - if (count($dateparts) == 3) { - $postfrom = sprintf( - ' AND postdate > %s ', - $this->db->escapeString($dateparts[2] . '-' . $dateparts[1] . '-' . $dateparts[0] . ' 00:00:00') - ); - } else { - $postfrom = ''; - } - } - - if ($postto != '') { - $dateparts = explode('/', $postto); - if (count($dateparts) == 3) { - $postto = sprintf( - ' AND postdate < %s ', - $this->db->escapeString($dateparts[2] . '-' . $dateparts[1] . '-' . $dateparts[0] . ' 23:59:59') - ); - } else { - $postto = ''; - } - } - - if ($group != '' && $group != '-1') { - $group = sprintf(' AND groupID = %d ', $group); - } else { - $group = ''; - } - - return $this->db->query( - sprintf( - " - SELECT searchname, guid, groups.name AS gname, CONCAT(cp.title,'_',category.title) AS catName - FROM releases - INNER JOIN category ON releases.categoryID = category.ID - INNER JOIN groups ON releases.groupID = groups.ID - INNER JOIN category cp ON cp.ID = category.parentID - WHERE nzbstatus = 1 %s %s %s", - $postfrom, $postto, $group - ) - ); - } - - /** - * Get date in this format : 01/01/2014 of the oldest release. - * - * @return mixed - */ - public function getEarliestUsenetPostDate() - { - $row = $this->db->queryOneRow( - sprintf( - " - SELECT %s AS postdate FROM releases", - (DB_TYPE === 'mysql' - ? "DATE_FORMAT(min(postdate), '%d/%m/%Y')" - : "to_char(min(postdate), 'dd/mm/yyyy')" - ) - ) - ); - - return ($row === false ? '01/01/2014' : $row['postdate']); - } - - /** - * Get date in this format : 01/01/2014 of the newest release. - * - * @return mixed - */ - public function getLatestUsenetPostDate() - { - $row = $this->db->queryOneRow( - sprintf( - " - SELECT %s AS postdate FROM releases", - (DB_TYPE === 'mysql' - ? "DATE_FORMAT(max(postdate), '%d/%m/%Y')" - : "to_char(max(postdate), 'dd/mm/yyyy')" - ) - ) - ); - - return ($row === false ? '01/01/2014' : $row['postdate']); - } - - /** - * Gets all groups for drop down selection on NZB-Export web page. - * - * @param bool $blnIncludeAll - * - * @return array - */ - public function getReleasedGroupsForSelect($blnIncludeAll = true) - { - $groups = $this->db->query('SELECT DISTINCT groups.ID, groups.name FROM releases INNER JOIN groups on groups.ID = releases.groupID'); - $temp_array = array(); - - if ($blnIncludeAll) { - $temp_array[-1] = '--All Groups--'; - } - - foreach ($groups as $group) { - $temp_array[$group['ID']] = $group['name']; - } - - return $temp_array; - } - - /** - * Get releases for RSS. - * - * @param $cat - * @param $num - * @param int $uid - * @param int $rageID - * @param int $anidbID - * @param int $airdate - * - * @return array - */ - public function getRss($cat, $num, $uid = 0, $rageID, $anidbID, $airdate = -1) - { - if (DB_TYPE === 'mysql') { - $limit = ' LIMIT 0,' . ($num > 100 ? 100 : $num); - } else { - $limit = ' LIMIT ' . ($num > 100 ? 100 : $num) . ' OFFSET 0'; - } - - $catsrch = $cartsrch = ''; - if (count($cat) > 0) { - if ($cat[0] == -2) { - $cartsrch = sprintf(' INNER JOIN usercart ON usercart.userID = %d AND usercart.releaseID = releases.ID ', $uid); - } else if ($cat[0] != -1) { - $catsrch = ' AND ('; - foreach ($cat as $category) { - if ($category != -1) { - $categ = new Category(); - if ($categ->isParent($category)) { - $children = $categ->getChildren($category); - $chlist = '-99'; - foreach ($children as $child) { - $chlist .= ', ' . $child['ID']; - } - - if ($chlist != '-99') { - $catsrch .= ' releases.categoryID IN (' . $chlist . ') OR '; - } - } else { - $catsrch .= sprintf(' releases.categoryID = %d OR ', $category); - } - } - } - $catsrch .= '1=2 )'; - } - } - - $rage = ($rageID > -1) ? sprintf(' AND releases.rageID = %d ', $rageID) : ''; - $anidb = ($anidbID > -1) ? sprintf(' AND releases.anidbID = %d ', $anidbID) : ''; - if (DB_TYPE === 'mysql') { - $airdate = ($airdate > - -1) ? sprintf(' AND releases.tvairdate >= DATE_SUB(CURDATE(), INTERVAL %d DAY) ', $airdate) : ''; - } else { - $airdate = ($airdate > - -1) ? sprintf(" AND releases.tvairdate >= (CURDATE() - INTERVAL '%d DAYS') ", $airdate) : ''; - } - - return $this->db->query( - sprintf( - " - SELECT releases.*, m.cover, m.imdbID, m.rating, m.plot, - m.year, m.genre, m.director, m.actors, g.name AS group_name, - CONCAT(cp.title, ' > ', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, - COALESCE(cp.ID,0) AS parentcategoryID, - mu.title AS mu_title, mu.url AS mu_url, mu.artist AS mu_artist, - mu.publisher AS mu_publisher, mu.releasedate AS mu_releasedate, - mu.review AS mu_review, mu.tracks AS mu_tracks, mu.cover AS mu_cover, - mug.title AS mu_genre, co.title AS co_title, co.url AS co_url, - co.publisher AS co_publisher, co.releasedate AS co_releasedate, - co.review AS co_review, co.cover AS co_cover, cog.title AS co_genre - FROM releases - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - INNER JOIN groups g ON g.ID = releases.groupID - LEFT OUTER JOIN movieinfo m ON m.imdbID = releases.imdbID AND m.title != '' - LEFT OUTER JOIN musicinfo mu ON mu.ID = releases.musicinfoID - LEFT OUTER JOIN genres mug ON mug.ID = mu.genreID - LEFT OUTER JOIN consoleinfo co ON co.ID = releases.consolenfoID - LEFT OUTER JOIN genres cog ON cog.ID = co.genreID %s - WHERE releases.passwordstatus <= %d %s %s %s %s ORDER BY postdate DESC %s", - $cartsrch, $this->showPasswords(), $catsrch, $rage, $anidb, $airdate, $limit - ) - ); - } - - /** - * Get TV shows for RSS. - * - * @param $num - * @param int $uid - * @param array $excludedcats - * @param $airdate - * - * @return array - */ - public function getShowsRss($num, $uid = 0, $excludedcats = array(), $airdate = -1) - { - $exccatlist = ''; - if (count($excludedcats) > 0) { - $exccatlist = ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $usql = $this->uSQL($this->db->query(sprintf('SELECT rageID, categoryID FROM userseries WHERE userID = %d', $uid), true), 'rageID'); - if (DB_TYPE === 'mysql') { - $airdate = ($airdate > - -1) ? sprintf(' AND releases.tvairdate >= DATE_SUB(CURDATE(), INTERVAL %d DAY) ', $airdate) : ''; - } else { - $airdate = ($airdate > - -1) ? sprintf(" AND releases.tvairdate >= (CURDATE() - INTERVAL '%d DAYS') ", $airdate) : ''; - } - $limit = ' LIMIT ' . ($num > 100 ? 100 : $num) . ' OFFSET 0'; - - return $this->db->query( - sprintf( - " - SELECT releases.*, tvr.rageID, tvr.releasetitle, g.name AS group_name, - CONCAT(cp.title, '-', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, - COALESCE(cp.ID,0) AS parentcategoryID - FROM releases - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - INNER JOIN groups g ON g.ID = releases.groupID - LEFT OUTER JOIN tvrage tvr ON tvr.rageID = releases.rageID - WHERE %s %s %s - AND releases.passwordstatus <= %d - ORDER BY postdate DESC %s", - $usql, $exccatlist, $airdate, $this->showPasswords(), $limit - ) - ); - } - - /** - * Get movies for RSS. - * - * @param $num - * @param int $uid - * @param array $excludedcats - * - * @return array - */ - public function getMyMoviesRss($num, $uid = 0, $excludedcats = array()) - { - $exccatlist = ''; - if (count($excludedcats) > 0) { - $exccatlist = ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $usql = $this->uSQL($this->db->query(sprintf('SELECT imdbID, categoryID FROM usermovies WHERE userID = %d', $uid), true), 'imdbID'); - $limit = ' LIMIT ' . ($num > 100 ? 100 : $num) . ' OFFSET 0'; - - return $this->db->query( - sprintf( - " - SELECT releases.*, mi.title AS releasetitle, g.name AS group_name, - CONCAT(cp.title, '-', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, - COALESCE(cp.ID,0) AS parentcategoryID - FROM releases - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - INNER JOIN groups g ON g.ID = releases.groupID - LEFT OUTER JOIN movieinfo mi ON mi.imdbID = releases.imdbID - WHERE %s %s - AND releases.passwordstatus <= %d - ORDER BY postdate DESC %s", - $usql, $exccatlist, $this->showPasswords(), $limit - ) - ); - } - - /** - * Get TV for my shows page. - * - * @param $usershows - * @param $start - * @param $num - * @param $orderby - * @param $maxage - * @param array $excludedcats - * - * @return array - */ - public function getShowsRange($usershows, $start, $num, $orderby, $maxage = -1, $excludedcats = array()) - { - if ($start === false) { - $limit = ''; - } else { - $limit = ' LIMIT ' . $num . ' OFFSET ' . $start; - } - - $exccatlist = $maxagesql = ''; - if (count($excludedcats) > 0) { - $exccatlist = ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $usql = $this->uSQL($usershows, 'rageID'); - - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxagesql = sprintf(' AND releases.postdate > NOW() - INTERVAL %d DAY ', $maxage); - } else { - $maxagesql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $maxage); - } - } - - $order = $this->getBrowseOrder($orderby); - - return $this->db->query( - sprintf( - " - SELECT releases.*, CONCAT(cp.title, '-', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name, - rn.ID AS nfoid, re.releaseID AS reid - FROM releases - LEFT OUTER JOIN releasevideo re ON re.releaseID = releases.ID - INNER JOIN groups ON groups.ID = releases.groupID - LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID AND rn.nfo IS NOT NULL - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - WHERE %s %s - AND releases.passwordstatus <= %d %s - ORDER BY %s %s %s", - $usql, $exccatlist, $this->showPasswords(), $maxagesql, $order[0], $order[1], $limit - ) - ); - } - - /** - * Get count for my shows page pagination. - * - * @param $usershows - * @param $maxage - * @param array $excludedcats - * - * @return int - */ - public function getShowsCount($usershows, $maxage = -1, $excludedcats = array()) - { - $exccatlist = $maxagesql = ''; - if (count($excludedcats) > 0) { - $exccatlist = ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')'; - } - - $usql = $this->uSQL($usershows, 'rageID'); - - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxagesql = sprintf(' AND releases.postdate > NOW() - INTERVAL %d DAY ', $maxage); - } else { - $maxagesql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $maxage); - } - } - - $res = $this->db->queryOneRow( - sprintf( - ' - SELECT COUNT(releases.ID) AS num - FROM releases - WHERE %s %s - AND releases.passwordstatus <= %d %s', - $usql, $exccatlist, $this->showPasswords(), $maxagesql - ), true - ); - - return ($res === false ? 0 : $res['num']); - } - - /** - * Get count for admin release list page. - * - * @return int - */ - public function getCount() - { - $res = $this->db->queryOneRow('SELECT COUNT(ID) AS num FROM releases'); - - return ($res === false ? 0 : $res['num']); - } - - /** - * Delete a release or multiple releases. - * - * @param int|string $id - * @param bool $isGuid - */ - public function delete($id, $isGuid = false) - { - if (!is_array($id)) { - $id = array($id); - } - - foreach ($id as $identifier) { - if ($isGuid) { - $rel = $this->getByGuid($identifier); - } else { - $rel = $this->getById($identifier); - } - $this->fastDelete($rel['ID'], $rel['guid']); - } - } - - /** - * Deletes a single release, and all the corresponding files. - * - * @param int $id release id - * @param string $guid release guid - */ - public function fastDelete($id, $guid) - { - $nzb = new Enzebe(); - // Delete NZB from disk. - $nzbpath = $nzb->getNZBPath($guid); - if (is_file($nzbpath)) { - @unlink($nzbpath); - } - - // Delete images. - $ri = new ReleaseImage(); - $ri->delete($guid); - - // Delete from DB. - if (DB_TYPE === 'mysql') { - $this->db->exec( - sprintf( - 'DELETE - releases, releasenfo, releasecomment, usercart, releasefiles, - releaseaudio, releasesubs, releasevideo, releaseextrafull - FROM releases - LEFT OUTER JOIN releasenfo ON releasenfo.releaseID = releases.ID - LEFT OUTER JOIN releasecomment ON releasecomment.releaseID = releases.ID - LEFT OUTER JOIN usercart ON usercart.releaseID = releases.ID - LEFT OUTER JOIN releasefiles ON releasefiles.releaseID = releases.ID - LEFT OUTER JOIN releaseaudio ON releaseaudio.releaseID = releases.ID - LEFT OUTER JOIN releasesubs ON releasesubs.releaseID = releases.ID - LEFT OUTER JOIN releasevideo ON releasevideo.releaseID = releases.ID - LEFT OUTER JOIN releaseextrafull ON releaseextrafull.releaseID = releases.ID - WHERE releases.ID = %d', - $id - ) - ); - } else { - $this->db->exec('DELETE FROM releasenfo WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releasecomment WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM usercart WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releasefiles WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releaseaudio WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releasesubs WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releasevideo WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releaseextrafull WHERE releaseID = ' . $id); - $this->db->exec('DELETE FROM releases WHERE ID = ' . $id); - } - } - - /** - * Used for release edit page on site. - * - * @param $id - * @param $name - * @param $searchname - * @param $fromname - * @param $category - * @param $parts - * @param $grabs - * @param $size - * @param $posteddate - * @param $addeddate - * @param $rageID - * @param $seriesfull - * @param $season - * @param $episode - * @param $imdbID - * @param $anidbID - */ - public function update( - $id, $name, $searchname, $fromname, $category, $parts, $grabs, $size, - $posteddate, $addeddate, $rageID, $seriesfull, $season, $episode, $imdbID, $anidbID - ) - { - $this->db->exec( - sprintf( - 'UPDATE releases - SET name = %s, searchname = %s, fromname = %s, categoryID = %d, - totalpart = %d, grabs = %d, size = %s, postdate = %s, adddate = %s, rageID = %d, - seriesfull = %s, season = %s, episode = %s, imdbID = %d, anidbID = %d - WHERE ID = %d', - $this->db->escapeString($name), $this->db->escapeString($searchname), $this->db->escapeString($fromname), - $category, $parts, $grabs, $this->db->escapeString($size), $this->db->escapeString($posteddate), - $this->db->escapeString($addeddate), $rageID, $this->db->escapeString($seriesfull), - $this->db->escapeString($season), $this->db->escapeString($episode), $imdbID, $anidbID, $id - ) - ); - } - - /** - * Used for updating releases on site. - * - * @param $guids - * @param $category - * @param $grabs - * @param $rageID - * @param $season - * @param $imdbID - * - * @return array|bool|int - */ - public function updatemulti($guids, $category, $grabs, $rageID, $season, $imdbID) - { - if (!is_array($guids) || sizeof($guids) < 1) { - return false; - } - - $update = array( - 'categoryID' => (($category == '-1') ? '' : $category), - 'grabs' => $grabs, - 'rageID' => $rageID, - 'season' => $season, - 'imdbID' => $imdbID - ); - - $updateSql = array(); - foreach ($update as $updk => $updv) { - if ($updv != '') { - $updateSql[] = sprintf($updk . '=%s', $this->db->escapeString($updv)); - } - } - - if (count($updateSql) < 1) { - return -1; - } - - $updateGuids = array(); - foreach ($guids as $guid) { - $updateGuids[] = $this->db->escapeString($guid); - } - - return $this->db->query( - sprintf( - ' - UPDATE releases SET %s WHERE guid IN (%s)', - implode(', ', $updateSql), - implode(', ', $updateGuids) - ) - ); - } - - /** - * Creates part of a query for some functions. - * - * @param $userquery - * @param $type - * - * @return string - */ - public function uSQL($userquery, $type) - { - $usql = '(1=2 '; - foreach ($userquery as $u) { - $usql .= sprintf('OR (releases.%s = %d', $type, $u[$type]); - if ($u['categoryID'] != '') { - $catsArr = explode('|', $u['categoryID']); - if (count($catsArr) > 1) { - $usql .= sprintf(' AND releases.categoryID IN (%s)', implode(',', $catsArr)); - } else { - $usql .= sprintf(' AND releases.categoryID = %d', $catsArr[0]); - } - } - $usql .= ') '; - } - $usql .= ') '; - - return $usql; - } - - /** - * Creates part of a query for searches based on the type of search. - * - * @param $search - * @param $type - * - * @return string - */ - public function searchSQL($search, $type) - { - // If the query starts with a ^ or ! it indicates the search is looking for items which start with the term - // still do the fulltext match, but mandate that all items returned must start with the provided word. - $words = explode(' ', $search); - - //only used to get a count of words - $searchwords = $searchsql = ''; - $intwordcount = 0; - - if (count($words) > 0) { - if ($type === 'name' || $type === 'searchname') { - //at least 1 term needs to be mandatory - if (!preg_match('/[+|!|^]/', $search)) { - $search = '+' . $search; - $words = explode(' ', $search); - } - foreach ($words as $word) { - $word = trim(rtrim(trim($word), '-')); - $word = str_replace('!', '+', $word); - $word = str_replace('^', '+', $word); - $word = str_replace("'", "\\'", $word); - - if ($word !== '' && $word !== '-' && strlen($word) >= 2) { - $searchwords .= sprintf('%s ', $word); - } - } - $searchwords = trim($searchwords); - - $searchsql .= sprintf(" AND MATCH(rs.name, rs.searchname) AGAINST('%s' IN BOOLEAN MODE)", - $searchwords - ); - } - if ($searchwords === '') { - $words = explode(' ', $search); - $like = 'ILIKE'; - if (DB_TYPE === 'mysql') { - $like = 'LIKE'; - } - foreach ($words as $word) { - if ($word != '') { - $word = trim(rtrim(trim($word), '-')); - if ($intwordcount == 0 && (strpos($word, '^') === 0)) { - $searchsql .= sprintf( - ' AND releases.%s %s %s', $type, $like, $this->db->escapeString( - substr($word, 1) . '%' - ) - ); - } else if (substr($word, 0, 2) == '--') { - $searchsql .= sprintf( - ' AND releases.%s NOT %s %s', $type, $like, $this->db->escapeString( - '%' . substr($word, 2) . '%' - ) - ); - } else { - $searchsql .= sprintf( - ' AND releases.%s %s %s', $type, $like, $this->db->escapeString( - '%' . $word . '%' - ) - ); - } - - $intwordcount++; - } - } - } - - return $searchsql; - } - } - - // Creates part of a query for searches requiring the categoryID's. - public function categorySQL($cat) - { - $catsrch = ''; - if (count($cat) > 0 && $cat[0] != -1) { - $categ = new Category(); - $catsrch = ' AND ('; - foreach ($cat as $category) { - if ($category != -1) { - if ($categ->isParent($category)) { - $children = $categ->getChildren($category); - $chlist = '-99'; - foreach ($children as $child) { - $chlist .= ', ' . $child['ID']; - } - - if ($chlist != '-99') { - $catsrch .= ' releases.categoryID IN (' . $chlist . ') OR '; - } - } else { - $catsrch .= sprintf(' releases.categoryID = %d OR ', $category); - } - } - } - $catsrch .= '1=2 )'; - } - - return $catsrch; - } - - // Function for searching on the site (by subject, searchname or advanced). - public function search($searchname, $usenetname, $postername, $groupname, $cat = array(-1), $sizefrom, $sizeto, $hasnfo, $hascomments, $daysnew, $daysold, $offset = 0, $limit = 1000, $orderby = '', $maxage = -1, $excludedcats = array(), $type = 'basic') - { - if ($type !== 'advanced') { - $catsrch = $this->categorySQL($cat); - } else { - $catsrch = ''; - if ($cat != '-1') { - $catsrch = sprintf(' AND (releases.categoryID = %d) ', $cat); - } - } - - $daysnewsql = $daysoldsql = $maxagesql = $groupIDsql = $parentcatsql = ''; - - $searchnamesql = ($searchname != '-1' ? $this->searchSQL($searchname, 'searchname') : ''); - $usenetnamesql = ($usenetname != '-1' ? $this->searchSQL($usenetname, 'name') : ''); - $posternamesql = ($postername != '-1' ? $this->searchSQL($postername, 'fromname') : ''); - $hasnfosql = ($hasnfo != '0' ? ' AND releases.nfostatus = 1 ' : ''); - $hascommentssql = ($hascomments != '0' ? ' AND releases.comments > 0 ' : ''); - $exccatlist = (count($excludedcats) > 0 ? - ' AND releases.categoryID NOT IN (' . implode(',', $excludedcats) . ')' : ''); - - if ($daysnew != '-1') { - if (DB_TYPE === 'mysql') { - $daysnewsql = sprintf(' AND releases.postdate < (NOW() - INTERVAL %d DAY) ', $daysnew); - } else { - $daysnewsql = sprintf(" AND releases.postdate < NOW() - INTERVAL '%d DAYS' ", $daysnew); - } - } - - if ($daysold != '-1') { - if (DB_TYPE === 'mysql') { - $daysoldsql = sprintf(' AND releases.postdate > (NOW() - INTERVAL %d DAY) ', $daysold); - } else { - $daysoldsql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $daysold); - } - } - - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxagesql = sprintf(' AND releases.postdate > (NOW() - INTERVAL %d DAY) ', $maxage); - } else { - $maxagesql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $maxage); - } - } - - if ($groupname != '-1') { - $groupID = $this->functions->getIDByName($groupname); - $groupIDsql = sprintf(' AND releases.groupID = %d ', $groupID); - } - - $sizefromsql = ''; - switch ($sizefrom) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '10': - case '11': - $sizefromsql = ' AND releases.size > ' . (string)(104857600 * (int)$sizefrom) . ' '; - break; - default: - break; - } - - $sizetosql = ''; - switch ($sizeto) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '10': - case '11': - $sizetosql = ' AND releases.size < ' . (string)(104857600 * (int)$sizeto) . ' '; - break; - default: - break; - } - - if ($orderby == '') { - $order[0] = 'postdate '; - $order[1] = 'desc '; - } else { - $order = $this->getBrowseOrder($orderby); - } - - $sql = sprintf( - "SELECT * FROM (SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name, - CONCAT(cp.ID, ',', c.ID) AS category_ids, - groups.name AS group_name, rn.ID AS nfoid, - re.releaseID AS reid, cp.ID AS categoryparentID - FROM releases - INNER JOIN releasesearch rs on rs.releaseID = releases.ID - LEFT OUTER JOIN releasevideo re ON re.releaseID = releases.ID - LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID - INNER JOIN groups ON groups.ID = releases.groupID - INNER JOIN category c ON c.ID = releases.categoryID - INNER JOIN category cp ON cp.ID = c.parentID - WHERE releases.passwordstatus <= %d %s %s %s %s %s %s %s %s %s %s %s %s %s) r - ORDER BY r.%s %s LIMIT %d OFFSET %d", - $this->showPasswords(), $searchnamesql, $usenetnamesql, $maxagesql, $posternamesql, $groupIDsql, $sizefromsql, - $sizetosql, $hasnfosql, $hascommentssql, $catsrch, $daysnewsql, $daysoldsql, $exccatlist, $order[0], - $order[1], $limit, $offset - ); - $wherepos = strpos($sql, 'WHERE'); - $countres = $this->db->queryOneRow( - 'SELECT COUNT(releases.ID) AS num FROM releases INNER JOIN releasesearch rs on rs.releaseID = releases.ID ' . - substr($sql, $wherepos, strrpos($sql, ')') - $wherepos) - ); - $res = $this->db->query($sql); - if (count($res) > 0) { - $res[0]['_totalrows'] = $countres['num']; - } - - return $res; - } - - public function searchbyrageID($rageID, $series = '', $episode = '', $offset = 0, $limit = 100, $name = '', $cat = array(-1), $maxage = -1) - { - $rageIDsql = $maxagesql = ''; - - if ($rageID != '-1') { - $rageIDsql = sprintf(' AND rageID = %d ', $rageID); - } - - if ($series != '') { - // Exclude four digit series, which will be the year 2010 etc. - if (is_numeric($series) && strlen($series) != 4) { - $series = sprintf('S%02d', $series); - } - - $series = sprintf(' AND UPPER(releases.season) = UPPER(%s)', $this->db->escapeString($series)); - } - - if ($episode != '') { - if (is_numeric($episode)) { - $episode = sprintf('E%02d', $episode); - } - - $like = 'ILIKE'; - if (DB_TYPE === 'mysql') { - $like = 'LIKE'; - } - $episode = sprintf(' AND releases.episode %s %s', $like, $this->db->escapeString('%' . $episode . '%')); - } - - $searchsql = ''; - if ($name !== '') { - $searchsql = $this->searchSQL($name, 'searchname'); - } - $catsrch = $this->categorySQL($cat); - - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxagesql = sprintf(' AND releases.postdate > NOW() - INTERVAL %d DAY ', $maxage); - } else { - $maxagesql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $maxage); - } - } - $sql = sprintf("SELECT releases.*, concat(cp.title, ' > ', c.title) AS category_name, CONCAT(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name, rn.ID AS nfoid, re.releaseID AS reid FROM releases INNER JOIN category c ON c.ID = releases.categoryID INNER JOIN groups ON groups.ID = releases.groupID INNER JOIN releasesearch rs on rs.releaseID = releases.ID LEFT OUTER JOIN releasevideo re ON re.releaseID = releases.ID LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID AND rn.nfo IS NOT NULL INNER JOIN category cp ON cp.ID = c.parentID WHERE releases.passwordstatus <= %d %s %s %s %s %s %s ORDER BY postdate DESC LIMIT %d OFFSET %d", $this->showPasswords(), $rageIDsql, $series, $episode, $searchsql, $catsrch, $maxagesql, $limit, $offset); - $orderpos = strpos($sql, 'ORDER BY'); - $wherepos = strpos($sql, 'WHERE'); - $sqlcount = 'SELECT COUNT(releases.ID) AS num FROM releases INNER JOIN releasesearch rs on rs.releaseID = releases.ID ' . substr($sql, $wherepos, $orderpos - $wherepos); - - $countres = $this->db->queryOneRow($sqlcount); - $res = $this->db->query($sql); - if (count($res) > 0) { - $res[0]['_totalrows'] = $countres['num']; - } - - return $res; - } - - public function searchbyanidbID($anidbID, $epno = '', $offset = 0, $limit = 100, $name = '', $cat = array(-1), $maxage = -1) - { - $anidbID = ($anidbID > -1) ? sprintf(' AND anidbID = %d ', $anidbID) : ''; - - $like = 'ILIKE'; - if (DB_TYPE === 'mysql') { - $like = 'LIKE'; - } - - is_numeric($epno) ? $epno = sprintf( - " AND releases.episode %s '%s' ", $like, $this->db->escapeString( - '%' . $epno . '%' - ) - ) : ''; - - $searchsql = ''; - if ($name !== '') { - $searchsql = $this->searchSQL($name, 'searchname'); - } - $catsrch = $this->categorySQL($cat); - - $maxagesql = ''; - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxagesql = sprintf(' AND releases.postdate > NOW() - INTERVAL %d DAY ', $maxage); - } else { - $maxagesql = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS' ", $maxage); - } - } - - $sql = sprintf("SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name, CONCAT(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name, rn.ID AS nfoid FROM releases INNER JOIN releasesearch rs on rs.releaseID = releases.ID INNER JOIN category c ON c.ID = releases.categoryID INNER JOIN groups ON groups.ID = releases.groupID LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID and rn.nfo IS NOT NULL INNER JOIN category cp ON cp.ID = c.parentID WHERE releases.passwordstatus <= %d %s %s %s %s %s ORDER BY postdate DESC LIMIT %d OFFSET %d", $this->showPasswords(), $anidbID, $epno, $searchsql, $catsrch, $maxage, $limit, $offset); - $orderpos = strpos($sql, 'ORDER BY'); - $wherepos = strpos($sql, 'WHERE'); - $sqlcount = 'SELECT COUNT(releases.ID) AS num FROM releases INNER JOIN releasesearch rs on rs.releaseID = releases.ID ' . substr($sql, $wherepos, $orderpos - $wherepos); - - $countres = $this->db->queryOneRow($sqlcount); - $res = $this->db->query($sql); - if (count($res) > 0) { - $res[0]['_totalrows'] = $countres['num']; - } - - return $res; - } - - public function searchbyimdbID($imdbID, $offset = 0, $limit = 100, $name = '', $cat = array(-1), $maxage = -1) - { - if ($imdbID != '-1' && is_numeric($imdbID)) { - // Pad ID with zeros just in case. - $imdbID = str_pad($imdbID, 7, '0', STR_PAD_LEFT); - $imdbID = sprintf(' AND imdbID = %d ', $imdbID); - } else { - $imdbID = ''; - } - - $searchsql = ''; - if ($name !== '') { - $searchsql = $this->searchSQL($name, 'searchname'); - } - $catsrch = $this->categorySQL($cat); - - if ($maxage > 0) { - if (DB_TYPE === 'mysql') { - $maxage = sprintf(' AND releases.postdate > NOW() - INTERVAL %d DAY ', $maxage); - } else { - $maxage = sprintf(" AND releases.postdate > NOW() - INTERVAL '%d DAYS ", $maxage); - } - } else { - $maxage = ''; - } - - $sql = sprintf("SELECT releases.*, concat(cp.title, ' > ', c.title) AS category_name, CONCAT(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name, rn.ID AS nfoid FROM releases INNER JOIN groups ON groups.ID = releases.groupID INNER JOIN category c ON c.ID = releases.categoryID INNER JOIN releasesearch rs on rs.releaseID = releases.ID LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID AND rn.nfo IS NOT NULL INNER JOIN category cp ON cp.ID = c.parentID WHERE releases.passwordstatus <= %d %s %s %s %s ORDER BY postdate DESC LIMIT %d OFFSET %d", $this->showPasswords(), $searchsql, $imdbID, $catsrch, $maxage, $limit, $offset); - $orderpos = strpos($sql, 'ORDER BY'); - $wherepos = strpos($sql, 'WHERE'); - $sqlcount = 'SELECT COUNT(releases.ID) AS num FROM releases INNER JOIN releasesearch rs on rs.releaseID = releases.ID ' . substr($sql, $wherepos, $orderpos - $wherepos); - - $countres = $this->db->queryOneRow($sqlcount); - $res = $this->db->query($sql); - if (count($res) > 0) { - $res[0]['_totalrows'] = $countres['num']; - } - - return $res; - } - - public function searchSimilar($currentid, $name, $limit = 6, $excludedcats = array()) - { - // Get the category for the parent of this release. - $currRow = $this->getById($currentid); - $cat = new Category(); - $catrow = $cat->getById($currRow['categoryID']); - $parentCat = $catrow['parentID']; - - $name = $this->getSimilarName($name); - $results = $this->search( - $name, -1, -1, -1, array($parentCat), -1, -1, 0, 0, -1, -1, 0, $limit, '', -1, - $excludedcats - ); - if (!$results) { - return $results; - } - - $ret = array(); - foreach ($results as $res) { - if ($res['ID'] != $currentid && $res['categoryparentID'] == $parentCat) { - $ret[] = $res; - } - } - - return $ret; - } - - public function getSimilarName($name) - { - $words = str_word_count(str_replace(array('.', '_'), ' ', $name), 2); - $firstwords = array_slice($words, 0, 3); - - return implode(' ', $firstwords); - } - - public function getByGuid($guid) - { - if (is_array($guid)) { - $tmpguids = array(); - foreach ($guid as $g) { - $tmpguids[] = $this->db->escapeString($g); - } - $gsql = sprintf('guid IN (%s)', implode(',', $tmpguids)); - } else { - $gsql = sprintf('guid = %s', $this->db->escapeString($guid)); - } - $sql = sprintf("SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name, CONCAT(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name FROM releases INNER JOIN groups ON groups.ID = releases.groupID INNER JOIN category c ON c.ID = releases.categoryID INNER JOIN category cp ON cp.ID = c.parentID WHERE %s ", $gsql); - - return (is_array($guid)) ? $this->db->query($sql) : $this->db->queryOneRow($sql); - } - - // Writes a zip file of an array of release guids directly to the stream. - public function getZipped($guids) - { - $nzb = new Enzebe(); - $zipfile = new ZipFile(); - - foreach ($guids as $guid) { - $nzbpath = $nzb->getNZBPath($guid); - - if (is_file($nzbpath)) { - ob_start(); - @readgzfile($nzbpath); - $nzbfile = ob_get_contents(); - ob_end_clean(); - - $filename = $guid; - $r = $this->getByGuid($guid); - if ($r) { - $filename = $r['searchname']; - } - - $zipfile->addFile($nzbfile, $filename . '.nzb'); - } - } - - return $zipfile->file(); - } - - public function getbyrageID($rageID, $series = '', $episode = '') - { - if ($series != '') { - // Exclude four digit series, which will be the year 2010 etc. - if (is_numeric($series) && strlen($series) != 4) { - $series = sprintf('S%02d', $series); - } - - $series = sprintf(' AND UPPER(releases.season) = UPPER(%s)', $this->db->escapeString($series)); - } - - if ($episode != '') { - if (is_numeric($episode)) { - $episode = sprintf('E%02d', $episode); - } - - $episode = sprintf(' AND UPPER(releases.episode) = UPPER(%s)', $this->db->escapeString($episode)); - } - - return $this->db->queryOneRow(sprintf("SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name, groups.name AS group_name FROM releases INNER JOIN groups ON groups.ID = releases.groupID INNER JOIN category c ON c.ID = releases.categoryID INNER JOIN category cp ON cp.ID = c.parentID WHERE releases.passwordstatus <= %d AND rageID = %d %s %s", $this->showPasswords(), $rageID, $series, $episode)); - } - - public function removerageIDFromReleases($rageID) - { - $res = $this->db->queryOneRow(sprintf('SELECT COUNT(ID) AS num FROM releases WHERE rageID = %d', $rageID)); - $this->db->exec(sprintf('UPDATE releases SET rageID = -1, seriesfull = NULL, season = NULL, episode = NULL WHERE rageID = %d', $rageID)); - - return $res['num']; - } - - public function removeanidbIDFromReleases($anidbID) - { - $res = $this->db->queryOneRow(sprintf('SELECT COUNT(ID) AS num FROM releases WHERE anidbID = %d', $anidbID)); - $this->db->exec(sprintf('UPDATE releases SET anidbID = -1, episode = NULL, tvtitle = NULL, tvairdate = NULL WHERE anidbID = %d', $anidbID)); - - return $res['num']; - } - - public function getById($id) - { - return $this->db->queryOneRow(sprintf('SELECT releases.*, groups.name AS group_name FROM releases INNER JOIN groups ON groups.ID = releases.groupID WHERE releases.ID = %d ', $id)); - } - - public function getReleaseNfo($id, $incnfo = true) - { - if (DB_TYPE === 'mysql') { - $uc = 'UNCOMPRESS(nfo)'; - } else { - $uc = 'nfo'; - } - $selnfo = ($incnfo) ? ", {$uc} AS nfo" : ''; - - return $this->db->queryOneRow( - sprintf( - 'SELECT ID, releaseID' . $selnfo . ' FROM releasenfo WHERE releaseID = %d AND nfo IS NOT NULL', $id - ) - ); - } - - public function updateGrab($guid) - { - if ($this->updategrabs) { - $this->db->exec(sprintf('UPDATE releases SET grabs = grabs + 1 WHERE guid = %s', $this->db->escapeString($guid))); - } - } - - // Sends releases back to other->misc. - public function resetCategorize($where = '') - { - $this->db->exec('UPDATE releases SET categoryID = 7010, iscategorized = 0 ' . $where); - } - - // Categorizes releases. - // $type = name or searchname - // Returns the quantity of categorized releases. - public function categorizeRelease($type, $where = '', $echooutput = false) - { - $cat = new Category(); - $relcount = 0; - $resrel = $this->db->queryDirect('SELECT ID, ' . $type . ', groupID FROM releases ' . $where); - $total = 0; - if ($resrel !== false) { - $total = $resrel->rowCount(); - } - if ($total > 0) { - foreach ($resrel as $rowrel) { - $catId = $cat->determineCategory($rowrel[$type], $rowrel['groupID']); - $this->db->exec(sprintf('UPDATE releases SET categoryID = %d, iscategorized = 1 WHERE ID = %d', $catId, $rowrel['ID'])); - $relcount++; - if ($this->echooutput) { - $this->consoleTools->overWritePrimary( - 'Categorizing: ' . $this->consoleTools->percentString($relcount, $total) - ); - } - } - } - if ($this->echooutput !== false && $relcount > 0) { - echo "\n"; - } - - return $relcount; - } - - public function processReleasesStage1($groupID) - { - require_once(WWW_DIR . "/lib/binaries.php"); - - $db = new DB; - $currTime_ori = $db->queryOneRow("SELECT NOW() as now"); - $cat = new Category(); - $nzb = new Enzebe(); - $s = new Sites(); - $releaseRegex = new ReleaseRegex(); - $page = new Page(); - $groups = new Groups; - $retcount = 0; - - echo $s->getLicense(); - - echo "\n\nStarting release update process (" . date("Y-m-d H:i:s") . ")\n"; - - if (!file_exists($page->site->nzbpath)) { - echo "Bad or missing nzb directory - " . $page->site->nzbpath; - - return -1; - } - - $this->checkRegexesUptoDate($page->site->latestregexurl, $page->site->latestregexrevision, $page->site->newznabID); - - // - // Get all regexes for all groups which are to be applied to new binaries - // in order of how they should be applied - // - $releaseRegex->get(); - echo "Stage 1 : Applying regex to binaries\n"; - $activeGroups = $groups->getActive(false); - foreach ($activeGroups as $groupArr) { - //check if regexes have already been applied during update binaries - if ($groupArr['regexmatchonly'] == 1) - continue; - - $groupRegexes = $releaseRegex->getForGroup($groupArr['name']); - - echo "Stage 1 : Applying " . sizeof($groupRegexes) . " regexes to group " . $groupArr['name'] . "\n"; - - // Get out all binaries of STAGE0 for current group - $newUnmatchedBinaries = array(); - $ressql = sprintf("SELECT binaries.ID, binaries.name, binaries.date, binaries.totalParts, binaries.procstat, binaries.fromname from binaries where groupID = %d and procstat IN (%d,%d) and regexID IS NULL order by binaries.date asc", $groupArr['ID'], Releases::PROCSTAT_NEW, Releases::PROCSTAT_TITLENOTMATCHED); - $resbin = $db->queryDirect($ressql); - - $matchedbins = 0; - while ($rowbin = $db->getAssocArray($resbin)) { - $regexMatches = array(); - foreach ($groupRegexes as $groupRegex) { - $regexCheck = $releaseRegex->performMatch($groupRegex, $rowbin['name']); - if ($regexCheck !== false) { - $regexMatches = $regexCheck; - break; - } - } - - if (!empty($regexMatches)) { - $matchedbins++; - $relparts = explode("/", $regexMatches['parts']); - $db->exec(sprintf("update binaries set relname = replace(%s, '_', ' '), relpart = %d, reltotalpart = %d, procstat=%d, categoryID=%s, regexID=%d, reqID=%s where ID = %d", - $db->escapeString($regexMatches['name']), $relparts[0], $relparts[1], Releases::PROCSTAT_TITLEMATCHED, $regexMatches['regcatid'], $regexMatches['regexID'], $db->escapeString($regexMatches['reqID']), $rowbin["ID"] - ) - ); - } else { - if ($rowbin['procstat'] == Releases::PROCSTAT_NEW) - $newUnmatchedBinaries[] = $rowbin['ID']; - } - - } - - //mark as not matched - if (!empty($newUnmatchedBinaries)) - $db->exec(sprintf("update binaries set procstat=%d where ID IN (%s)", Releases::PROCSTAT_TITLENOTMATCHED, implode(',', $newUnmatchedBinaries))); - - } - } - - public function processReleasesStage2($groupID) - { - // - // Move all binaries from releases which have the correct number of files on to the next stage. - // - echo "Stage 2 : Marking binaries where all parts are available"; - $result = $db->queryDirect(sprintf("SELECT relname, date, SUM(reltotalpart) AS reltotalpart, groupID, reqID, fromname, SUM(num) AS num, coalesce(g.minfilestoformrelease, s.minfilestoformrelease) as minfilestoformrelease FROM ( SELECT relname, reltotalpart, groupID, reqID, fromname, max(date) as date, COUNT(ID) AS num FROM binaries WHERE procstat = %s GROUP BY relname, reltotalpart, groupID, reqID, fromname ORDER BY NULL ) x left outer join groups g on g.ID = x.groupID inner join ( select value as minfilestoformrelease from site where setting = 'minfilestoformrelease' ) s GROUP BY relname, groupID, reqID, fromname, minfilestoformrelease ORDER BY NULL", Releases::PROCSTAT_TITLEMATCHED)); - - while ($row = $db->getAssocArray($result)) { - $retcount++; - - // - // Less than the site permitted number of files in a release. Dont discard it, as it may - // be part of a set being uploaded. - // - if ($row["num"] < $row["minfilestoformrelease"]) { - //echo "Number of files in release ".$row["relname"]." less than site/group setting (".$row['num']."/".$row["minfilestoformrelease"].")\n"; - $db->exec(sprintf("update binaries set procattempts = procattempts + 1 where relname = %s and procstat = %d and groupID = %d and fromname = %s", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - } - - // - // There are the same or more files in our release than the number of files specified - // in the message subject so go ahead and make a release - // - elseif ($row["num"] >= $row["reltotalpart"]) { - $incomplete = false; - - if ($row['reltotalpart'] == 0 && strtotime($currTime_ori['now']) - strtotime($row['date']) < 14400) { - $incomplete = true; - } else { - // Check that the binary is complete - $binlist = $db->query(sprintf("SELECT binaries.ID, totalParts, date, COUNT(DISTINCT parts.messageID) AS num FROM binaries, parts WHERE binaries.ID=parts.binaryID AND binaries.relname = %s AND binaries.procstat = %d AND binaries.groupID = %d AND binaries.fromname = %s GROUP BY binaries.ID ORDER BY NULL", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - - foreach ($binlist as $rowbin) { - if ($rowbin['num'] < $rowbin['totalParts']) { - // Allow to binary to release if posted to usenet longer than four hours ago and we still don't have all the parts - if (!(strtotime($currTime_ori['now']) - strtotime($rowbin['date']) > 14400)) { - $incomplete = true; - break; - } - } - } - } - - if (!$incomplete) { - // - // Right number of files, but see if the binary is a allfilled/reqid post, in which case it needs its name looked up - // - if ($row['reqID'] != '' && $page->site->reqidurl != "") { - // - // Try and get the name using the group - // - $binGroup = $db->queryOneRow(sprintf("SELECT name FROM groups WHERE ID = %d", $row["groupID"])); - $newtitle = $this->getReleaseNameForReqId($page->site->reqidurl, $page->site->newznabID, $binGroup["name"], $row["reqID"]); - - // - // if the feed/group wasnt supported by the scraper, then just use the release name as the title. - // - if ($newtitle == "no feed") { - $newtitle = $row["relname"]; - } - - // - // Valid release with right number of files and title now, so move it on - // - if ($newtitle != "") { - $db->exec(sprintf("update binaries set relname = %s, procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - $db->escapeString($newtitle), Releases::PROCSTAT_READYTORELEASE, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) - ) - ); - } else { - // - // Item not found, if the binary was added to the index yages ago, then give up. - // - $maxaddeddate = $db->queryOneRow(sprintf("SELECT NOW() as now, MAX(dateadded) as dateadded FROM binaries WHERE relname = %s and procstat = %d and groupID = %d and fromname=%s", - $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) - ) - ); - - // - // If added to the index over 48 hours ago, give up trying to determine the title - // - if (strtotime($maxaddeddate['now']) - strtotime($maxaddeddate['dateadded']) > (60 * 60 * 48)) { - $db->exec(sprintf("update binaries set procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - Releases::PROCSTAT_NOREQIDNAMELOOKUPFOUND, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) - ) - ); - } - } - } else { - $db->exec(sprintf("update binaries set procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - Releases::PROCSTAT_READYTORELEASE, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) - ) - ); - } - } - } - - // - // Theres less than the expected number of files, so update the attempts and move on. - // - else { - // pointless updating of attempts, as was creating a lot of database writes for people regex groups with posts without part numbering. - //$db->exec(sprintf("update binaries set procattempts = procattempts + 1 where relname = %s and procstat = %d and groupID = %d and fromname=%s", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) )); - } - if ($retcount % 100 == 0) - echo "."; - } - - $retcount = 0; - } - - public function processReleasesStage3($groupID) - { - $minsizecounts = $maxsizecounts = $minfilecounts = 0; - - // Set table names - if ($this->tablepergroup === 1) { - if ($groupID == '') { - exit($this->c->error("\nYou are using 'tablepergroup', you must use releases_threaded.py")); - } - $group['cname'] = 'collections_' . $groupID; - $group['bname'] = 'binaries_' . $groupID; - $group['pname'] = 'parts_' . $groupID; - } else { - $group['cname'] = 'collections'; - $group['bname'] = 'binaries'; - $group['pname'] = 'parts'; - } - - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 3 -> Creating releases from complete binaries.")); - } - $stage3 = TIME(); - - if ($groupID == '') { - $groupIDs = $this->groups->getActiveIDs(); - foreach ($groupIDs as $groupID) { - $res = $this->db->query( - 'SELECT ID FROM ' . $group['cname'] . ' WHERE filecheck = 3 AND filesize > 0 AND groupID = ' . - $groupID['ID'] - ); - if (count($res) > 0) { - $minsizecount = 0; - if (DB_TYPE === 'mysql') { - $mscq = $this->db->exec( - "UPDATE " . $group['cname'] . - " c LEFT JOIN (SELECT g.ID, COALESCE(g.minsizetoformrelease, s.minsizetoformrelease) AS minsizetoformrelease FROM groups g INNER JOIN ( SELECT value AS minsizetoformrelease FROM settings WHERE setting = 'minsizetoformrelease' ) s ) g ON g.ID = c.groupID SET c.filecheck = 5 WHERE g.minsizetoformrelease != 0 AND c.filecheck = 3 AND c.filesize < g.minsizetoformrelease AND c.filesize > 0 AND groupID = " . - $groupID['ID'] - ); - if ($mscq !== false) { - $minsizecount = $mscq->rowCount(); - } - } else { - $s = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minsizetoformrelease::integer) as size FROM settings s, groups g WHERE s.setting = 'minsizetoformrelease' AND g.ID = " . - $groupID['ID'] - ); - if ($s['size'] > 0) { - $mscq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND filesize < %d AND filesize > 0 AND groupID = ' . - $groupID['ID'], $s['size'] - ) - ); - if ($mscq !== false) { - $minsizecount = $mscq->rowCount(); - } - } - } - if ($minsizecount < 1) { - $minsizecount = 0; - } - $minsizecounts = $minsizecount + $minsizecounts; - - $maxfilesizeres = $this->db->queryOneRow("SELECT value FROM settings WHERE setting = 'maxsizetoformrelease'"); - if ($maxfilesizeres['value'] != 0) { - $mascq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND groupID = %d AND filesize > %d ', $groupID['ID'], $maxfilesizeres['value'] - ) - ); - $maxsizecount = 0; - if ($mascq !== false) { - $maxsizecount = $mascq->rowCount(); - } - if ($maxsizecount < 1) { - $maxsizecount = 0; - } - $maxsizecounts = $maxsizecount + $maxsizecounts; - } - - $minfilecount = 0; - if (DB_TYPE === 'mysql') { - $mifcq = $this->db->exec( - "UPDATE " . $group['cname'] . - " c LEFT JOIN (SELECT g.ID, COALESCE(g.minfilestoformrelease, s.minfilestoformrelease) AS minfilestoformrelease FROM groups g INNER JOIN ( SELECT value AS minfilestoformrelease FROM settings WHERE setting = 'minfilestoformrelease' ) s ) g ON g.ID = c.groupID SET c.filecheck = 5 WHERE g.minfilestoformrelease != 0 AND c.filecheck = 3 AND c.totalfiles < g.minfilestoformrelease AND groupID = " . - $groupID['ID'] - ); - if ($mifcq !== false) { - $minfilecount = $mifcq->rowCount(); - } - } else { - $f = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minfilestoformrelease::integer) as files FROM settings s, groups g WHERE s.setting = 'minfilestoformrelease' AND g.ID = " . - $groupID['ID'] - ); - if ($f['files'] > 0) { - $mifcq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND filesize < %d AND filesize > 0 AND groupID = ' . - $groupID['ID'], $s['size'] - ) - ); - if ($mifcq !== false) { - $minfilecount = $mifcq->rowCount(); - } - } - } - if ($minfilecount < 1) { - $minfilecount = 0; - } - $minfilecounts = $minfilecount + $minfilecounts; - } - } - } else { - $res = $this->db->queryDirect( - 'SELECT ID FROM ' . $group['cname'] . ' WHERE filecheck = 3 AND filesize > 0 AND groupID = ' . $groupID - ); - if ($res !== false && $res->rowCount() > 0) { - $minsizecount = 0; - if (DB_TYPE === 'mysql') { - $mscq = $this->db->exec( - "UPDATE " . $group['cname'] . - " c LEFT JOIN (SELECT g.ID, coalesce(g.minsizetoformrelease, s.minsizetoformrelease) AS minsizetoformrelease FROM groups g INNER JOIN ( SELECT value AS minsizetoformrelease FROM settings WHERE setting = 'minsizetoformrelease' ) s ) g ON g.ID = c.groupID SET c.filecheck = 5 WHERE g.minsizetoformrelease != 0 AND c.filecheck = 3 AND c.filesize < g.minsizetoformrelease AND c.filesize > 0 AND groupID = " . - $groupID - ); - if ($mscq !== false) { - $minsizecount = $mscq->rowCount(); - } - } else { - $s = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minsizetoformrelease::integer) as size FROM settings s, groups g WHERE s.setting = 'minsizetoformrelease' AND g.ID = " . - $groupID - ); - if ($s['size'] > 0) { - $mscq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND filesize < %d AND filesize > 0 AND groupID = ' . - $groupID, $s['size'] - ) - ); - if ($mscq !== false) { - $minsizecount = $mscq->rowCount(); - } - } - } - if ($minsizecount < 0) { - $minsizecount = 0; - } - $minsizecounts = $minsizecount + $minsizecounts; - - $maxfilesizeres = $this->db->queryOneRow("SELECT value FROM settings WHERE setting = 'maxsizetoformrelease'"); - if ($maxfilesizeres['value'] != 0) { - $mascq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND filesize > %d ', $maxfilesizeres['value'] - ) - ); - if ($mascq !== false) { - $maxsizecount = $mascq->rowCount(); - } - if ($maxsizecount < 0) { - $maxsizecount = 0; - } - $maxsizecounts = $maxsizecount + $maxsizecounts; - } - - $minfilecount = 0; - if (DB_TYPE === 'mysql') { - $mifcq = $this->db->exec( - "UPDATE " . $group['cname'] . - " c LEFT JOIN (SELECT g.ID, coalesce(g.minfilestoformrelease, s.minfilestoformrelease) AS minfilestoformrelease FROM groups g INNER JOIN ( SELECT value AS minfilestoformrelease FROM settings WHERE setting = 'minfilestoformrelease' ) s ) g ON g.ID = c.groupID SET c.filecheck = 5 WHERE g.minfilestoformrelease != 0 AND c.filecheck = 3 AND c.totalfiles < g.minfilestoformrelease AND groupID = " . - $groupID - ); - if ($mifcq !== false) { - $minfilecount = $mifcq->rowCount(); - } - } else { - $f = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minfilestoformrelease::integer) as files FROM settings s, groups g WHERE s.setting = 'minfilestoformrelease' AND g.ID = " . - $groupID - ); - if ($f['files'] > 0) { - $mifcq = $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE filecheck = 3 AND filesize < %d AND filesize > 0 AND groupID = ' . - $groupID, $s['size'] - ) - ); - if ($mifcq !== false) { - $minfilecount = $mifcq->rowCount(); - } - } - } - if ($minfilecount < 0) { - $minfilecount = 0; - } - $minfilecounts = $minfilecount + $minfilecounts; - } - } - - $delcount = $minsizecounts + $maxsizecounts + $minfilecounts; - if ($this->echooutput && $delcount > 0) { - $this->c->doEcho( - $this->c->primary( - 'Deleted ' . - number_format($delcount) . - " collections smaller/larger than group/site settings." - ) - ); - } - if ($this->echooutput) { - $this->c->doEcho($this->c->primary($this->consoleTools->convertTime(TIME() - $stage3)), true); - } - } - - public function processReleasesStage4($groupID) - { - $categorize = new Category(); - $retcount = $duplicate = 0; - $where = (!empty($groupID)) ? ' groupID = ' . $groupID . ' AND ' : ' '; - - // Set table names - if ($this->tablepergroup === 1) { - if ($groupID == '') { - exit($this->c->error("\nYou are using 'tablepergroup', you must use releases_threaded.py")); - } - $group['cname'] = 'collections_' . $groupID; - $group['bname'] = 'binaries_' . $groupID; - $group['pname'] = 'parts_' . $groupID; - } else { - $group['cname'] = 'collections'; - $group['bname'] = 'binaries'; - $group['pname'] = 'parts'; - } - - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 4 -> Create releases.")); - } - $stage4 = TIME(); - $rescol = $this->db->queryDirect( - 'SELECT ' . $group['cname'] . '.*, groups.name AS gname FROM ' . $group['cname'] . - ' INNER JOIN groups ON ' . $group['cname'] . '.groupID = groups.ID WHERE' . $where . - 'filecheck = 3 AND filesize > 0 LIMIT ' . $this->stage5limit - ); - if ($rescol !== false && $this->echooutput) { - echo $this->c->primary($rescol->rowCount() . " Collections ready to be converted to releases."); - } - - if ($rescol !== false && $rescol->rowCount() > 0) { - $predb = new PreDb($this->echooutput); - foreach ($rescol as $rowcol) { - $propername = true; - $relid = false; - $cleanRelName = str_replace(array('#', '@', '$', '%', '^', '§', '¨', '©', 'Ö'), '', $rowcol['subject']); - $cleanerName = $this->releaseCleaning->releaseCleaner($rowcol['subject'], $rowcol['fromname'], $rowcol['filesize'], $rowcol['gname']); - /* $ncarr = $this->collectionsCleaning->collectionsCleaner($subject, $rowcol['gname']); - $cleanerName = $ncarr['subject']; - $category = $ncarr['cat']; - $relstat = $ncar['rstatus']; */ - $fromname = trim($rowcol['fromname'], "'"); - if (!is_array($cleanerName)) { - $cleanName = $cleanerName; - } else { - $cleanName = $cleanerName['cleansubject']; - $propername = $cleanerName['properlynamed']; - } - $relguid = sha1(uniqid('', true) . mt_rand()); - - $category = $categorize->determineCategory($cleanName, $rowcol['groupID']); - $cleanRelName = utf8_encode($cleanRelName); - $cleanName = utf8_encode($cleanName); - $fromname = utf8_encode($fromname); - - // Look for duplicates, duplicates match on releases.name, releases.fromname and releases.size - // A 1% variance in size is considered the same size when the subject and poster are the same - $minsize = $rowcol['filesize'] * .99; - $maxsize = $rowcol['filesize'] * 1.01; - - $dupecheck = $this->db->queryOneRow(sprintf('SELECT ID, guid FROM releases WHERE name = %s AND fromname = %s AND size BETWEEN %s AND %s', $this->db->escapeString($cleanRelName), $this->db->escapeString($fromname), $this->db->escapeString($minsize), $this->db->escapeString($maxsize))); - if (!$dupecheck) { - if ($propername == true) { - $relid = $this->db->queryInsert( - sprintf( - 'INSERT INTO releases - (name, searchname, totalpart, groupID, adddate, guid, rageID, postdate, fromname, - size, passwordstatus, haspreview, categoryID, nfostatus, isrenamed, iscategorized) - VALUES - (%s, %s, %d, %d, NOW(), %s, -1, %s, %s, %s, %d, -1, %d, -1, 1, 1)', - $this->db->escapeString($cleanRelName), - $this->db->escapeString($cleanName), - $rowcol['totalfiles'], - $rowcol['groupID'], - $this->db->escapeString($relguid), - $this->db->escapeString($rowcol['date']), - $this->db->escapeString($fromname), - $this->db->escapeString($rowcol['filesize']), - ($this->site->checkpasswordedrar == '1' ? -1 : 0), - $category - ) - ); - } else { - $relid = $this->db->queryInsert( - sprintf( - 'INSERT INTO releases - (name, searchname, totalpart, groupID, adddate, guid, rageID, postdate, fromname, - size, passwordstatus, haspreview, categoryID, nfostatus, iscategorized) - VALUES (%s, %s, %d, %d, NOW(), %s, -1, %s, %s, %s, %d, -1, %d, -1, 1)', - $this->db->escapeString($cleanRelName), - $this->db->escapeString($cleanName), - $rowcol['totalfiles'], - $rowcol['groupID'], - $this->db->escapeString($relguid), - $this->db->escapeString($rowcol['date']), - $this->db->escapeString($fromname), - $this->db->escapeString($rowcol['filesize']), - ($this->site->checkpasswordedrar == '1' ? -1 : 0), - $category - ) - ); - } - } - - if ($relid) { - // try to match to predb here - $predb->matchPre($cleanRelName, $relid); - - // Update collections table to say we inserted the release. - $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 4, releaseID = %d WHERE ID = %d', $relid, $rowcol['ID'] - ) - ); - $retcount++; - if ($this->echooutput) { - echo $this->c->primary('Added release ' . $cleanName); - } - } else if (isset($relid) && $relid == false) { - $this->db->exec( - sprintf( - 'UPDATE ' . $group['cname'] . - ' SET filecheck = 5 WHERE collectionhash = %s', $this->db->escapeString($rowcol['collectionhash']) - ) - ); - $duplicate++; - } - } - } - - if ($this->echooutput) { - $this->c->doEcho( - $this->c->primary( - number_format($retcount) . - ' Releases added and ' . - number_format($duplicate) . - ' marked for deletion in ' . - $this->consoleTools->convertTime(TIME() - $stage4) - ), true - ); - } - - return $retcount; - } - - /* - * Adding this in to delete releases before NZB's are created. - */ - - public function processReleasesStage4dot5($groupID) - { - $minsizecount = $maxsizecount = $minfilecount = $catminsizecount = 0; - - if ($this->echooutput) { - echo $this->c->header("Stage 4.5 -> Delete releases smaller/larger than minimum size/file count from group/site setting."); - } - - $stage4dot5 = TIME(); - // Delete smaller than min sizes - $catresrel = $this->db->queryDirect('SELECT c.ID AS id, CASE WHEN c.minsize = 0 THEN cp.minsize ELSE c.minsize END AS minsize FROM category c INNER JOIN category cp ON cp.ID = c.parentID WHERE c.parentID IS NOT NULL'); - foreach ($catresrel as $catrowrel) { - if ($catrowrel['minsize'] > 0) { - //printf("SELECT r.id, r.guid FROM releases r WHERE r.categoryID = %d AND r.size < %d\n", $catrowrel['ID'], $catrowrel['minsize']); - $resrel = $this->db->queryDirect(sprintf('SELECT r.id, r.guid FROM releases r WHERE r.categoryID = %d AND r.size < %d', $catrowrel['ID'], $catrowrel['minsize'])); - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $catminsizecount++; - } - } - } - - // Delete larger than max sizes - if ($groupID == '') { - $groupIDs = $this->groups->getActiveIDs(); - - foreach ($groupIDs as $groupID) { - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf("SELECT r.id, r.guid FROM releases r LEFT JOIN (SELECT g.ID, coalesce(g.minsizetoformrelease, s.minsizetoformrelease) AS minsizetoformrelease FROM groups g INNER JOIN ( SELECT value as minsizetoformrelease FROM settings WHERE setting = 'minsizetoformrelease' ) s WHERE g.ID = %s ) g ON g.ID = r.groupID WHERE g.minsizetoformrelease != 0 AND r.size < minsizetoformrelease AND r.groupID = %s", $groupID['ID'], $groupID['ID'])); - } else { - $resrel = array(); - $s = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minsizetoformrelease::integer) as size FROM settings s, groups g WHERE s.setting = 'minsizetoformrelease' AND g.ID = " . - $groupID['ID'] - ); - if ($s['size'] > 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE size < %d AND groupID = %d', $s['size'], $groupID['ID'])); - } - } - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $minsizecount++; - } - } - - $maxfilesizeres = $this->db->queryOneRow("SELECT value FROM settings WHERE setting = 'maxsizetoformrelease'"); - if ($maxfilesizeres['value'] != 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE groupID = %d AND size > %d', $groupID['ID'], $maxfilesizeres['value'])); - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $maxsizecount++; - } - } - } - - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf("SELECT r.id, r.guid FROM releases r LEFT JOIN (SELECT g.ID, coalesce(g.minfilestoformrelease, s.minfilestoformrelease) as minfilestoformrelease FROM groups g INNER JOIN ( SELECT value as minfilestoformrelease FROM settings WHERE setting = 'minfilestoformrelease' ) s WHERE g.ID = %d ) g ON g.ID = r.groupID WHERE g.minfilestoformrelease != 0 AND r.totalpart < minfilestoformrelease AND r.groupID = %d", $groupID['ID'], $groupID['ID'])); - } else { - $resrel = array(); - $f = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minfilestoformrelease::integer) as files FROM settings s, groups g WHERE s.setting = 'minfilestoformrelease' AND g.ID = " . - $groupID['ID'] - ); - if ($f['files'] > 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE totalpart < %d AND groupID = %d', $f['files'], $groupID['ID'])); - } - } - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $minfilecount++; - } - } - } - } else { - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf("SELECT r.id, r.guid FROM releases r LEFT JOIN (SELECT g.ID, coalesce(g.minsizetoformrelease, s.minsizetoformrelease) AS minsizetoformrelease FROM groups g INNER JOIN ( SELECT value AS minsizetoformrelease FROM settings WHERE setting = 'minsizetoformrelease' ) s WHERE g.ID = %d ) g ON g.ID = r.groupID WHERE g.minsizetoformrelease != 0 AND r.size < minsizetoformrelease AND r.groupID = %d", $groupID, $groupID)); - } else { - $resrel = array(); - $s = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minsizetoformrelease::integer) as size FROM settings s, groups g WHERE s.setting = 'minsizetoformrelease' AND g.ID = " . - $groupID - ); - if ($s['size'] > 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE size < %d AND groupID = %d', $s['size'], $groupID)); - } - } - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $minsizecount++; - } - } - - $maxfilesizeres = $this->db->queryOneRow("SELECT value FROM settings WHERE setting = 'maxsizetoformrelease'"); - if ($maxfilesizeres['value'] != 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE groupID = %d AND size > %s', $groupID, $this->db->escapeString($maxfilesizeres['value']))); - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $maxsizecount++; - } - } - } - - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf("SELECT r.id, r.guid FROM releases r LEFT JOIN (SELECT g.ID, coalesce(g.minfilestoformrelease, s.minfilestoformrelease) AS minfilestoformrelease FROM groups g INNER JOIN ( SELECT value AS minfilestoformrelease FROM settings WHERE setting = 'minfilestoformrelease' ) s WHERE g.ID = %d ) g ON g.ID = r.groupID WHERE g.minfilestoformrelease != 0 AND r.totalpart < minfilestoformrelease AND r.groupID = %d", $groupID, $groupID)); - } else { - $resrel = array(); - $f = $this->db->queryOneRow( - "SELECT GREATEST(s.value::integer, g.minfilestoformrelease::integer) as files FROM settings s, groups g WHERE s.setting = 'minfilestoformrelease' AND g.ID = " . - $groupID - ); - if ($f['files'] > 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE totalpart < %d AND groupID = %d', $f['files'], $groupID)); - } - } - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $minfilecount++; - } - } - } - - $delcount = $minsizecount + $maxsizecount + $minfilecount + $catminsizecount; - if ($this->echooutput && $delcount > 0) { - $this->c->doEcho( - $this->c->primary( - 'Deleted ' . - number_format($delcount) . - " releases smaller/larger than group/site settings." - ) - ); - } - if ($this->echooutput) { - $this->c->doEcho($this->c->primary($this->consoleTools->convertTime(TIME() - $stage4dot5)), true); - } - } - - public function processReleasesStage5($groupID) - { - $nzbcount = $reccount = 0; - $where = (!empty($groupID)) ? ' r.groupID = ' . $groupID . ' AND ' : ' '; - - // Set table names - if ($this->tablepergroup === 1) { - if ($groupID == '') { - exit($this->c->error("\nYou are using 'tablepergroup', you must use releases_threaded.py")); - } - $group['cname'] = 'collections_' . $groupID; - $group['bname'] = 'binaries_' . $groupID; - $group['pname'] = 'parts_' . $groupID; - } else { - $group['cname'] = 'collections'; - $group['bname'] = 'binaries'; - $group['pname'] = 'parts'; - } - - // Create NZB. - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 5 -> Create the NZB, mark collections as ready for deletion.")); - } - - $stage5 = TIME(); - $resrel = $this->db->queryDirect( - "SELECT CONCAT(COALESCE(cp.title,'') , CASE WHEN cp.title IS NULL THEN '' ELSE ' > ' END , c.title) AS title, r.name, r.id, r.guid FROM releases r INNER JOIN category c ON r.categoryID = c.ID INNER JOIN category cp ON cp.ID = c.parentID WHERE" . - $where . "nzbstatus = 0" - ); - $total = 0; - if ($resrel !== false) { - $total = $resrel->rowCount(); - } - if ($total > 0) { - $nzb = new Enzebe(); - // Init vars for writing the NZB's. - $nzb->initiateForWrite($this->db, htmlspecialchars(date('F j, Y, g:i a O'), ENT_QUOTES, 'utf-8'), $groupID); - foreach ($resrel as $rowrel) { - $nzb_create = $nzb->writeNZBforreleaseID($rowrel['ID'], $rowrel['guid'], $rowrel['name'], $rowrel['title']); - if ($nzb_create !== false) { - $this->db->exec( - sprintf( - 'UPDATE %s SET filecheck = 5 WHERE releaseID = %s', $group['cname'], $rowrel['ID'] - ) - ); - $nzbcount++; - if ($this->echooutput) { - echo $this->consoleTools->overWritePrimary( - 'Creating NZBs: ' . $this->consoleTools->percentString($nzbcount, $total) - ); - } - } - } - // Reset vars for next use. - $nzb->cleanForWrite(); - } - - $timing = $this->c->primary($this->consoleTools->convertTime(TIME() - $stage5)); - if ($this->echooutput) { - $this->c->doEcho( - $this->c->primary( - number_format($nzbcount) . - ' NZBs created in ' . - $timing - ) - ); - } - - return $nzbcount; - } - - /** - * Process RequestID's. - * - * @param int $groupID - */ - public function processReleasesStage5b($groupID) - { - if ($this->site->lookup_reqids == 1 || $this->site->lookup_reqids == 2) { - $category = new Category(); - $iFoundCnt = 0; - $stage8 = TIME(); - - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 5b -> Request ID lookup. ")); - } - - // Look for records that potentially have requestID titles and have not been renamed by any other means - $resRel = $this->db->queryDirect( - sprintf(" - SELECT r.id, r.name, r.searchname, g.name AS groupname - FROM releases r - LEFT JOIN groups g ON r.groupID = g.ID - WHERE r.groupID = %d - AND nzbstatus = 1 - AND isrenamed = 0 - AND (isrequestid = 1 AND reqidstatus in (%d, %d) OR (reqidstatus = %d AND adddate > NOW() - INTERVAL %d HOUR)) - LIMIT 100", - $groupID, - self::REQID_UPROC, - self::REQID_BAD, - self::REQID_NONE, - (isset($this->site->request_hours) ? (int)$this->site->request_hours : 1) - ) - ); - - if ($resRel !== false && $resRel->rowCount() > 0) { - $newTitle = false; - $web = (!empty($this->site->request_url) && - (nzedb\utility\getUrl($this->site->request_url) === false ? false : true)); - - foreach ($resRel as $rowRel) { - $newTitle = $local = false; - - // Try to get request id. - if (preg_match('/\[\s*(\d+)\s*\]/', $rowRel['name'], $requestID)) { - $requestID = (int)$requestID[1]; - } else { - $requestID = 0; - } - - if ($requestID === 0) { - $this->db->exec( - sprintf(' - UPDATE releases - SET reqidstatus = %d - WHERE ID = %d', - self::REQID_ZERO, - $rowRel['ID'] - ) - ); - } else { - - // Do a local lookup first. - $run = $this->db->queryOneRow( - sprintf(" - SELECT title - FROM predb - WHERE requestid = %d - AND groupID = %d", - $requestID, $groupID - ) - ); - if ($run !== false) { - $newTitle = $run['title']; - $local = true; - $iFoundCnt++; - - // Do a web lookup. - } else if ($web !== false) { - $xml = @simplexml_load_file( - str_ireplace( - '[REQUEST_ID]', - $requestID, - str_ireplace( - '[GROUP_NM]', - urlencode($rowRel['groupname']), - $this->site->request_url - ) - ) - ); - if ($xml !== false && - isset($xml->request[0]['name']) && !empty($xml->request[0]['name']) && - strtolower($xml->request[0]['name']) !== strtolower($rowRel['searchname']) - ) { - $newTitle = $xml->request[0]['name']; - $iFoundCnt++; - } - } - } - - if ($newTitle !== false) { - - $determinedCat = $category->determineCategory($newTitle, $groupID); - $this->db->exec( - sprintf(' - UPDATE releases - SET reqidstatus = %d, isrenamed = 1, proc_files = 1, searchname = %s, categoryID = %d - WHERE ID = %d', - self::REQID_FOUND, - $this->db->escapeString($newTitle), - $determinedCat, - $rowRel['ID'] - ) - ); - - if ($this->echooutput) { - echo $this->c->primary( - "\n\nNew name: $newTitle" . - "\nOld name: " . $rowRel['searchname'] . - "\nNew cat: " . $category->getNameByID($determinedCat) . - "\nGroup: " . $rowRel['groupname'] . - "\nMethod: " . ($local === true ? 'requestID local' : 'requestID web') . - "\nreleaseID: " . $rowRel['ID'] - ); - } - } else { - $this->db->exec( - sprintf( - 'UPDATE releases SET reqidstatus = %d WHERE ID = %d', - self::REQID_NONE, - $rowRel['ID'] - ) - ); - } - } - if ($this->echooutput && $newTitle !== false) { - echo "\n"; - } - } - - if ($this->echooutput) { - $this->c->doEcho( - $this->c->primary( - number_format($iFoundCnt) . - ' Releases updated in ' . - $this->consoleTools->convertTime(TIME() - $stage8) - ), true - ); - } - } - } - - public function processReleasesStage6($categorize, $postproc, $groupID, $nntp) - { - $where = (!empty($groupID)) ? 'WHERE iscategorized = 0 AND groupID = ' . $groupID : 'WHERE iscategorized = 0'; - - // Categorize releases. - if ($this->echooutput) { - echo $this->c->header("Stage 6 -> Categorize and post process releases."); - } - $stage6 = TIME(); - if ($categorize == 1) { - $this->categorizeRelease('name', $where); - } - - if ($postproc == 1) { - $postprocess = new PostProcess($this->echooutput); - $postprocess->processAll($nntp); - } else { - if ($this->echooutput) { - $this->c->doEcho( - $this->c->info( - "\nPost-processing is not running inside the releases.php file.\n" . - "If you are using tmux or screen they might have their own files running Post-processing." - ) - ); - } - } - if ($this->echooutput) { - $this->c->doEcho($this->c->primary($this->consoleTools->convertTime(TIME() - $stage6)), true); - } - } - - public function processReleasesStage7a($groupID) - { - $reccount = $delq = 0; - $where = ' '; - $where1 = ''; - - // Set table names - if ($this->tablepergroup === 1) { - if ($groupID == '') { - exit($this->c->error("\nYou are using 'tablepergroup', you must use releases_threaded.py")); - } - $group['cname'] = 'collections_' . $groupID; - $group['bname'] = 'binaries_' . $groupID; - $group['pname'] = 'parts_' . $groupID; - } else { - $group['cname'] = 'collections'; - $group['bname'] = 'binaries'; - $group['pname'] = 'parts'; - $where = (!empty($groupID)) ? ' ' . $group['cname'] . '.groupID = ' . $groupID . ' AND ' : ' '; - $where1 = (!empty($groupID)) ? ' AND ' . $group['cname'] . '.groupID = ' . $groupID : ''; - } - - // Delete old releases and finished collections. - if ($this->echooutput) { - echo $this->c->header("Stage 7a -> Delete finished collections."); - } - $stage7 = TIME(); - - // Completed releases and old collections that were missed somehow. - if (DB_TYPE === 'mysql') { - $delq = $this->db->exec( - sprintf( - 'DELETE ' . $group['cname'] . ', ' . $group['bname'] . ', ' . $group['pname'] . ' FROM ' . - $group['cname'] . ', ' . $group['bname'] . ', ' . $group['pname'] . ' WHERE' . $where . - $group['cname'] . '.filecheck = 5 AND ' . $group['cname'] . '.id = ' . $group['bname'] . - '.collectionid AND ' . $group['bname'] . '.id = ' . $group['pname'] . '.binaryid' - ) - ); - if ($delq !== false) { - $reccount += $delq->rowCount(); - } - } else { - $idr = $this->db->queryDirect('SELECT ID FROM ' . $group['cname'] . ' WHERE filecheck = 5 ' . $where); - if ($idr !== false && $idr->rowCount() > 0) { - foreach ($idr as $id) { - $delqa = $this->db->exec( - sprintf( - 'DELETE FROM ' . $group['pname'] . ' WHERE EXISTS (SELECT ID FROM ' . $group['bname'] . - ' WHERE ' . $group['bname'] . '.id = ' . $group['pname'] . '.binaryid AND ' . - $group['bname'] . '.collectionid = %d)', $id['ID'] - ) - ); - if ($delqa !== false) { - $reccount += $delqa->rowCount(); - } - $delqb = $this->db->exec( - sprintf( - 'DELETE FROM ' . $group['bname'] . ' WHERE collectionid = %d', $id['ID'] - ) - ); - if ($delqb !== false) { - $reccount += $delqb->rowCount(); - } - } - $delqc = $this->db->exec('DELETE FROM ' . $group['cname'] . ' WHERE filecheck = 5 ' . $where); - if ($delqc !== false) { - $reccount += $delqc->rowCount(); - } - } - } - - // Old collections that were missed somehow. - if (DB_TYPE === 'mysql') { - $delq = $this->db->exec( - sprintf( - 'DELETE ' . $group['cname'] . ', ' . $group['bname'] . ', ' . $group['pname'] . ' FROM ' . - $group['cname'] . ', ' . $group['bname'] . ', ' . $group['pname'] . ' WHERE ' . $group['cname'] . - '.dateadded < (NOW() - INTERVAL %d HOUR) AND ' . $group['cname'] . '.id = ' . $group['bname'] . - '.collectionid AND ' . $group['bname'] . '.id = ' . $group['pname'] . '.binaryid' . - $where1, $this->site->partretentionhours - ) - ); - if ($delq !== false) { - $reccount += $delq->rowCount(); - } - } else { - $idr = $this->db->queryDirect( - sprintf( - "SELECT ID FROM " . $group['cname'] . " WHERE dateadded < (NOW() - INTERVAL '%d HOURS')" . - $where1, $this->site->partretentionhours - ) - ); - - if ($idr !== false && $idr->rowCount() > 0) { - foreach ($idr as $id) { - $delqa = $this->db->exec( - sprintf( - 'DELETE FROM ' . $group['pname'] . ' WHERE EXISTS (SELECT ID FROM ' . $group['bname'] . - ' WHERE ' . $group['bname'] . '.id = ' . $group['pname'] . '.binaryid AND ' . - $group['bname'] . '.collectionid = %d)', $id['ID'] - ) - ); - if ($delqa !== false) { - $reccount += $delqa->rowCount(); - } - $delqb = $this->db->exec( - sprintf( - 'DELETE FROM ' . $group['bname'] . ' WHERE collectionid = %d', $id['ID'] - ) - ); - if ($delqb !== false) { - $reccount += $delqb->rowCount(); - } - } - } - $delqc = $this->db->exec( - sprintf( - "DELETE FROM " . $group['cname'] . " WHERE dateadded < (NOW() - INTERVAL '%d HOURS')" . - $where1, $this->site->partretentionhours - ) - ); - if ($delqc !== false) { - $reccount += $delqc->rowCount(); - } - } - - // Binaries/parts that somehow have no collection. - if (DB_TYPE === 'mysql') { - $delqd = $this->db->exec( - 'DELETE ' . $group['bname'] . ', ' . $group['pname'] . ' FROM ' . $group['bname'] . ', ' . - $group['pname'] . ' WHERE ' . $group['bname'] . '.collectionid = 0 AND ' . $group['bname'] . '.id = ' . - $group['pname'] . '.binaryid' - ); - if ($delqd !== false) { - $reccount += $delqd->rowCount(); - } - } else { - $delqe = $this->db->exec( - 'DELETE FROM ' . $group['pname'] . ' WHERE EXISTS (SELECT ID FROM ' . $group['bname'] . ' WHERE ' . - $group['bname'] . '.id = ' . $group['pname'] . '.binaryid AND ' . $group['bname'] . '.collectionid = 0)' - ); - if ($delqe !== false) { - $reccount += $delqe->rowCount(); - } - $delqf = $this->db->exec('DELETE FROM ' . $group['bname'] . ' WHERE collectionid = 0'); - if ($delqf !== false) { - $reccount += $delqf->rowCount(); - } - } - - // Parts that somehow have no binaries. - if (mt_rand(1, 100) % 3 == 0) { - $delqg = $this->db->exec( - 'DELETE FROM ' . $group['pname'] . ' WHERE binaryid NOT IN (SELECT b.id FROM ' . $group['bname'] . ' b)' - ); - if ($delqg !== false) { - $reccount += $delqg->rowCount(); - } - } - - // Binaries that somehow have no collection. - $delqh = $this->db->exec( - 'DELETE FROM ' . $group['bname'] . ' WHERE collectionid NOT IN (SELECT c.ID FROM ' . $group['cname'] . ' c)' - ); - if ($delqh !== false) { - $reccount += $delqh->rowCount(); - } - - // Collections that somehow have no binaries. - $delqi = $this->db->exec( - 'DELETE FROM ' . $group['cname'] . ' WHERE ' . $group['cname'] . '.id NOT IN (SELECT ' . $group['bname'] . - '.collectionid FROM ' . $group['bname'] . ') ' . $where1 - ); - if ($delqi !== false) { - $reccount += $delqi->rowCount(); - } - - if ($this->echooutput) { - $this->c->doEcho( - $this->c->primary( - 'Removed ' . - number_format($reccount) . - ' parts/binaries/collection rows in ' . - $this->consoleTools->convertTime(TIME() - $stage7) - ) - ); - } - } - - // Queries that are not per group - public function processReleasesStage7b() - { - $category = new Category(); - $genres = new Genres(); - $remcount = $reccount = $passcount = $dupecount = $relsizecount = $completioncount = $disabledcount = $disabledgenrecount = $miscothercount = $total = 0; - - // Delete old releases and finished collections. - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 7b -> Delete old releases and passworded releases.")); - } - $stage7 = TIME(); - - // Releases past retention. - if ($this->site->releaseretentiondays != 0) { - if (DB_TYPE === 'mysql') { - $result = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE postdate < (NOW() - INTERVAL %d DAY)', $this->site->releaseretentiondays)); - } else { - $result = $this->db->queryDirect(sprintf("SELECT ID, guid FROM releases WHERE postdate < (NOW() - INTERVAL '%d DAYS')", $this->site->releaseretentiondays)); - } - if ($result !== false && $result->rowCount() > 0) { - foreach ($result as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $remcount++; - } - } - } - - // Passworded releases. - if ($this->site->deletepasswordedrelease == 1) { - $result = $this->db->queryDirect( - 'SELECT ID, guid FROM releases WHERE passwordstatus = ' . Releases::PASSWD_RAR - ); - if ($result !== false && $result->rowCount() > 0) { - foreach ($result as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $passcount++; - } - } - } - - // Possibly passworded releases. - if ($this->site->deletepossiblerelease == 1) { - $result = $this->db->queryDirect( - 'SELECT ID, guid FROM releases WHERE passwordstatus = ' . Releases::PASSWD_POTENTIAL - ); - if ($result !== false && $result->rowCount() > 0) { - foreach ($result as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $passcount++; - } - } - } - - // Crossposted releases. - do { - if ($this->crosspostt != 0) { - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE adddate > (NOW() - INTERVAL %d HOUR) GROUP BY name HAVING COUNT(name) > 1', $this->crosspostt)); - } else { - $resrel = $this->db->queryDirect(sprintf("SELECT ID, guid FROM releases WHERE adddate > (NOW() - INTERVAL '%d HOURS') GROUP BY name, id HAVING COUNT(name) > 1", $this->crosspostt)); - } - $total = 0; - if ($resrel !== false) { - $total = $resrel->rowCount(); - } - if ($total > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $dupecount++; - } - } - } - } while ($total > 0); - - // Releases below completion %. - if ($this->completion > 100) { - $this->completion = 100; - echo $this->c->error("\nYou have an invalid setting for completion."); - } - if ($this->completion > 0) { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE completion < %d AND completion > 0', $this->completion)); - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $completioncount++; - } - } - } - - // Disabled categories. - $catlist = $category->getDisabledIDs(); - if (count($catlist) > 0) { - foreach ($catlist as $cat) { - $res = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE categoryID = %d', $cat['ID'])); - if ($res !== false && $res->rowCount() > 0) { - foreach ($res as $rel) { - $disabledcount++; - $this->fastDelete($rel['ID'], $rel['guid']); - } - } - } - } - - // Disabled music genres. - $genrelist = $genres->getDisabledIDs(); - if (count($genrelist) > 0) { - foreach ($genrelist as $genre) { - $rels = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases INNER JOIN (SELECT ID AS mid FROM musicinfo WHERE musicinfo.genreID = %d) mi ON releases.musicinfoID = mid', $genre['ID'])); - if ($rels !== false && $rels->rowCount() > 0) { - foreach ($rels as $rel) { - $disabledgenrecount++; - $this->fastDelete($rel['ID'], $rel['guid']); - } - } - } - } - - // Misc other. - if ($this->site->miscotherretentionhours > 0) { - if (DB_TYPE === 'mysql') { - $resrel = $this->db->queryDirect(sprintf('SELECT ID, guid FROM releases WHERE categoryID = %d AND adddate <= NOW() - INTERVAL %d HOUR', CATEGORY::CAT_MISC, $this->site->miscotherretentionhours)); - } else { - $resrel = $this->db->queryDirect(sprintf("SELECT ID, guid FROM releases WHERE categoryID = %d AND adddate <= NOW() - INTERVAL '%d HOURS'", CATEGORY::CAT_MISC, $this->site->miscotherretentionhours)); - } - if ($resrel !== false && $resrel->rowCount() > 0) { - foreach ($resrel as $rowrel) { - $this->fastDelete($rowrel['ID'], $rowrel['guid']); - $miscothercount++; - } - } - } - - if (DB_TYPE === 'mysql') { - $this->db->exec(sprintf('DELETE FROM nzbs WHERE dateadded < (NOW() - INTERVAL %d HOUR)', $this->site->partretentionhours)); - } else { - $this->db->exec(sprintf("DELETE FROM nzbs WHERE dateadded < (NOW() - INTERVAL '%d HOURS')", $this->site->partretentionhours)); - } - - if ($this->echooutput && $this->completion > 0) { - $this->c->doEcho( - $this->c->primary( - 'Removed releases: ' . - number_format($remcount) . - ' past retention, ' . - number_format($passcount) . - ' passworded, ' . - number_format($dupecount) . - ' crossposted, ' . - number_format($disabledcount) . - ' from disabled categories, ' . - number_format($disabledgenrecount) . - ' from disabled music genres, ' . - number_format($miscothercount) . - ' from misc->other, ' . - number_format($completioncount) . - ' under ' . - $this->completion . - '% completion.' - ) - ); - } else if ($this->echooutput && $this->completion == 0) { - $this->c->doEcho( - $this->c->primary( - 'Removed releases: ' . - number_format($remcount) . - ' past retention, ' . - number_format($passcount) . - ' passworded, ' . - number_format($dupecount) . - ' crossposted, ' . - number_format($disabledcount) . - ' from disabled categories, ' . - number_format($disabledgenrecount) . - ' from disabled music genres, ' . - number_format($miscothercount) . - ' from misc->other' - ) - ); - } - - if ($this->echooutput) { - if ($reccount > 0) { - $this->c->doEcho( - $this->c->primary( - "Removed " . number_format($reccount) . ' parts/binaries/collection rows.' - ) - ); - } - $this->c->doEcho($this->c->primary($this->consoleTools->convertTime(TIME() - $stage7)), true); - } - } - - public function processReleasesStage4567_loop($categorize, $postproc, $groupID, $nntp) - { - $DIR = nZEDb_MISC; - $PYTHON = shell_exec('which python3 2>/dev/null'); - $PYTHON = (empty($PYTHON) ? 'python -OOu' : 'python3 -OOu'); - - $tot_retcount = $tot_nzbcount = $loops = 0; - do { - $retcount = $this->processReleasesStage4($groupID); - $tot_retcount = $tot_retcount + $retcount; - - $nzbcount = $this->processReleasesStage5($groupID); - if ($this->requestids == '1') { - $this->processReleasesStage5b($groupID); - } else if ($this->requestids == '2') { - $stage8 = TIME(); - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Stage 5b -> Request ID Threaded lookup.")); - } - passthru("$PYTHON ${DIR}update/python/requestid_threaded.py"); - if ($this->echooutput) { - $this->c->doEcho( - $this->c->primary( - "\nReleases updated in " . - $this->consoleTools->convertTime(TIME() - $stage8) - ) - ); - } - } - - $tot_nzbcount = $tot_nzbcount + $nzbcount; - $this->processReleasesStage6($categorize, $postproc, $groupID, $nntp); - $this->processReleasesStage7a($groupID); - $loops++; - // This loops as long as there were releases created or 3 loops, otherwise, you could loop indefinately - } while (($nzbcount > 0 || $retcount > 0) && $loops < 3); - - return $tot_retcount; - } - - public function processReleases($categorize, $postproc, $groupName, $nntp, $echooutput) - { - $this->echooutput = $echooutput; - if ($this->hashcheck == 0) { - exit($this->c->error("You must run update_binaries.php to update your collectionhash.\n")); - } - $groupID = ''; - - if (!empty($groupName)) { - $groupInfo = $this->groups->getByName($groupName); - $groupID = $groupInfo['ID']; - } - - $this->processReleases = microtime(true); - if ($this->echooutput) { - $this->c->doEcho($this->c->header("Starting release update process (" . date('Y-m-d H:i:s') . ")"), true); - } - - if (!file_exists($this->site->nzbpath)) { - if ($this->echooutput) { - $this->c->doEcho($this->c->error('Bad or missing nzb directory - ' . $this->site->nzbpath), true); - } - - return; - } - - $this->processReleasesStage1($groupID); - $this->processReleasesStage2($groupID); - $this->processReleasesStage3($groupID); - $releasesAdded = $this->processReleasesStage4567_loop($categorize, $postproc, $groupID, $nntp); - $this->processReleasesStage4dot5($groupID); - $this->processReleasesStage7b(); - $where = (!empty($groupID)) ? ' WHERE groupID = ' . $groupID : ''; - - //Print amount of added releases and time it took. - if ($this->echooutput && $this->tablepergroup == 0) { - $countID = $this->db->queryOneRow('SELECT COUNT(ID) FROM collections ' . $where); - $this->c->doEcho( - $this->c->primary( - 'Completed adding ' . - number_format($releasesAdded) . - ' releases in ' . - $this->consoleTools->convertTime(number_format(microtime(true) - $this->processReleases, 2)) . - '. ' . - number_format(array_shift($countID)) . - ' collections waiting to be created (still incomplete or in queue for creation)' - ), true - ); - } - - return $releasesAdded; - } - - // This resets collections, useful when the namecleaning class's collectioncleaner function changes. - public function resetCollections() - { - $res = $this->db->queryDirect('SELECT b.id as bid, b.name as bname, c.* FROM binaries b LEFT JOIN collections c ON b.collectionid = c.ID'); - if ($res !== false && $res->rowCount() > 0) { - $timestart = TIME(); - if ($this->echooutput) { - echo "Going to remake all the collections. This can be a long process, be patient. DO NOT STOP THIS SCRIPT!\n"; - } - // Reset the collectionhash. - $this->db->exec('UPDATE collections SET collectionhash = 0'); - $delcount = 0; - $cIDS = array(); - foreach ($res as $row) { - - $groupName = $this->groups->getByNameByID($row['groupID']); - $newSHA1 = sha1( - $this->collectionsCleaning->collectionsCleaner( - $row['bname'], - $groupName . - $row['fromname'] . - $row['groupID'] . - $row['totalfiles'] - ) - ); - $cres = $this->db->queryOneRow(sprintf('SELECT ID FROM collections WHERE collectionhash = %s', $this->db->escapeString($newSHA1))); - if (!$cres) { - $cIDS[] = $row['ID']; - $csql = sprintf('INSERT INTO collections (subject, fromname, date, xref, groupID, totalfiles, collectionhash, filecheck, dateadded) VALUES (%s, %s, %s, %s, %d, %s, %s, 0, NOW())', $this->db->escapeString($row['bname']), $this->db->escapeString($row['fromname']), $this->db->escapeString($row['date']), $this->db->escapeString($row['xref']), $row['groupID'], $this->db->escapeString($row['totalfiles']), $this->db->escapeString($newSHA1)); - $collectionID = $this->db->queryInsert($csql); - if ($this->echooutput) { - $this->consoleTools->overWrite( - 'Recreated: ' . count($cIDS) . ' collections. Time:' . - $this->consoleTools->convertTimer(TIME() - $timestart) - ); - } - } else { - $collectionID = $cres['ID']; - } - //Update the binaries with the new info. - $this->db->exec(sprintf('UPDATE binaries SET collectionid = %d WHERE ID = %d', $collectionID, $row['bid'])); - } - //Remove the old collections. - $delstart = TIME(); - if ($this->echooutput) { - echo "\n"; - } - $totalcIDS = count($cIDS); - foreach ($cIDS as $cID) { - $this->db->exec(sprintf('DELETE FROM collections WHERE ID = %d', $cID)); - $delcount++; - if ($this->echooutput) { - $this->consoleTools->overWrite( - 'Deleting old collections:' . $this->consoleTools->percentString($delcount, $totalcIDS) . - ' Time:' . $this->consoleTools->convertTimer(TIME() - $delstart) - ); - } - } - // Delete previous failed attempts. - $this->db->exec('DELETE FROM collections WHERE collectionhash = "0"'); - - if ($this->hashcheck == 0) { - $this->db->exec("UPDATE settings SET value = 1 WHERE setting = 'hashcheck'"); - } - if ($this->echooutput) { - echo "\nRemade " . count($cIDS) . ' collections in ' . - $this->consoleTools->convertTime(TIME() - $timestart) . "\n"; - } - } else { - $this->db->exec("UPDATE settings SET value = 1 WHERE setting = 'hashcheck'"); - } - } - - public function getTopDownloads() - { - return $this->db->query('SELECT ID, searchname, guid, adddate, SUM(grabs) AS grabs FROM releases WHERE grabs > 0 GROUP BY id, searchname, adddate HAVING SUM(grabs) > 0 ORDER BY grabs DESC LIMIT 10'); - } - - public function getTopComments() - { - return $this->db->query('SELECT ID, guid, searchname, adddate, SUM(comments) AS comments FROM releases WHERE comments > 0 GROUP BY id, searchname, adddate HAVING SUM(comments) > 0 ORDER BY comments DESC LIMIT 10'); - } - - public function getRecentlyAdded() - { - if (DB_TYPE === 'mysql') { - return $this->db->query("SELECT CONCAT(cp.title, ' > ', category.title) AS title, COUNT(*) AS count FROM category INNER JOIN category cp on cp.ID = category.parentID INNER JOIN releases ON releases.categoryID = category.id WHERE releases.adddate > NOW() - INTERVAL 1 WEEK GROUP BY concat(cp.title, ' > ', category.title) ORDER BY COUNT(*) DESC"); - } else { - return $this->db->query("SELECT CONCAT(cp.title, ' > ', category.title) AS title, COUNT(*) AS count FROM category INNER JOIN category cp on cp.ID = category.parentID INNER JOIN releases ON releases.categoryID = category.id WHERE releases.adddate > NOW() - INTERVAL '1 WEEK' GROUP BY concat(cp.title, ' > ', category.title) ORDER BY COUNT(*) DESC"); - } - } - - /** - * Get all newest movies with coves for poster wall. - * - * @return array - */ - public function getNewestMovies() - { - return $this->db->query( - "SELECT DISTINCT (a.imdbID), - guid, name, b.title, searchname, size, completion, - postdate, categoryID, comments, grabs, c.cover - FROM releases a, category b, movieinfo c - WHERE a.categoryID BETWEEN 2000 AND 2999 - AND b.title = 'Movies' - AND a.imdbID = c.imdbID - AND a.imdbID !='NULL' - AND a.imdbID != 0 - AND c.cover = 1 - GROUP BY a.imdbID - ORDER BY a.postdate - DESC LIMIT 24" - ); - } - - /** - * Get all newest games with covers for poster wall. - * - * @return array - */ - public function getNewestConsole() - { - return $this->db->query( - "SELECT DISTINCT (a.consolenfoID), - guid, name, b.title, searchname, size, completion, - postdate, categoryID, comments, grabs, c.cover - FROM releases a, category b, consoleinfo c - WHERE c.cover > 0 - AND a.categoryID BETWEEN 1000 AND 1999 - AND b.title = 'Console' - AND a.consolenfoID = c.ID - AND a.consolenfoID != -2 - AND a.consolenfoID != 0 - GROUP BY a.consolenfoID - ORDER BY a.postdate - DESC LIMIT 35" - ); - } - - /** - * Get all newest music with covers for poster wall. - * - * @return array - */ - public function getNewestMP3s() - { - return $this->db->query( - "SELECT DISTINCT (a.musicinfoID), - guid, name, b.title, searchname, size, completion, - postdate, categoryID, comments, grabs, c.cover - FROM releases a, category b, musicinfo c - WHERE c.cover > 0 - AND a.categoryID BETWEEN 3000 AND 3999 - AND a.categoryID != 3030 - AND b.title = 'Audio' - AND a.musicinfoID = c.ID - AND a.musicinfoID != -2 - GROUP BY a.musicinfoID - ORDER BY a.postdate - DESC LIMIT 24" - ); - } - - /** - * Get all newest books with covers for poster wall. - * - * @return array - */ - public function getNewestBooks() - { - return $this->db->query( - "SELECT DISTINCT (a.bookinfoid), - guid, name, b.title, searchname, size, completion, - postdate, categoryID, comments, grabs, url, c.cover, c.title as booktitle, c.author - FROM releases a, category b, bookinfo c - WHERE c.cover > 0 - AND (a.categoryID BETWEEN 8000 AND 8999 OR a.categoryID = 3030) - AND (b.title = 'Books' OR b.title = 'Audiobook') - AND a.bookinfoid = c.ID - AND a.bookinfoid != -2 - GROUP BY a.bookinfoid - ORDER BY a.postdate - DESC LIMIT 24" - ); - } - -} diff --git a/lib/copy_this/www/lib/releases.php b/lib/copy_this/www/lib/releases.php deleted file mode 100644 index 48b2270c0..000000000 --- a/lib/copy_this/www/lib/releases.php +++ /dev/null @@ -1,2063 +0,0 @@ - 0) - { - $n = array(); - foreach($names as $nm) - $n[] = " searchname = ". $db->escapeString($nm); - - $nsql = "( ".implode(' or ', $n)." )"; - } - - $sql = sprintf(" SELECT releases.*, CONCAT(cp.title, ' > ', c.title) AS category_name, - m.ID AS movie_id, m.title, m.rating, m.cover, m.plot, m.year, m.genre, m.director, m.actors, m.tagline, - mu.ID AS music_id, mu.title as mu_title, mu.cover as mu_cover, mu.year as mu_year, mu.artist as mu_artist, mu.tracks as mu_tracks, mu.review as mu_review, - ep.ID AS ep_id, ep.showtitle as ep_showtitle, ep.airdate as ep_airdate, ep.fullep as ep_fullep, ep.overview as ep_overview, - tvrage.imgdata as rage_imgdata, tvrage.ID as rg_ID - FROM releases - LEFT OUTER JOIN category c ON c.ID = releases.categoryID - LEFT OUTER JOIN category cp ON cp.ID = c.parentID - LEFT OUTER JOIN movieinfo m ON m.imdbID = releases.imdbID - LEFT OUTER JOIN musicinfo mu ON mu.ID = releases.musicinfoID - LEFT OUTER JOIN episodeinfo ep ON ep.ID = releases.episodeinfoID - LEFT OUTER JOIN tvrage ON tvrage.rageID = releases.rageID - where %s", $nsql); - - return $db->queryDirect($sql); - } - - /** - * Get a count of releases for pager. used in admin manage list - */ - public function getCount() - { - $db = new DB(); - $res = $db->queryOneRow("select count(ID) as num from releases"); - - return $res["num"]; - } - - /** - * Get a range of releases. used in admin manage list - */ - public function getRange($start, $num) - { - $db = new DB(); - - if ($start === false) - $limit = ""; - else - $limit = " LIMIT ".$start.",".$num; - - return $db->query(" SELECT releases.*, concat(cp.title, ' > ', c.title) as category_name from releases left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID order by postdate desc" . $limit); - } - - /** - * Get a count of previews for pager. used in admin manage list - */ - public function getPreviewCount($previewtype, $cat) - { - $db = new DB(); - - $catsrch = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - } - - $sql = sprintf("select count(ID) as num from releases where haspreview = %d %s ", $previewtype, $catsrch); - $res = $db->queryOneRow($sql); - return $res["num"]; - } - - /** - * Get a range of releases. used in admin manage list - */ - public function getPreviewRange($previewtype, $cat, $start, $num) - { - $db = new DB(); - - $catsrch = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - } - - if ($start === false) - $limit = ""; - else - $limit = " LIMIT ".$start.",".$num; - - $sql = sprintf(" SELECT releases.*, concat(cp.title, ' > ', c.title) as category_name from releases left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID where haspreview = %d %s order by postdate desc %s", $previewtype, $catsrch, $limit); - return $db->query($sql); - } - - - /** - * Get a count of releases for main browse pager. - */ - public function getBrowseCount($cat, $maxage=-1, $excludedcats=array(), $grp=array()) - { - $db = new DB(); - - $catsrch = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - } - - if ($maxage > 0) - $maxage = sprintf(" and postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - $grpsql = ""; - if (count($grp) > 0) - { - $grpsql = " and ("; - foreach ($grp as $grpname) - { - $grpsql.= sprintf(" groups.name = %s or ", $db->escapeString(str_replace("a.b.", "alt.binaries.", $grpname))); - } - $grpsql.= "1=2 )"; - } - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and categoryID not in (".implode(",", $excludedcats).")"; - - $sql = sprintf("select count(releases.ID) as num from releases left outer join groups on groups.ID = releases.groupID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s", $catsrch, $maxage, $exccatlist, $grpsql); - $res = $db->queryOneRow($sql, true); - - return $res["num"]; - } - - /** - * Get a releases for main browse pages. - */ - public function getBrowseRange($cat, $start, $num, $orderby, $maxage=-1, $excludedcats=array(), $grp=array()) - { - $db = new DB(); - - if ($start === false) - $limit = ""; - else - $limit = " LIMIT ".$start.",".$num; - - $usecatindex = ""; - $catsrch = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - $usecatindex = " use index (ix_releases_categoryID) "; - } - - $maxagesql = ""; - if ($maxage > 0) - $maxagesql = sprintf(" and postdate > now() - interval %d day ", $maxage); - - $grpsql = ""; - if (count($grp) > 0) - { - $grpsql = "select ID from groups where ("; - foreach ($grp as $grpname) - $grpsql.= sprintf(" groups.name = %s or ", $db->escapeString(str_replace("a.b.", "alt.binaries.", $grpname))); - - $grpsql.= "1=2 )"; - - $grpres = $db->query($grpsql); - if (count($grpsql) > 0) - { - $grpsql = " and ( "; - foreach ($grpres as $grpresrow) - $grpsql.= sprintf(" groups.ID = %d or ", $grpresrow["ID"]); - - $grpsql = substr($grpsql, 0, strlen($grpsql) - 3)." ) "; - } - else - $grpsql = ""; - } - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - $order = $this->getBrowseOrder($orderby); - $sql = sprintf(" SELECT releases.*, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID, re.releaseID as reID, pre.ctime, pre.nuketype, coalesce(movieinfo.ID,0) as movieinfoID from releases %s left outer join groups on groups.ID = releases.groupID left outer join movieinfo on movieinfo.imdbID = releases.imdbID left outer join releaseaudio re on re.releaseID = releases.ID and re.audioID = 1 left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID left outer join predb pre on pre.ID = releases.preID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s order by %s %s".$limit, $usecatindex, $catsrch, $maxagesql, $exccatlist, $grpsql, $order[0], $order[1]); - return $db->query($sql, true); - } - - /** - * Get a column names browse list to be ordered by - */ - public function getBrowseOrder($orderby) - { - $order = ($orderby == '') ? 'posted_desc' : $orderby; - $orderArr = explode("_", $order); - switch($orderArr[0]) { - case 'cat': - $orderfield = 'categoryID'; - break; - case 'name': - $orderfield = 'searchname'; - break; - case 'size': - $orderfield = 'size'; - break; - case 'files': - $orderfield = 'totalpart'; - break; - case 'stats': - $orderfield = 'grabs'; - break; - case 'posted': - default: - $orderfield = 'postdate'; - break; - } - $ordersort = (isset($orderArr[1]) && preg_match('/^asc|desc$/i', $orderArr[1])) ? $orderArr[1] : 'desc'; - return array($orderfield, $ordersort); - } - - /** - * Get a list of available columns for sorting browse list - */ - public function getBrowseOrdering() - { - return array('name_asc', 'name_desc', 'cat_asc', 'cat_desc', 'posted_asc', 'posted_desc', 'size_asc', 'size_desc', 'files_asc', 'files_desc', 'stats_asc', 'stats_desc'); - } - - /** - * Get a range of releases. Used in nzb export - */ - public function getForExport($postfrom, $postto, $group, $cat) - { - $db = new DB(); - if ($postfrom != "") - { - $dateparts = explode("/", $postfrom); - if (count($dateparts) == 3) - $postfrom = sprintf(" and postdate > %s ", $db->escapeString($dateparts[2]."-".$dateparts[1]."-".$dateparts[0]." 00:00:00")); - else - $postfrom = ""; - } - - if ($postto != "") - { - $dateparts = explode("/", $postto); - if (count($dateparts) == 3) - $postto = sprintf(" and postdate < %s ", $db->escapeString($dateparts[2]."-".$dateparts[1]."-".$dateparts[0]." 23:59:59")); - else - $postto = ""; - } - - if ($group != "" && $group != "-1") - $group = sprintf(" and groupID = %d ", $group); - else - $group = ""; - - if ($cat != "" && $cat != "-1") - $cat = sprintf(" and categoryID = %d ", $cat); - else - $cat = ""; - - return $db->queryDirect(sprintf("SELECT searchname, guid, CONCAT(cp.title,'_',category.title) as catName FROM releases INNER JOIN category ON releases.categoryID = category.ID LEFT OUTER JOIN category cp ON cp.ID = category.parentID where 1 = 1 %s %s %s %s", $postfrom, $postto, $group, $cat)); - } - - /** - * Get the earliest release - */ - public function getEarliestUsenetPostDate() - { - $db = new DB(); - $row = $db->queryOneRow("SELECT DATE_FORMAT(min(postdate), '%d/%m/%Y') as postdate from releases"); - - return $row["postdate"]; - } - - /** - * Get the most recent release - */ - public function getLatestUsenetPostDate() - { - $db = new DB(); - $row = $db->queryOneRow("SELECT DATE_FORMAT(max(postdate), '%d/%m/%Y') as postdate from releases"); - - return $row["postdate"]; - } - - /** - * Get all groups for which there is a release for a html select - */ - public function getReleasedGroupsForSelect($blnIncludeAll = true) - { - $db = new DB(); - $groups = $db->query("select distinct groups.ID, groups.name from releases inner join groups on groups.ID = releases.groupID"); - $temp_array = array(); - - if ($blnIncludeAll) - $temp_array[-1] = "--All Groups--"; - - foreach($groups as $group) - $temp_array[$group["ID"]] = $group["name"]; - - return $temp_array; - } - - /** - * Get releases for all types of rss feeds - */ - public function getRss($cat, $num, $uid=0, $rageid, $anidbid, $airdate=-1) - { - $db = new DB(); - - $limit = " LIMIT 0,".($num > 100 ? 100 : $num); - - $cartsrch = ""; - $catsrch = ""; - - if (count($cat) > 0) - { - if ($cat[0] == -2) - { - $cartsrch = sprintf(" inner join usercart on usercart.userID = %d and usercart.releaseID = releases.ID ", $uid); - } - elseif ($cat[0] == -1) - { - } - else - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - } - } - - $rage = ($rageid > -1) ? sprintf(" and releases.rageID = %d ", $rageid) : ''; - $anidb = ($anidbid > -1) ? sprintf(" and releases.anidbID = %d ", $anidbid) : ''; - $airdate = ($airdate > -1) ? sprintf(" and releases.tvairdate >= DATE_SUB(CURDATE(), INTERVAL %d DAY) ", $airdate) : ''; - - $sql = sprintf(" SELECT releases.*, rn.ID as nfoID, m.title as imdbtitle, m.cover, m.imdbID, m.rating, m.plot, m.year, m.genre, m.director, m.actors, g.name as group_name, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, coalesce(cp.ID,0) as parentCategoryID, mu.title as mu_title, mu.url as mu_url, mu.artist as mu_artist, mu.publisher as mu_publisher, mu.releasedate as mu_releasedate, mu.review as mu_review, mu.tracks as mu_tracks, mu.cover as mu_cover, mug.title as mu_genre, co.title as co_title, co.url as co_url, co.publisher as co_publisher, co.releasedate as co_releasedate, co.review as co_review, co.cover as co_cover, cog.title as co_genre, bo.title as bo_title, bo.url as bo_url, bo.publisher as bo_publisher, bo.author as bo_author, bo.publishdate as bo_publishdate, bo.review as bo_review, bo.cover as bo_cover from releases left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID left outer join groups g on g.ID = releases.groupID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join movieinfo m on m.imdbID = releases.imdbID and m.title != '' left outer join musicinfo mu on mu.ID = releases.musicinfoID left outer join genres mug on mug.ID = mu.genreID left outer join bookinfo bo on bo.ID = releases.bookinfoID left outer join consoleinfo co on co.ID = releases.consoleinfoID left outer join genres cog on cog.ID = co.genreID %s where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s order by postdate desc %s" ,$cartsrch, $catsrch, $rage, $anidb, $airdate, $limit); - return $db->query($sql, true); - } - - /** - * Get releases in users 'my tv show' rss feed - */ - public function getShowsRss($num, $uid=0, $excludedcats=array(), $airdate=-1) - { - $db = new DB(); - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - $usershows = $db->query(sprintf("select rageID, categoryID from userseries where userID = %d", $uid), true); - $usql = '(1=2 '; - foreach($usershows as $ushow) - { - $usql .= sprintf('or (releases.rageID = %d', $ushow['rageID']); - if ($ushow['categoryID'] != '') - { - $catsArr = explode('|', $ushow['categoryID']); - if (count($catsArr) > 1) - $usql .= sprintf(' and releases.categoryID in (%s)', implode(',',$catsArr)); - else - $usql .= sprintf(' and releases.categoryID = %d', $catsArr[0]); - } - $usql .= ') '; - } - $usql .= ') '; - - $airdate = ($airdate > -1) ? sprintf(" and releases.tvairdate >= DATE_SUB(CURDATE(), INTERVAL %d DAY) ", $airdate) : ''; - - $limit = " LIMIT 0,".($num > 100 ? 100 : $num); - - $sql = sprintf(" SELECT releases.*, tvr.rageID, tvr.releasetitle, epinfo.overview, epinfo.director, epinfo.gueststars, epinfo.writer, epinfo.rating, epinfo.fullep, epinfo.showtitle, epinfo.tvdbID as ep_tvdbID, g.name as group_name, concat(cp.title, '-', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, coalesce(cp.ID,0) as parentCategoryID - FROM releases FORCE INDEX (ix_releases_rageID) - left outer join category c on c.ID = releases.categoryID - left outer join category cp on cp.ID = c.parentID - left outer join groups g on g.ID = releases.groupID - left outer join (SELECT ID, releasetitle, rageid FROM tvrage GROUP BY rageid) tvr on tvr.rageID = releases.rageID - left outer join episodeinfo epinfo on epinfo.ID = releases.episodeinfoID - inner join - ( select ID from - ( select id, rageID, categoryID, season, episode from releases where %s order by season desc, episode desc, postdate asc ) releases - group by rageID, season, episode, categoryID - ) z on z.id = releases.ID - where %s %s %s - and releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') - order by postdate desc %s" , $usql, $usql, $exccatlist, $airdate, $limit); - return $db->query($sql); - } - - /** - * Get releases in users 'my movies' rss feed - */ - public function getMyMoviesRss($num, $uid=0, $excludedcats=array()) - { - $db = new DB(); - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - $usermovies = $db->query(sprintf("select imdbID, categoryID from usermovies where userID = %d", $uid), true); - $usql = '(1=2 '; - foreach($usermovies as $umov) - { - $usql .= sprintf('or (releases.imdbID = %d', $umov['imdbID']); - if ($umov['categoryID'] != '') - { - $catsArr = explode('|', $umov['categoryID']); - if (count($catsArr) > 1) - $usql .= sprintf(' and releases.categoryID in (%s)', implode(',',$catsArr)); - else - $usql .= sprintf(' and releases.categoryID = %d', $catsArr[0]); - } - $usql .= ') '; - } - $usql .= ') '; - - $limit = " LIMIT 0,".($num > 100 ? 100 : $num); - - $sql = sprintf(" SELECT releases.*, mi.title as releasetitle, g.name as group_name, concat(cp.title, '-', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, coalesce(cp.ID,0) as parentCategoryID - FROM releases - left outer join category c on c.ID = releases.categoryID - left outer join category cp on cp.ID = c.parentID - left outer join groups g on g.ID = releases.groupID - left outer join movieinfo mi on mi.imdbID = releases.imdbID - where %s %s - and releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') - order by postdate desc %s" , $usql, $exccatlist, $limit); - return $db->query($sql); - } - - /** - * Get range of releases in users 'my tvshows' - */ - public function getShowsRange($usershows, $start, $num, $orderby, $maxage=-1, $excludedcats=array()) - { - $db = new DB(); - - if ($start === false) - $limit = ""; - else - $limit = " LIMIT ".$start.",".$num; - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - $usql = '(1=2 '; - foreach($usershows as $ushow) - { - $usql .= sprintf('or (releases.rageID = %d', $ushow['rageID']); - if ($ushow['categoryID'] != '') - { - $catsArr = explode('|', $ushow['categoryID']); - if (count($catsArr) > 1) - $usql .= sprintf(' and releases.categoryID in (%s)', implode(',',$catsArr)); - else - $usql .= sprintf(' and releases.categoryID = %d', $catsArr[0]); - } - $usql .= ') '; - } - $usql .= ') '; - - $maxagesql = ""; - if ($maxage > 0) - $maxagesql = sprintf(" and releases.postdate > now() - interval %d day ", $maxage); - - $order = $this->getBrowseOrder($orderby); - $sql = sprintf(" SELECT releases.*, concat(cp.title, '-', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, pre.ctime, pre.nuketype, rn.ID as nfoID, re.releaseID as reID from releases left outer join releasevideo re on re.releaseID = releases.ID left outer join groups on groups.ID = releases.groupID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category c on c.ID = releases.categoryID left outer join predb pre on pre.ID = releases.preID left outer join category cp on cp.ID = c.parentID where %s %s and releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s order by %s %s".$limit, $usql, $exccatlist, $maxagesql, $order[0], $order[1]); - - return $db->query($sql, true); - } - - /** - * Get count of releases in users 'my tvshows' for pager - */ - public function getShowsCount($usershows, $maxage=-1, $excludedcats=array()) - { - $db = new DB(); - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - $usql = '(1=2 '; - foreach($usershows as $ushow) - { - $usql .= sprintf('or (releases.rageID = %d', $ushow['rageID']); - if ($ushow['categoryID'] != '') - { - $catsArr = explode('|', $ushow['categoryID']); - if (count($catsArr) > 1) - $usql .= sprintf(' and releases.categoryID in (%s)', implode(',',$catsArr)); - else - $usql .= sprintf(' and releases.categoryID = %d', $catsArr[0]); - } - $usql .= ') '; - } - $usql .= ') '; - - $maxagesql = ""; - if ($maxage > 0) - $maxagesql = sprintf(" and releases.postdate > now() - interval %d day ", $maxage); - - $res = $db->queryOneRow(sprintf(" SELECT count(releases.ID) as num from releases where %s %s and releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s", $usql, $exccatlist, $maxagesql), true); - - return $res["num"]; - } - - /** - * Delete one or more releases. - */ - public function delete($id, $isGuid=false) - { - $db = new DB(); - $users = new Users(); - $s = new Sites(); - $nfo = new Nfo(); - $site = $s->get(); - $rf = new ReleaseFiles(); - $re = new ReleaseExtra(); - $rc = new ReleaseComments(); - $ri = new ReleaseImage(); - - if (!is_array($id)) - $id = array($id); - - foreach($id as $identifier) - { - // - // delete from disk. - // - $rel = ($isGuid) ? $this->getByGuid($identifier) : $this->getById($identifier); - - $nzbpath = ""; - if ($isGuid) - $nzbpath = $site->nzbpath.substr($identifier, 0, 1)."/".$identifier.".nzb.gz"; - elseif ($rel) - $nzbpath = $site->nzbpath.substr($rel["guid"], 0, 1)."/".$rel["guid"].".nzb.gz"; - - if ($nzbpath != "" && file_exists($nzbpath)) - unlink($nzbpath); - - $audiopreviewpath = ""; - if ($isGuid) - $audiopreviewpath = WWW_DIR.'covers/audio/'.$identifier.".mp3"; - elseif ($rel) - $audiopreviewpath = WWW_DIR.'covers/audio/'.$rel["guid"].".mp3"; - - if ($audiopreviewpath && file_exists($audiopreviewpath)) - unlink($audiopreviewpath); - - if ($rel) - { - $nfo->deleteReleaseNfo($rel['ID']); - $rc->deleteCommentsForRelease($rel['ID']); - $users->delCartForRelease($rel['ID']); - $users->delDownloadRequestsForRelease($rel['ID']); - $rf->delete($rel['ID']); - $re->delete($rel['ID']); - $re->deleteFull($rel['ID']); - $ri->delete($rel['guid']); - $db->exec(sprintf("DELETE from releases where id = %d", $rel['ID'])); - } - } - } - - /** - * Delete a preview associated with a release and update the release to indicate it doesnt have one. - */ - public function deletePreview($guid) - { - $this->updateHasPreview($guid, 0); - $ri = new ReleaseImage(); - $ri->delete($guid); - } - - /** - * Update a release. - */ - public function update($id, $name, $searchname, $fromname, $category, $parts, $grabs, $size, $posteddate, $addeddate, $rageid, $seriesfull, $season, $episode, $imdbid, $anidbid, $tvdbid, $consoleinfoid) - { - $db = new DB(); - - $db->exec(sprintf("update releases set name=%s, searchname=%s, fromname=%s, categoryID=%d, totalpart=%d, grabs=%d, size=%s, postdate=%s, adddate=%s, rageID=%d, seriesfull=%s, season=%s, episode=%s, imdbID=%d, anidbID=%d, tvdbID=%d,consoleinfoID=%d where id = %d", - $db->escapeString($name), $db->escapeString($searchname), $db->escapeString($fromname), $category, $parts, $grabs, $db->escapeString($size), $db->escapeString($posteddate), $db->escapeString($addeddate), $rageid, $db->escapeString($seriesfull), $db->escapeString($season), $db->escapeString($episode), $imdbid, $anidbid, $tvdbid, $consoleinfoid, $id)); - } - - /** - * Update multiple releases. - */ - public function updatemulti($guids, $category, $grabs, $rageid, $season, $imdbid) - { - if (!is_array($guids) || sizeof($guids) < 1) - return false; - - $update = array( - 'categoryID'=>(($category == '-1') ? '' : $category), - 'grabs'=>$grabs, - 'rageID'=>$rageid, - 'season'=>$season, - 'imdbID'=>$imdbid - ); - - $db = new DB(); - $updateSql = array(); - foreach($update as $updk=>$updv) { - if ($updv != '') - $updateSql[] = sprintf($updk.'=%s', $db->escapeString($updv)); - } - - if (sizeof($updateSql) < 1) { - //echo 'no field set to be changed'; - return -1; - } - - $updateGuids = array(); - foreach($guids as $guid) { - $updateGuids[] = $db->escapeString($guid); - } - - $sql = sprintf('update releases set '.implode(', ', $updateSql).' where guid in (%s)', implode(', ', $updateGuids)); - return $db->exec($sql); - } - - /** - * Update whether a release has a preview. - */ - public function updateHasPreview($guid, $haspreview) - { - $db = new DB(); - $db->exec(sprintf("update releases set haspreview = %d where guid = %s", $haspreview, $db->escapeString($guid))); - } - - /** - * Not yet implemented. - */ - public function searchadv($searchname, $filename, $poster, $group, $cat=array(-1), $sizefrom, $sizeto, $offset=0, $limit=1000, $orderby='', $maxage=-1, $excludedcats=array()) - { - return array(); - } - - /** - * Search for releases. - */ - public function search($search, $cat=array(-1), $offset=0, $limit=1000, $orderby='', $maxage=-1, $excludedcats=array(), $grp=array(), $minsize=-1, $maxsize=-1) - { - $s = new Sites(); - $site = $s->get(); - - if ($site->sphinxenabled) { - $sphinx = new Sphinx(); - $order = $this->getBrowseOrder($orderby); - $results = $sphinx->search($search, $cat, $offset, $limit, $order, $maxage, $excludedcats, $grp, array(), true, $minsize, $maxsize); - if (is_array($results)) - return $results; - } - - // - // Search using MySQL - // - $db = new DB(); - - $catsrch = ""; - $usecatindex = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - $usecatindex = " use index (ix_releases_categoryID) "; - } - - $grpsql = ""; - if (count($grp) > 0) - { - $grpsql = " and ("; - foreach ($grp as $grpname) - { - $grpsql.= sprintf(" groups.name = %s or ", $db->escapeString(str_replace("a.b.", "alt.binaries.", $grpname))); - } - $grpsql.= "1=2 )"; - } - - // - // if the query starts with a ^ it indicates the search is looking for items which start with the term - // still do the fulltext match, but mandate that all items returned must start with the provided word - // - $words = explode(" ", $search); - $searchsql = ""; - $intwordcount = 0; - if (count($words) > 0) - { - foreach ($words as $word) - { - if ($word != "") - { - // - // see if the first word had a caret, which indicates search must start with term - // - if ($intwordcount == 0 && (strpos($word, "^") === 0)) - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString(substr($word, 1)."%")); - elseif (substr($word, 0, 2) == '--') - $searchsql.= sprintf(" and releases.searchname not like %s", $db->escapeString("%".substr($word, 2)."%")); - else - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString("%".$word."%")); - - $intwordcount++; - } - } - } - - if ($maxage > 0) - $maxage = sprintf(" and postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - if ($minsize != -1) - $minsize = sprintf(" and size > %d ", $minsize); - else - $minsize = ""; - - if ($maxsize != -1) - $maxsize = sprintf(" and size < %d ", $maxsize); - else - $maxsize = ""; - - $exccatlist = ""; - if (count($excludedcats) > 0) - $exccatlist = " and releases.categoryID not in (".implode(",", $excludedcats).")"; - - if ($orderby == "") - { - $order[0] = " postdate "; - $order[1] = " desc "; - } else - $order = $this->getBrowseOrder($orderby); - - $sql = sprintf("select releases.*, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID, re.releaseID as reID, cp.ID as categoryParentID, pre.ctime, pre.nuketype, coalesce(movieinfo.ID,0) as movieinfoID from releases %s left outer join movieinfo on movieinfo.imdbID = releases.imdbID left outer join releasevideo re on re.releaseID = releases.ID left outer join releasenfo rn on rn.releaseID = releases.ID left outer join groups on groups.ID = releases.groupID left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID left outer join predb pre on pre.ID = releases.preID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s %s %s %s order by %s %s limit %d, %d ", $usecatindex, $searchsql, $catsrch, $maxage, $exccatlist, $grpsql, $minsize, $maxsize, $order[0], $order[1], $offset, $limit); - $orderpos = strpos($sql, "order by"); - $wherepos = strpos($sql, "where"); - $sqlcount = "select count(releases.ID) as num from releases ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Search for releases by rage id. Used by API/Sickbeard. - */ - public function searchbyRageId($rageId, $series="", $episode="", $offset=0, $limit=100, $name="", $cat=array(-1), $maxage=-1) - { - $s = new Sites(); - $site = $s->get(); - - // Sphinx appears much slower than searching mysql directly when you have a rage ID already - if ($site->sphinxenabled && $rageId == "-1") - { - $sphinx = new Sphinx(); - $results = $sphinx->searchbyRageId($rageId, $series, $episode, $offset, $limit, $name, $cat, $maxage, array(), true); - if (is_array($results)) - return $results; - } - - $db = new DB(); - - if ($rageId != "-1") - $rageId = sprintf(" and rageID = %d ", $rageId); - else - $rageId = ""; - - if ($series != "") - { - // - // Exclude four digit series, which will be the year 2010 etc - // - if (is_numeric($series) && strlen($series) != 4) - $series = sprintf('S%02d', $series); - - $series = sprintf(" and releases.season = %s", $db->escapeString($series)); - } - if ($episode != "") - { - if (is_numeric($episode)) - $episode = sprintf('E%02d', $episode); - - $episode = sprintf(" and releases.episode like %s", $db->escapeString('%'.$episode.'%')); - } - - // - // if the query starts with a ^ it indicates the search is looking for items which start with the term - // still do the fulltext match, but mandate that all items returned must start with the provided word - // - $words = explode(" ", $name); - $searchsql = ""; - $intwordcount = 0; - if (count($words) > 0) - { - foreach ($words as $word) - { - if ($word != "") { - // - // see if the first word had a caret, which indicates search must start with term - // - if ($intwordcount == 0 && (strpos($word, "^") === 0)) - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString(substr($word, 1)."%")); - elseif (substr($word, 0, 2) == '--') - $searchsql.= sprintf(" and releases.searchname not like %s", $db->escapeString("%".substr($word, 2)."%")); - else - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString("%".$word."%")); - - $intwordcount++; - } - } - } - - $catsrch = ""; - $usecatindex = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - $usecatindex = " use index (ix_releases_categoryID) "; - } - - if ($maxage > 0) - $maxage = sprintf(" and postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - $sql = sprintf("select releases.*, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID, re.releaseID as reID from releases %s left outer join category c on c.ID = releases.categoryID left outer join groups on groups.ID = releases.groupID left outer join releasevideo re on re.releaseID = releases.ID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category cp on cp.ID = c.parentID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s %s %s order by postdate desc limit %d, %d ", $usecatindex, $rageId, $series, $episode, $searchsql, $catsrch, $maxage, $offset, $limit); - $orderpos = strpos($sql, "order by"); - $wherepos = strpos($sql, "where"); - $sqlcount = "select count(releases.ID) as num from releases ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Search for releases by anidb id. Used by API/Sickbeard. - */ - public function searchbyAnidbId($anidbID, $epno='', $offset=0, $limit=100, $name='', $maxage=-1) - { - $s = new Sites(); - $site = $s->get(); - if ($site->sphinxenabled) { - $sphinx = new Sphinx(); - $results = $sphinx->searchbyAnidbId($anidbID, $epno, $offset, $limit, $name, $maxage, array(), true); - if (is_array($results)) - return $results; - } - - $db = new DB(); - - $anidbID = ($anidbID > -1) ? sprintf(" AND anidbID = %d ", $anidbID) : ''; - - $epno = is_numeric($epno) ? sprintf(" AND releases.episode LIKE '%s' ", $db->escapeString('%'.$epno.'%')) : ''; - - // - // if the query starts with a ^ it indicates the search is looking for items which start with the term - // still do the fulltext match, but mandate that all items returned must start with the provided word - // - $words = explode(" ", $name); - $searchsql = ""; - $intwordcount = 0; - if (count($words) > 0) - { - foreach ($words as $word) - { - if ($word != "") { - // - // see if the first word had a caret, which indicates search must start with term - // - if ($intwordcount == 0 && (strpos($word, "^") === 0)) - $searchsql.= sprintf(" AND releases.searchname LIKE '%s' ", $db->escapeString(substr($word, 1)."%")); - elseif (substr($word, 0, 2) == '--') - $searchsql.= sprintf(" AND releases.searchname NOT LIKE '%s' ", $db->escapeString("%".substr($word, 2)."%")); - else - $searchsql.= sprintf(" AND releases.searchname LIKE '%s' ", $db->escapeString("%".$word."%")); - - $intwordcount++; - } - } - } - - $maxage = ($maxage > 0) ? sprintf(" and postdate > now() - interval %d day ", $maxage) : ''; - - $sql = sprintf("SELECT releases.*, concat(cp.title, ' > ', c.title) - AS category_name, concat(cp.ID, ',', c.ID) AS category_ids, groups.name AS group_name, rn.ID AS nfoID - FROM releases LEFT OUTER JOIN category c ON c.ID = releases.categoryID LEFT OUTER JOIN groups ON groups.ID = releases.groupID - LEFT OUTER JOIN releasenfo rn ON rn.releaseID = releases.ID and rn.nfo IS NOT NULL LEFT OUTER JOIN category cp ON cp.ID = c.parentID - WHERE releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s ORDER BY postdate desc LIMIT %d, %d ", - $anidbID, $epno, $searchsql, $maxage, $offset, $limit - ); - $orderpos = strpos($sql, "ORDER BY"); - $wherepos = strpos($sql, "WHERE"); - $sqlcount = "SELECT count(releases.ID) AS num FROM releases ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Search for releases by album/artist/musicinfo. Used by API. - */ - public function searchAudio($artist, $album, $label, $track, $year, $genre=array(-1), $offset=0, $limit=100, $cat=array(-1), $maxage=-1) - { - $s = new Sites(); - $site = $s->get(); - if ($site->sphinxenabled) { - $sphinx = new Sphinx(); - $results = $sphinx->searchAudio($artist, $album, $label, $track, $year, $genre, $offset, $limit, $cat, $maxage, array(), true); - if (is_array($results)) - return $results; - } - - $db = new DB(); - $searchsql = ""; - - if ($artist != "") - $searchsql.= sprintf(" and musicinfo.artist like %s ", $db->escapeString("%".$artist."%")); - if ($album != "") - $searchsql.= sprintf(" and musicinfo.title like %s ", $db->escapeString("%".$album."%")); - if ($label != "") - $searchsql.= sprintf(" and musicinfo.publisher like %s ", $db->escapeString("%".$label."%")); - if ($track != "") - $searchsql.= sprintf(" and musicinfo.tracks like %s ", $db->escapeString("%".$track."%")); - if ($year != "") - $searchsql.= sprintf(" and musicinfo.year = %d ", $year); - - - $catsrch = ""; - $usecatindex = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - $usecatindex = " use index (ix_releases_categoryID) "; - } - - if ($maxage > 0) - $maxage = sprintf(" and postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - $genresql = ""; - if (count($genre) > 0 && $genre[0] != -1) - { - $genresql = " and ("; - foreach ($genre as $g) - { - $genresql .= sprintf(" musicinfo.genreID = %d or ", $g); - } - $genresql.= "1=2 )"; - } - - $sql = sprintf("select releases.*, musicinfo.cover as mi_cover, musicinfo.review as mi_review, musicinfo.tracks as mi_tracks, musicinfo.publisher as mi_publisher, musicinfo.title as mi_title, musicinfo.artist as mi_artist, genres.title as music_genrename, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID from releases %s left outer join musicinfo on musicinfo.ID = releases.musicinfoID left join genres on genres.ID = musicinfo.genreID left outer join groups on groups.ID = releases.groupID left outer join category c on c.ID = releases.categoryID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category cp on cp.ID = c.parentID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s order by postdate desc limit %d, %d ", $usecatindex, $searchsql, $catsrch, $maxage, $genresql, $offset, $limit); - $orderpos = strpos($sql, "order by"); - $wherepos = strpos($sql, "where"); - $sqlcount = "select count(releases.ID) as num from releases inner join musicinfo on musicinfo.ID = releases.musicinfoID ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Search for releases by author/bookinfo. Used by API. - */ - public function searchBook($author, $title, $offset=0, $limit=100, $maxage=-1) - { - $s = new Sites(); - $site = $s->get(); - if ($site->sphinxenabled) { - $sphinx = new Sphinx(); - $results = $sphinx->searchBook($author, $title, $offset, $limit, $maxage, array(), true); - if (is_array($results)) - return $results; - } - - $db = new DB(); - $searchsql = ""; - - if ($author != "") - $searchsql.= sprintf(" and bookinfo.author like %s ", $db->escapeString("%".$author."%")); - if ($title != "") - $searchsql.= sprintf(" and bookinfo.title like %s ", $db->escapeString("%".$title."%")); - - if ($maxage > 0) - $maxage = sprintf(" and postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - $sql = sprintf("select releases.*, bookinfo.cover as bi_cover, bookinfo.review as bi_review, bookinfo.publisher as bi_publisher, bookinfo.pages as bi_pages, bookinfo.publishdate as bi_publishdate, bookinfo.title as bi_title, bookinfo.author as bi_author, genres.title as book_genrename, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID from releases left outer join bookinfo on bookinfo.ID = releases.bookinfoID left join genres on genres.ID = bookinfo.genreID left outer join groups on groups.ID = releases.groupID left outer join category c on c.ID = releases.categoryID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category cp on cp.ID = c.parentID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s order by postdate desc limit %d, %d ", $searchsql, $maxage, $offset, $limit); - $orderpos = strpos($sql, "order by"); - $wherepos = strpos($sql, "where"); - $sqlcount = "select count(releases.ID) as num from releases inner join bookinfo on bookinfo.ID = releases.bookinfoID ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Search for releases by imdbid/movieinfo. Used by API/Couchpotato. - */ - public function searchbyImdbId($imdbId, $offset=0, $limit=100, $name="", $cat=array(-1), $genre="", $maxage=-1) - { - $s = new Sites(); - $site = $s->get(); - if ($site->sphinxenabled) { - $sphinx = new Sphinx(); - $results = $sphinx->searchbyImdbId($imdbId, $offset, $limit, $name, $cat, $genre, $maxage, array(), true); - if (is_array($results)) - return $results; - } - - $db = new DB(); - - if ($imdbId != "-1" && is_numeric($imdbId)) { - //pad id with zeros just in case - $imdbId = str_pad($imdbId, 7, "0",STR_PAD_LEFT); - $imdbId = sprintf(" and releases.imdbID = %d ", $imdbId); - } else { - $imdbId = ""; - } - - // - // if the query starts with a ^ it indicates the search is looking for items which start with the term - // still do the fulltext match, but mandate that all items returned must start with the provided word - // - $words = explode(" ", $name); - $searchsql = ""; - $intwordcount = 0; - if (count($words) > 0) - { - foreach ($words as $word) - { - if ($word != "") - { - // - // see if the first word had a caret, which indicates search must start with term - // - if ($intwordcount == 0 && (strpos($word, "^") === 0)) - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString(substr($word, 1)."%")); - elseif (substr($word, 0, 2) == '--') - $searchsql.= sprintf(" and releases.searchname not like %s", $db->escapeString("%".substr($word, 2)."%")); - else - $searchsql.= sprintf(" and releases.searchname like %s", $db->escapeString("%".$word."%")); - - $intwordcount++; - } - } - } - - $catsrch = ""; - if (count($cat) > 0 && $cat[0] != -1) - { - $catsrch = " and ("; - foreach ($cat as $category) - { - if ($category != -1) - { - $categ = new Category(); - if ($categ->isParent($category)) - { - $children = $categ->getChildren($category); - $chlist = "-99"; - foreach ($children as $child) - $chlist.=", ".$child["ID"]; - - if ($chlist != "-99") - $catsrch .= " releases.categoryID in (".$chlist.") or "; - } - else - { - $catsrch .= sprintf(" releases.categoryID = %d or ", $category); - } - } - } - $catsrch.= "1=2 )"; - } - - if ($maxage > 0) - $maxage = sprintf(" and releases.postdate > now() - interval %d day ", $maxage); - else - $maxage = ""; - - if ($genre != "") - { - $genre = sprintf(" and movieinfo.genre like %s", $db->escapeString("%".$genre."%")); - } - - $sql = sprintf("select releases.*, movieinfo.title as moi_title, movieinfo.tagline as moi_tagline, movieinfo.rating as moi_rating, movieinfo.plot as moi_plot, movieinfo.year as moi_year, movieinfo.genre as moi_genre, movieinfo.director as moi_director, movieinfo.actors as moi_actors, movieinfo.cover as moi_cover, movieinfo.backdrop as moi_backdrop, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, rn.ID as nfoID from releases left outer join groups on groups.ID = releases.groupID left outer join category c on c.ID = releases.categoryID left outer join releasenfo rn on rn.releaseID = releases.ID and rn.nfo is not null left outer join category cp on cp.ID = c.parentID left outer join movieinfo on releases.imdbID = movieinfo.imdbID where releases.passwordstatus <= (select value from site where setting='showpasswordedrelease') %s %s %s %s %s order by postdate desc limit %d, %d ", $searchsql, $imdbId, $catsrch, $maxage, $genre, $offset, $limit); - $orderpos = strpos($sql, "order by"); - $wherepos = strpos($sql, "where"); - $sqlcount = "select count(releases.ID) as num from releases left outer join movieinfo on releases.imdbID = movieinfo.imdbID ".substr($sql, $wherepos,$orderpos-$wherepos); - - $countres = $db->queryOneRow($sqlcount, true); - $res = $db->query($sql, true); - if (count($res) > 0) - $res[0]["_totalrows"] = $countres["num"]; - - return $res; - } - - /** - * Return a list of releases with a similar name to that provided. - */ - public function searchSimilar($currentid, $name, $limit=6, $excludedcats=array()) - { - $name = $this->getSimilarName($name); - $results = $this->search($name, array(-1), 0, $limit, '', -1, $excludedcats); - if (!$results) - return $results; - - // - // Get the category for the parent of this release - // - $currRow = $this->getById($currentid); - $cat = new Category(); - $catrow = $cat->getById($currRow["categoryID"]); - $parentCat = $catrow["parentID"]; - - $ret = array(); - foreach ($results as $res) - if ($res["ID"] != $currentid && $res["categoryParentID"] == $parentCat) - $ret[] = $res; - - return $ret; - } - - /** - * Return a similar release name. - */ - public function getSimilarName($name) - { - $words = str_word_count(str_replace(array(".","_"), " ", $name), 2); - $firstwords = array_slice($words, 0, 2); - return implode(' ', $firstwords); - } - - /** - * Retrieve one or more releases by guid. - */ - public function getByGuid($guid) - { - $db = new DB(); - if (is_array($guid)) - { - $tmpguids = array(); - foreach($guid as $g) - $tmpguids[] = $db->escapeString($g); - $gsql = sprintf('guid in (%s)', implode(',',$tmpguids)); - } else { - $gsql = sprintf('guid = %s', $db->escapeString($guid)); - } - $sql = sprintf("select releases.*, musicinfo.cover as mi_cover, musicinfo.review as mi_review, musicinfo.tracks as mi_tracks, musicinfo.publisher as mi_publisher, musicinfo.title as mi_title, musicinfo.artist as mi_artist, music_genre.title as music_genrename, bookinfo.cover as bi_cover, bookinfo.review as bi_review, bookinfo.publisher as bi_publisher, bookinfo.publishdate as bi_publishdate, bookinfo.title as bi_title, bookinfo.author as bi_author, bookinfo.pages as bi_pages, bookinfo.isbn as bi_isbn, concat(cp.title, ' > ', c.title) as category_name, concat(cp.ID, ',', c.ID) as category_ids, groups.name as group_name, movieinfo.title AS movietitle, movieinfo.year AS movieyear, (SELECT releasetitle FROM tvrage WHERE rageid = releases.rageid AND rageid > 0 LIMIT 1) AS tvreleasetitle from releases left outer join groups on groups.ID = releases.groupID left outer join category c on c.ID = releases.categoryID left outer join category cp on cp.ID = c.parentID left outer join musicinfo on musicinfo.ID = releases.musicinfoID left outer join bookinfo on bookinfo.ID = releases.bookinfoID left outer join movieinfo on movieinfo.imdbID = releases.imdbID left join genres music_genre on music_genre.ID = musicinfo.genreID where %s", $gsql); - return (is_array($guid)) ? $db->query($sql) : $db->queryOneRow($sql); - } - - /** - * Writes a zip file of an array of release guids directly to the stream - */ - public function getZipped($guids) - { - $s = new Sites(); - $nzb = new Enzebe(); - $site = $s->get(); - $zipfile = new zipfile(); - - foreach ($guids as $guid) - { - $nzbpath = $nzb->getNZBPath($guid); - - if (file_exists($nzbpath)) - { - ob_start(); - @readgzfile($nzbpath); - $nzbfile = ob_get_contents(); - ob_end_clean(); - - $filename = $guid; - $r = $this->getByGuid($guid); - if ($r) - $filename = $r["searchname"]; - - $zipfile->addFile($nzbfile, $filename.".nzb"); - } - } - - return $zipfile->file(); - } - - /** - * Removes an associated tvrage id from all releases using it. - */ - public function removeRageIdFromReleases($rageid) - { - $db = new DB(); - $res = $db->queryOneRow(sprintf("select count(ID) as num from releases where rageID = %d", $rageid)); - $ret = $res["num"]; - $db->exec(sprintf("update releases set rageID = -1, seriesfull = null, season = null, episode = null where rageID = %d", $rageid)); - return $ret; - } - - /** - * Removes an associated tvdb id from all releases using it. - */ - public function removeThetvdbIdFromReleases($tvdbID) - { - $db = new DB(); - $res = $db->queryOneRow(sprintf("SELECT count(ID) AS num FROM releases WHERE tvdbID = %d", $tvdbID)); - $ret = $res["num"]; - $res = $db->exec(sprintf("update releases SET tvdbID = -1 where tvdbID = %d", $tvdbID)); - return $ret; - } - - public function removeAnidbIdFromReleases($anidbID) - { - $db = new DB(); - $res = $db->queryOneRow(sprintf("SELECT count(ID) AS num FROM releases WHERE anidbID = %d", $anidbID)); - $ret = $res["num"]; - $db->exec(sprintf("update releases SET anidbID = -1, episode = null, tvtitle = null, tvairdate = null where anidbID = %d", $anidbID)); - return $ret; - } - - public function getById($id) - { - $db = new DB(); - - return $db->queryOneRow(sprintf("select releases.*, groups.name as group_name from releases left outer join groups on groups.ID = releases.groupID where releases.ID = %d ", $id)); - } - - public function getReleaseNfo($id, $incnfo=true) - { - $db = new DB(); - $selnfo = ($incnfo) ? ', uncompress(nfo) as nfo' : ''; - - return $db->queryOneRow(sprintf("SELECT ID, releaseID" . $selnfo . " FROM releasenfo where releaseID = %d AND nfo IS NOT NULL", $id)); - } - - public function updateGrab($guid) - { - $db = new DB(); - $db->exec(sprintf("update releases set grabs = grabs + 1 where guid = %s", $db->escapeString($guid))); - } - - function processReleases() - { - require_once(WWW_DIR."/lib/binaries.php"); - - $db = new DB; - $currTime_ori = $db->queryOneRow("SELECT NOW() as now"); - $cat = new Category(); - $nzb = new Enzebe(); - $s = new Sites(); - $releaseRegex = new ReleaseRegex(); - $page = new Page(); - $groups = new Groups; - $retcount = 0; - - echo $s->getLicense(); - - echo "\n\nStarting release update process (".date("Y-m-d H:i:s").")\n"; - - if (!file_exists($page->site->nzbpath)) - { - echo "Bad or missing nzb directory - ".$page->site->nzbpath; - return -1; - } - - $this->checkRegexesUptoDate($page->site->latestregexurl, $page->site->latestregexrevision, $page->site->newznabID); - - // - // Get all regexes for all groups which are to be applied to new binaries - // in order of how they should be applied - // - $releaseRegex->get(); - echo "Stage 1 : Applying regex to binaries\n"; - $activeGroups = $groups->getActive(false); - foreach($activeGroups as $groupArr) - { - //check if regexes have already been applied during update binaries - if ($groupArr['regexmatchonly'] == 1) - continue; - - $groupRegexes = $releaseRegex->getForGroup($groupArr['name']); - - echo "Stage 1 : Applying ".sizeof($groupRegexes)." regexes to group ".$groupArr['name']."\n"; - - // Get out all binaries of STAGE0 for current group - $newUnmatchedBinaries = array(); - $ressql = sprintf("SELECT binaries.ID, binaries.name, binaries.date, binaries.totalParts, binaries.procstat, binaries.fromname from binaries where groupID = %d and procstat IN (%d,%d) and regexID IS NULL order by binaries.date asc", $groupArr['ID'], Releases::PROCSTAT_NEW, Releases::PROCSTAT_TITLENOTMATCHED); - $resbin = $db->queryDirect($ressql); - - $matchedbins = 0; - while ($rowbin = $db->getAssocArray($resbin)) - { - $regexMatches = array(); - foreach($groupRegexes as $groupRegex) - { - $regexCheck = $releaseRegex->performMatch($groupRegex, $rowbin['name']); - if ($regexCheck !== false) - { - $regexMatches = $regexCheck; - break; - } - } - - if (!empty($regexMatches)) - { - $matchedbins++; - $relparts = explode("/", $regexMatches['parts']); - $db->exec(sprintf("update binaries set relname = replace(%s, '_', ' '), relpart = %d, reltotalpart = %d, procstat=%d, categoryID=%s, regexID=%d, reqID=%s where ID = %d", - $db->escapeString($regexMatches['name']), $relparts[0], $relparts[1], Releases::PROCSTAT_TITLEMATCHED, $regexMatches['regcatid'], $regexMatches['regexID'], $db->escapeString($regexMatches['reqID']), $rowbin["ID"] )); - } - else - { - if ($rowbin['procstat'] == Releases::PROCSTAT_NEW) - $newUnmatchedBinaries[] = $rowbin['ID']; - } - - } - - //mark as not matched - if (!empty($newUnmatchedBinaries)) - $db->exec(sprintf("update binaries set procstat=%d where ID IN (%s)", Releases::PROCSTAT_TITLENOTMATCHED, implode(',',$newUnmatchedBinaries))); - - } - - // - // Move all binaries from releases which have the correct number of files on to the next stage. - // - echo "Stage 2 : Marking binaries where all parts are available"; - $result = $db->queryDirect(sprintf("SELECT relname, date, SUM(reltotalpart) AS reltotalpart, groupID, reqID, fromname, SUM(num) AS num, coalesce(g.minfilestoformrelease, s.minfilestoformrelease) as minfilestoformrelease FROM ( SELECT relname, reltotalpart, groupID, reqID, fromname, max(date) as date, COUNT(ID) AS num FROM binaries WHERE procstat = %s GROUP BY relname, reltotalpart, groupID, reqID, fromname ORDER BY NULL ) x left outer join groups g on g.ID = x.groupID inner join ( select value as minfilestoformrelease from site where setting = 'minfilestoformrelease' ) s GROUP BY relname, groupID, reqID, fromname, minfilestoformrelease ORDER BY NULL", Releases::PROCSTAT_TITLEMATCHED)); - - while ($row = $db->getAssocArray($result)) - { - $retcount ++; - - // - // Less than the site permitted number of files in a release. Dont discard it, as it may - // be part of a set being uploaded. - // - if ($row["num"] < $row["minfilestoformrelease"]) - { - //echo "Number of files in release ".$row["relname"]." less than site/group setting (".$row['num']."/".$row["minfilestoformrelease"].")\n"; - $db->exec(sprintf("update binaries set procattempts = procattempts + 1 where relname = %s and procstat = %d and groupID = %d and fromname = %s", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) )); - } - - // - // There are the same or more files in our release than the number of files specified - // in the message subject so go ahead and make a release - // - elseif ($row["num"] >= $row["reltotalpart"]) - { - $incomplete = false; - - if ($row['reltotalpart'] == 0 && strtotime($currTime_ori['now']) - strtotime($row['date']) < 14400) - { - $incomplete = true; - } - else - { - // Check that the binary is complete - $binlist = $db->query(sprintf("SELECT binaries.ID, totalParts, date, COUNT(DISTINCT parts.messageID) AS num FROM binaries, parts WHERE binaries.ID=parts.binaryID AND binaries.relname = %s AND binaries.procstat = %d AND binaries.groupID = %d AND binaries.fromname = %s GROUP BY binaries.ID ORDER BY NULL", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) )); - - foreach ($binlist as $rowbin) - { - if ($rowbin['num'] < $rowbin['totalParts']) - { - // Allow to binary to release if posted to usenet longer than four hours ago and we still don't have all the parts - if (!(strtotime($currTime_ori['now']) - strtotime($rowbin['date']) > 14400)) - { - $incomplete = true; - break; - } - } - } - } - - if (!$incomplete) - { - // - // Right number of files, but see if the binary is a allfilled/reqid post, in which case it needs its name looked up - // - if ($row['reqID'] !='' && $page->site->reqidurl != "") - { - // - // Try and get the name using the group - // - $binGroup = $db->queryOneRow(sprintf("SELECT name FROM groups WHERE ID = %d", $row["groupID"])); - $newtitle = $this->getReleaseNameForReqId($page->site->reqidurl, $page->site->newznabID, $binGroup["name"], $row["reqID"]); - - // - // if the feed/group wasnt supported by the scraper, then just use the release name as the title. - // - if ($newtitle == "no feed") - { - $newtitle = $row["relname"]; - } - - // - // Valid release with right number of files and title now, so move it on - // - if ($newtitle != "") - { - $db->exec(sprintf("update binaries set relname = %s, procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - $db->escapeString($newtitle), Releases::PROCSTAT_READYTORELEASE, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - } - else - { - // - // Item not found, if the binary was added to the index yages ago, then give up. - // - $maxaddeddate = $db->queryOneRow(sprintf("SELECT NOW() as now, MAX(dateadded) as dateadded FROM binaries WHERE relname = %s and procstat = %d and groupID = %d and fromname=%s", - $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - - // - // If added to the index over 48 hours ago, give up trying to determine the title - // - if (strtotime($maxaddeddate['now']) - strtotime($maxaddeddate['dateadded']) > (60*60*48)) - { - $db->exec(sprintf("update binaries set procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - Releases::PROCSTAT_NOREQIDNAMELOOKUPFOUND, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - } - } - } - else - { - $db->exec(sprintf("update binaries set procstat=%d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - Releases::PROCSTAT_READYTORELEASE, $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]))); - } - } - } - - // - // Theres less than the expected number of files, so update the attempts and move on. - // - else - { - // pointless updating of attempts, as was creating a lot of database writes for people regex groups with posts without part numbering. - //$db->exec(sprintf("update binaries set procattempts = procattempts + 1 where relname = %s and procstat = %d and groupID = %d and fromname=%s", $db->escapeString($row["relname"]), Releases::PROCSTAT_TITLEMATCHED, $row["groupID"], $db->escapeString($row["fromname"]) )); - } - if ($retcount % 100 == 0) - echo "."; - } - - $retcount=0; - - - echo "\nStage 3 : Creating releases from complete binaries\n"; - // - // Get out all distinct relname, group from binaries of STAGE2 - // - $result = $db->queryDirect(sprintf("SELECT relname, groupID, g.name as group_name, fromname, max(categoryID) as categoryID, max(regexID) as regexID, max(reqID) as reqID, MAX(date) as date, count(binaries.ID) as parts from binaries inner join groups g on g.ID = binaries.groupID where procstat = %d and relname is not null group by relname, g.name, groupID, fromname ORDER BY COUNT(binaries.ID) desc", Releases::PROCSTAT_READYTORELEASE)); - while ($row = $db->getAssocArray($result)) - { - $relguid = md5(uniqid()); - - // - // Get categoryID if one has been allocated to this - // - if ($row["categoryID"] != "") - $catId = $row["categoryID"]; - else - $catId = $cat->determineCategory($row["group_name"], $row["relname"]); - - // Clean release name - $cleanRelName = $this->cleanReleaseName($row['relname']); - $relid = $this->insertRelease($cleanRelName, $row["parts"], $row["groupID"], $relguid, $catId, $row["regexID"], $row["date"], $row["fromname"], $row["reqID"], $page->site); - - // - // Tag every binary for this release with its parent release id - // - $db->exec(sprintf("update binaries set procstat = %d, releaseID = %d where relname = %s and procstat = %d and groupID = %d and fromname=%s", - Releases::PROCSTAT_RELEASED, $relid, $db->escapeString($row["relname"]), Releases::PROCSTAT_READYTORELEASE, $row["groupID"], $db->escapeString($row["fromname"]))); - - // - // Write the nzb to disk - // - $nzbfile = $nzb->getNZBPath($relguid, true); - $nzb->writeNZBforReleaseId($relid, $relguid, $cleanRelName, $catId); - - // - // Remove used binaries - // - $db->exec(sprintf("DELETE parts, binaries FROM parts JOIN binaries ON binaries.ID = parts.binaryID WHERE releaseID = %d ", $relid)); - - // - // If nzb successfully written, then load it and get size completion from it - // - $nzbInfo = new nzbInfo; - if (!$nzbInfo->loadFromFile($nzbfile)) - { - echo "Stage 3 : Failed to write nzb file (bad perms?) ".$nzbfile."\n"; - //copy($nzbfile, "./ERRORNZB_".$relguid); - $this->delete($relid); - } - else - { - // Check if gid already exists - $dupes = $db->queryOneRow(sprintf("SELECT EXISTS(SELECT 1 FROM releases WHERE gid = %s) as total", $db->escapeString($nzbInfo->gid))); - if ($dupes['total'] > 0) - { - echo "Stage 3 : Duplicate - ".$cleanRelName."\n"; - $this->delete($relid); - } - else - { - $db->exec(sprintf("update releases set totalpart = %d, size = %s, completion = %d, GID=%s where ID = %d", $nzbInfo->filecount, $nzbInfo->filesize, $nzbInfo->completion, $db->escapeString($nzbInfo->gid), $relid )); - echo "Stage 3 : Added release ".$cleanRelName."\n"; - - //Increment new release count - $retcount ++; - } - } - } - - // - // Delete any releases under the minimum completion percent. - // - if($page->site->completionpercent != 0) - { - echo "Stage 4 : Deleting releases less than ".$page->site->completionpercent." complete\n"; - $result = $db->query(sprintf("select ID from releases where completion > 0 and completion < %d", $page->site->completionpercent)); - foreach ($result as $row) - $this->delete($row["ID"]); - } - - // - // Delete releases whos minsize is less than the site or group minimum - // - $result = $db->query("select releases.ID from releases left outer join (SELECT g.ID, coalesce(g.minsizetoformrelease, s.minsizetoformrelease) as minsizetoformrelease FROM groups g inner join ( select value as minsizetoformrelease from site where setting = 'minsizetoformrelease' ) s ) x on x.ID = releases.groupID where minsizetoformrelease != 0 and releases.size < minsizetoformrelease"); - if (count($result) > 0) - { - echo "Stage 4 : Deleting ".count($result)." release(s) where size is smaller than minsize for site/group\n"; - foreach ($result as $row) - $this->delete($row["ID"]); - } - - $result = $db->query("select releases.ID, name, categoryID, size FROM releases JOIN ( - select - catc.ID, - case when catc.minsizetoformrelease = 0 then catp.minsizetoformrelease else catc.minsizetoformrelease end as minsizetoformrelease, - case when catc.maxsizetoformrelease = 0 then catp.maxsizetoformrelease else catc.maxsizetoformrelease end as maxsizetoformrelease - from category catp join category catc on catc.parentID = catp.ID - where (catc.minsizetoformrelease != 0 or catc.maxsizetoformrelease != 0) or (catp.minsizetoformrelease != 0 or catp.maxsizetoformrelease != 0) - ) x on x.ID = releases.categoryID - where - (size < minsizetoformrelease and minsizetoformrelease != 0) or - (size > maxsizetoformrelease and maxsizetoformrelease != 0)"); - - if(count($result) > 0) - { - echo "Stage 4 : Deleting release(s) not matching category min/max size ...\n"; - foreach ($result as $r){ - $this->delete($r['ID']); - } - } - - echo "Stage 5 : Post processing started\n"; - $postprocess = new PostProcess(true); - $postprocess->processAll(); - - // - // aggregate the releasefiles upto the releases. - // - echo "Stage 6 : Aggregating Files\n"; - $db->exec("update releases INNER JOIN (SELECT releaseID, COUNT(ID) AS num FROM releasefiles GROUP BY releaseID) b ON b.releaseID = releases.ID and releases.rarinnerfilecount = 0 SET rarinnerfilecount = b.num"); - - // Remove the binaries and parts used to form releases, or that are duplicates. - // - if ($page->site->partsdeletechunks > 0) - { - echo "Stage 7 : Chunk deleting unused binaries and parts"; - $query=sprintf("SELECT parts.ID as partsID,binaries.ID as binariesID FROM parts - LEFT JOIN binaries ON binaries.ID = parts.binaryID - WHERE binaries.dateadded < %s - INTERVAL %d HOUR LIMIT 0,%d", - $db->escapeString($currTime_ori["now"]), ceil($page->site->rawretentiondays*24), - $page->site->partsdeletechunks); - - $cc = 0; - $done=false; - while(!$done) - { - $dd=$cc; - $result=$db->query($query); - if (count($result) > 0) - { - $pID=array();$bID=array(); - foreach ($result as $row) - { - $pID[]=$row['partsID']; - $bID[]=$row['binariesID']; - } - $pID='('.implode(',',$pID).')'; - $bID='('.implode(',',$bID).')'; - $fr = $db->exec("DELETE FROM parts WHERE ID IN {$pID}"); - if($fr>0) - { - $cc+=$fr; - $cc+=$db->exec("DELETE FROM binaries WHERE ID IN {$bID}"); - } - unset($pID);unset($bID); - if($cc==$dd) - { - $done=true; - } - echo ($cc % 10000 ? '.':''); - } - else - { - $done=true; - } - } - echo "\nStage 7 : Complete - ".$cc." rows affected\n"; - } - else - { - echo "Stage 7 : Deleting unused binaries and parts\n"; - $db->exec(sprintf("DELETE parts, binaries FROM parts JOIN binaries ON binaries.ID = parts.binaryID - WHERE binaries.dateadded < %s - INTERVAL %d HOUR", $db->escapeString($currTime_ori["now"]), ceil($page->site->rawretentiondays*24))); - } - - // - // User/Request housekeeping, should ideally move this to its own section, but it needs to be done automatically. - // - $users = new Users; - $users->pruneRequestHistory($page->site->userdownloadpurgedays); - - echo "Done : Added ". $retcount." releases\n\n"; - - return $retcount; - } - - public function insertRelease($cleanRelName, $parts, $group, $guid, $catId, $regexID, $date, $fromname, $reqID, $site) - { - $db = new DB(); - - if ($regexID == "") - $regexID = " null "; - - if ($reqID != "") - $reqID = $db->escapeString($reqID); - else - $reqID = " null "; - - $sql = sprintf("insert into releases (name, searchname, totalpart, groupID, adddate, guid, categoryID, regexID, rageID, postdate, fromname, size, reqID, passwordstatus, completion, haspreview) - values (%s, %s, %d, %d, now(), %s, %d, %s, -1, %s, %s, 0, %s, %d, 100, %d)", - $db->escapeString($cleanRelName), $db->escapeString($cleanRelName), $parts, $group, $db->escapeString($guid), $catId, $regexID, - $db->escapeString($date), $db->escapeString($fromname), $reqID, ($site->checkpasswordedrar > 0 ? -1 : 0), -1); - - $relid = $db->queryInsert($sql); - - return $relid; - } - - public function cleanReleaseName($relname) - { - $cleanArr = array('#', '@', '$', '%', '^', '§', '¨', '©', 'Ö'); - - $relname = str_replace($cleanArr, '', $relname); - $relname = str_replace('_', ' ', $relname); - - return $relname; - } - - public function getReleaseNameForReqId($url, $nnid, $groupname, $reqid) - { - if ($reqid == " null " || $reqid == "0" || $reqid == "") - return ""; - - $url = str_ireplace("[GROUP]", urlencode($groupname), $url); - $url = str_ireplace("[REQID]", urlencode($reqid), $url); - - if ($nnid != "") - { - $url = $url."&newznabID=".$nnid; - } - - $xml = getUrl($url); - - if ($xml === false || preg_match('/no feed/i', $xml)) - return "no feed"; - else { - if ($xml != "") - { - $xmlObj = @simplexml_load_string($xml); - $arrXml = objectsIntoArray($xmlObj); - - if (isset($arrXml["item"]) && is_array($arrXml["item"])) - { - foreach ($arrXml["item"] as $item) - { - $title = (array_key_exists("@attributes", $item) ? $item["@attributes"]["title"] : $item["title"]); - return $title; - } - } - } - } - - return ""; - } - - public function checkRegexesUptoDate($url, $rev, $nnid) - { - if ($url != "") - { - if ($nnid != "") - $nnid = "?newznabID=".$nnid."&rev=".$rev; - - $regfile = getUrl($url.$nnid, "get", "", "gzip"); - if ($regfile !== false && $regfile != "") - { - /*$Rev: 728 $*/ - if (preg_match('/\/\*\$Rev: (\d{3,4})/i', $regfile, $matches)) { - $serverrev = intval($matches[1]); - if ($serverrev > $rev) - { - $db = new DB(); - $site = new Sites; - - $queries = explode(";", $regfile); - $queries = array_map("trim", $queries); - foreach($queries as $q) { - if ($q) { - $db->exec($q); - } - } - - $site->updateLatestRegexRevision($serverrev); - echo "Updated regexes to revision ".$serverrev."\n"; - } - else - { - echo "Using latest regex revision ".$rev."\n"; - } - } - else - { - echo "Error Processing Regex File\n"; - } - } - else - { - echo "Error Regex File Does Not Exist or Unable to Connect\n"; - } - } - } - - public function getTopDownloads() - { - $db = new DB(); - return $db->query("SELECT ID, searchname, guid, adddate, grabs FROM releases - where grabs > 0 - ORDER BY grabs DESC - LIMIT 10" - ); - } - - public function getTopComments() - { - $db = new DB(); - return $db->query("SELECT ID, guid, searchname, adddate, comments FROM releases - where comments > 0 - ORDER BY comments DESC - LIMIT 10" - ); - } - - public function getRecentlyAdded() - { - $db = new DB(); - return $db->query("SELECT concat(cp.title, ' > ', category.title) as title, COUNT(*) AS count - FROM category - left outer join category cp on cp.ID = category.parentID - INNER JOIN releases ON releases.categoryID = category.ID - WHERE releases.adddate > NOW() - INTERVAL 1 WEEK - GROUP BY concat(cp.title, ' > ', category.title) - ORDER BY COUNT(*) DESC"); - } -} \ No newline at end of file