/** * Function for searching on the site (by subject, searchname or advanced). * * @param string $searchName * @param string $usenetName * @param string $posterName * @param string $groupName * @param int $sizeFrom * @param int $sizeTo * @param int $hasNfo * @param int $hasComments * @param int $daysNew * @param int $daysOld * @param int $offset * @param int $limit * @param string $orderBy * @param int $maxAge * @param integer[] $excludedCats * @param string $type * @param array $cat * * @return array */ public function search($searchName, $usenetName, $posterName, $groupName, $sizeFrom, $sizeTo, $hasNfo, $hasComments, $daysNew, $daysOld, $offset = 0, $limit = 1000, $orderBy = '', $maxAge = -1, $excludedCats = [], $type = 'basic', $cat = [-1]) { $sizeRange = [1 => 1, 2 => 2.5, 3 => 5, 4 => 10, 5 => 20, 6 => 30, 7 => 40, 8 => 80, 9 => 160, 10 => 320, 11 => 640]; if ($orderBy == '') { $orderBy = []; $orderBy[0] = 'postdate '; $orderBy[1] = 'desc '; } else { $orderBy = $this->getBrowseOrder($orderBy); } $searchOptions = []; if ($searchName != -1) { $searchOptions['searchname'] = $searchName; } if ($usenetName != -1) { $searchOptions['name'] = $usenetName; } if ($posterName != -1) { $searchOptions['fromname'] = $posterName; } $whereSql = sprintf("%s\n\t\t\tWHERE r.passwordstatus %s AND r.nzbstatus = %d %s %s %s %s %s %s %s %s %s %s %s", $this->releaseSearch->getFullTextJoinString(), $this->showPasswords(), NZB::NZB_ADDED, $maxAge > 0 ? sprintf(' AND r.postdate > (NOW() - INTERVAL %d DAY) ', $maxAge) : '', $groupName != -1 ? sprintf(' AND r.group_id = %d ', $this->groups->getIDByName($groupName)) : '', array_key_exists($sizeFrom, $sizeRange) ? ' AND r.size > ' . (string) (104857600 * (int) $sizeRange[$sizeFrom]) . ' ' : '', array_key_exists($sizeTo, $sizeRange) ? ' AND r.size < ' . (string) (104857600 * (int) $sizeRange[$sizeTo]) . ' ' : '', $hasNfo != 0 ? ' AND r.nfostatus = 1 ' : '', $hasComments != 0 ? ' AND r.comments > 0 ' : '', $type !== 'advanced' ? $this->categorySQL($cat) : ($cat[0] != '-1' ? sprintf(' AND (r.categoryid = %d) ', $cat[0]) : ''), $daysNew != -1 ? sprintf(' AND r.postdate < (NOW() - INTERVAL %d DAY) ', $daysNew) : '', $daysOld != -1 ? sprintf(' AND r.postdate > (NOW() - INTERVAL %d DAY) ', $daysOld) : '', count($excludedCats) > 0 ? ' AND r.categoryid NOT IN (' . implode(',', $excludedCats) . ')' : '', count($searchOptions) > 0 ? $this->releaseSearch->getSearchSQL($searchOptions) : ''); $baseSql = sprintf("SELECT r.*,\n\t\t\t\tCONCAT(cp.title, ' > ', c.title) AS category_name,\n\t\t\t\tCONCAT(cp.id, ',', c.id) AS category_ids,\n\t\t\t\tgroups.name AS group_name,\n\t\t\t\trn.id AS nfoid,\n\t\t\t\tre.releaseid AS reid,\n\t\t\t\tcp.id AS categoryparentid\n\t\t\tFROM releases r\n\t\t\tLEFT OUTER JOIN video_data re ON re.releaseid = r.id\n\t\t\tLEFT OUTER JOIN release_nfos rn ON rn.releaseid = r.id\n\t\t\tINNER JOIN groups ON groups.id = r.group_id\n\t\t\tINNER JOIN category c ON c.id = r.categoryid\n\t\t\tINNER JOIN category cp ON cp.id = c.parentid\n\t\t\t%s", $whereSql); $sql = sprintf("SELECT * FROM (\n\t\t\t\t%s\n\t\t\t) r\n\t\t\tORDER BY r.%s %s\n\t\t\tLIMIT %d OFFSET %d", $baseSql, $orderBy[0], $orderBy[1], $limit, $offset); $releases = $this->pdo->query($sql); if ($releases && count($releases)) { $releases[0]['_totalrows'] = $this->getPagerCount($baseSql); } return $releases; }
/** * Test a single release naming regex for a group name. * * @param string $groupName * @param string $regex * @param int $displayLimit * @param int $queryLimit * * @return array */ public function testReleaseNamingRegex($groupName, $regex, $displayLimit, $queryLimit) { $groups = new Groups(['Settings' => $this->pdo]); $groupID = $groups->getIDByName($groupName); if (!$groupID) { return []; } $rows = $this->pdo->query(sprintf('SELECT name, searchname, id FROM releases WHERE group_id = %d LIMIT %d', $groupID, $queryLimit)); $data = []; if ($rows) { $limit = 1; foreach ($rows as $row) { $match = $this->_matchRegex($regex, $row['name']); if ($match) { $data[$row['id']] = ['subject' => $row['name'], 'old_name' => $row['searchname'], 'new_name' => $match]; if ($limit++ > $displayLimit) { break; } } } } return $data; }
/** * Returns unix time for an article number. * * @param int $post The article number to get the time from. * @param array $groupData Usenet group info from NNTP selectGroup method. * * @return int Timestamp. */ public function postdate($post, array $groupData) { // Set table names $groupID = $this->_groups->getIDByName($groupData['group']); $group = []; if ($groupID !== '') { $group = $this->_groups->getCBPTableNames($this->_tablePerGroup, $groupID); } $currentPost = $post; $attempts = $date = 0; do { // Try to get the article date locally first. if ($groupID !== '') { // Try to get locally. $local = $this->_pdo->queryOneRow(sprintf(' SELECT c.date AS date FROM %s c INNER JOIN %s b ON(c.id=b.collection_id) INNER JOIN %s p ON(b.id=p.binaryid) WHERE p.number = %s %s LIMIT 1', $group['cname'], $group['bname'], $group['pname'], $currentPost, $this->_tablePerGroup === false ? sprintf('AND c.group_id = %d', $groupID) : '')); if ($local !== false) { $date = $local['date']; break; } } // If we could not find it locally, try usenet. $header = $this->_nntp->getXOVER($currentPost); if (!$this->_nntp->isError($header)) { // Check if the date is set. if (isset($header[0]['Date']) && strlen($header[0]['Date']) > 0) { $date = $header[0]['Date']; break; } } // Try to get a different article number. if (abs($currentPost - $groupData['first']) > abs($groupData['last'] - $currentPost)) { $tempPost = round($currentPost / (mt_rand(1005, 1012) / 1000), 0, PHP_ROUND_HALF_UP); if ($tempPost < $groupData['first']) { $tempPost = $groupData['first']; } } else { $tempPost = round(mt_rand(1005, 1012) / 1000 * $currentPost, 0, PHP_ROUND_HALF_UP); if ($tempPost > $groupData['last']) { $tempPost = $groupData['last']; } } // If we got the same article number as last time, give up. if ($tempPost === $currentPost) { break; } $currentPost = $tempPost; if ($this->_debug) { $this->_colorCLI->doEcho($this->_colorCLI->debug('Postdate retried ' . $attempts . " time(s).")); } } while ($attempts++ <= 20); // If we didn't get a date, set it to now. if (!$date) { $date = time(); } else { $date = strtotime($date); } if ($this->_debug) { $this->_debugging->log(get_class(), __FUNCTION__, 'Article (' . $post . "'s) date is (" . $date . ') (' . $this->daysOld($date) . " days old)", Logger::LOG_INFO); } return $date; }