diff --git a/gazelle.sql b/gazelle.sql index 4dafb596..5abf7344 100644 --- a/gazelle.sql +++ b/gazelle.sql @@ -928,27 +928,29 @@ CREATE TABLE `sphinx_t` ( `id` int(11) NOT NULL, `gid` int(11) NOT NULL, `uid` int(11) NOT NULL, - `size` bigint(20) DEFAULT NULL, - `snatched` int(11) DEFAULT NULL, - `seeders` int(11) DEFAULT NULL, - `leechers` int(11) DEFAULT NULL, - `time` int(11) DEFAULT NULL, - `logscore` smallint(6) DEFAULT NULL, - `scene` tinyint(4) DEFAULT NULL, - `haslog` tinyint(4) DEFAULT NULL, - `hascue` tinyint(4) DEFAULT NULL, - `freetorrent` tinyint(4) DEFAULT NULL, - `media` varchar(15) DEFAULT NULL, - `format` varchar(15) DEFAULT NULL, - `encoding` varchar(30) DEFAULT NULL, - `remyear` smallint(6) DEFAULT NULL, - `remtitle` varchar(80) DEFAULT NULL, - `remrlabel` varchar(80) DEFAULT NULL, - `remcnumber` varchar(80) DEFAULT NULL, + `size` bigint(20) NOT NULL, + `snatched` int(11) NOT NULL, + `seeders` int(11) NOT NULL, + `leechers` int(11) NOT NULL, + `time` int(11) NOT NULL, + `logscore` smallint(6) NOT NULL, + `scene` tinyint(4) NOT NULL, + `haslog` tinyint(4) NOT NULL, + `hascue` tinyint(4) NOT NULL, + `freetorrent` tinyint(4) NOT NULL, + `media` varchar(15) NOT NULL, + `format` varchar(15) NOT NULL, + `encoding` varchar(30) NOT NULL, + `remyear` smallint(6) NOT NULL, + `remtitle` varchar(80) NOT NULL, + `remrlabel` varchar(80) NOT NULL, + `remcnumber` varchar(80) NOT NULL, `filelist` mediumtext, - `remident` int(10) unsigned DEFAULT NULL, + `remident` int(10) unsigned NOT NULL, + `description` text, PRIMARY KEY (`id`), - KEY `gid_remident` (`gid`,`remident`) + KEY `gid_remident` (`gid`,`remident`), + KEY `format` (`format`) ) ENGINE=InnoDB CHARSET utf8; CREATE TABLE `sphinx_tg` ( @@ -1322,7 +1324,8 @@ CREATE TABLE `users_donor_ranks` ( PRIMARY KEY (`UserID`), KEY `DonationTime` (`DonationTime`), KEY `SpecialRank` (`SpecialRank`), - KEY `Rank` (`Rank`) + KEY `Rank` (`Rank`), + KEY `TotalRank` (`TotalRank`) ) ENGINE=InnoDB CHARSET utf8; CREATE TABLE `users_downloads` ( diff --git a/sections/ajax/browse.php b/sections/ajax/browse.php index d8742a99..e5f04cdb 100644 --- a/sections/ajax/browse.php +++ b/sections/ajax/browse.php @@ -4,7 +4,7 @@ // The "order by x" links on columns headers function header_link($SortKey, $DefaultWay = 'desc') { - global $OrderBy,$OrderWay; + global $OrderBy, $OrderWay; if ($SortKey == $OrderBy) { if ($OrderWay == 'desc') { $NewWay = 'asc'; @@ -14,11 +14,32 @@ function header_link($SortKey, $DefaultWay = 'desc') { } else { $NewWay = $DefaultWay; } - return "torrents.php?order_way=$NewWay&order_by=$SortKey&".Format::get_url(array('order_way', 'order_by')); } /** Start default parameters and validation **/ +if (!empty($_GET['searchstr']) || !empty($_GET['groupname'])) { + if (!empty($_GET['searchstr'])) { + $InfoHash = $_GET['searchstr']; + } else { + $InfoHash = $_GET['groupname']; + } + + // Search by infohash + if ($InfoHash = is_valid_torrenthash($InfoHash)) { + $InfoHash = db_string(pack('H*', $InfoHash)); + $DB->query(" + SELECT ID, GroupID + FROM torrents + WHERE info_hash = '$InfoHash'"); + if ($DB->has_results()) { + list($ID, $GroupID) = $DB->next_record(); + header("Location: torrents.php?id=$GroupID&torrentid=$ID"); + die(); + } + } +} + // Setting default search options if (!empty($_GET['setdefault'])) { $UnsetList = array('page', 'setdefault'); @@ -51,7 +72,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { WHERE UserID = '".db_string($LoggedUser['ID'])."'"); list($SiteOptions) = $DB->next_record(MYSQLI_NUM, false); $SiteOptions = unserialize($SiteOptions); - $SiteOptions['DefaultSearch']=''; + $SiteOptions['DefaultSearch'] = ''; $DB->query(" UPDATE users_info SET SiteOptions = '".db_string(serialize($SiteOptions))."' @@ -89,12 +110,14 @@ function header_link($SortKey, $DefaultWay = 'desc') { 'leechers' => array('sumleechers', 'leechers'), 'snatched' => array('sumsnatched', 'snatched'), 'random' => false); + $AggregateExp = array( 'maxsize' => 'MAX(size) AS maxsize', 'sumseeders' => 'SUM(seeders) AS sumseeders', 'sumleechers' => 'SUM(leechers) AS sumleechers', 'sumsnatched' => 'SUM(snatched) AS sumsnatched'); } else { + $GroupResults = false; $SortOrders = array( 'year' => 'year', 'time' => 'id', @@ -160,7 +183,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { $Filtered = false; $EnableNegation = false; // Sphinx needs at least one positive search condition to support the NOT operator -// Filelist searches makes use of the proximity operator to ensure that all keywords match the same file +// File list searches make use of the proximity operator to ensure that all keywords match the same file if (!empty($_GET['filelist'])) { $SearchString = trim($_GET['filelist']); if ($SearchString !== '') { @@ -173,12 +196,10 @@ function header_link($SortKey, $DefaultWay = 'desc') { } // Collect all entered search terms to find out whether to enable the NOT operator -$GroupFields = array('artistname', 'groupname', 'recordlabel', 'cataloguenumber', 'taglist'); -$TorrentFields = array('remastertitle', 'remasteryear', 'remasterrecordlabel', 'remastercataloguenumber', 'encoding', 'format', 'media'); $SearchWords = array(); foreach (array('artistname', 'groupname', 'recordlabel', 'cataloguenumber', 'taglist', 'remastertitle', 'remasteryear', 'remasterrecordlabel', - 'remastercataloguenumber', 'encoding', 'format', 'media') as $Search) { + 'remastercataloguenumber', 'encoding', 'format', 'media', 'description') as $Search) { if (!empty($_GET[$Search])) { $SearchString = trim($_GET[$Search]); if ($SearchString !== '') { @@ -191,7 +212,11 @@ function header_link($SortKey, $DefaultWay = 'desc') { } foreach ($Words as $Word) { $Word = trim($Word); - if ($Word[0] == '!' && strlen($Word) >= 2) { + // Skip isolated hyphens to enable "Artist - Title" searches + if ($Word === '-') { + continue; + } + if ($Word[0] === '!' && strlen($Word) >= 2) { if (strpos($Word, '!', 1) === false) { $SearchWords[$Search]['exclude'][] = $Word; } else { @@ -216,8 +241,12 @@ function header_link($SortKey, $DefaultWay = 'desc') { $BasicSearch = array('include' => array(), 'exclude' => array()); foreach ($Words as $Word) { $Word = trim($Word); - if ($Word[0] == '!' && strlen($Word) >= 2) { - if ($Word == '!100%') { + // Skip isolated hyphens to enable "Artist - Title" searches + if ($Word === '-') { + continue; + } + if ($Word[0] === '!' && strlen($Word) >= 2) { + if ($Word === '!100%') { $_GET['haslog'] = '-1'; } elseif (strpos($Word, '!', 1) === false) { $BasicSearch['exclude'][] = $Word; @@ -274,7 +303,51 @@ function header_link($SortKey, $DefaultWay = 'desc') { // Tag list if (!empty($SearchWords['taglist'])) { + //Get tag aliases. + $TagAliases = $Cache->get_value('tag_aliases_search'); + if ($TagAliases === false) { + $DB->query(' + SELECT ID, BadTag, AliasTag + FROM tag_aliases + ORDER BY BadTag'); + $TagAliases = $DB->to_array(false, MYSQLI_ASSOC, false); + //Unify tag aliases to be in_this_format as tags not in.this.format + array_walk_recursive($TagAliases, create_function('&$val', '$val = preg_replace("/\./","_", $val);')); + //Clean up the array for smaller cache size + foreach ($TagAliases as &$TagAlias) { + foreach (array_keys($TagAlias) as $Key) { + if (is_numeric($Key)) { + unset($TagAlias[$Key]); + } + } + } + $Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days + } + //Get tags $Tags = $SearchWords['taglist']; + //Replace bad tags with tag aliases + $End = count($Tags['include']); + for ($i = 0; $i < $End; $i++) { + foreach ($TagAliases as $TagAlias) { + if ($Tags['include'][$i] === $TagAlias['BadTag']) { + $Tags['include'][$i] = $TagAlias['AliasTag']; + break; + } + } + } + $End = count($Tags['exclude']); + for ($i = 0; $i < $End; $i++) { + foreach ($TagAliases as $TagAlias) { + if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) { + $Tags['exclude'][$i] = '!'.$TagAlias['AliasTag']; + break; + } + } + } + //Only keep unique entries after unifying tag standard + $Tags['include'] = array_unique($Tags['include']); + $Tags['exclude'] = array_unique($Tags['exclude']); + $TagListString = implode(', ', array_merge($Tags['include'], $Tags['exclude'])); if (!$EnableNegation && !empty($Tags['exclude'])) { $Tags['include'] = array_merge($Tags['include'], $Tags['exclude']); unset($Tags['exclude']); @@ -290,13 +363,15 @@ function header_link($SortKey, $DefaultWay = 'desc') { $QueryParts = array(); // 'All' tags - if (!isset($_GET['tags_type']) || $_GET['tags_type'] === '1') { + if (!isset($_GET['tags_type']) || $_GET['tags_type'] == 1) { $_GET['tags_type'] = '1'; $Tags = array_merge($Tags['include'], $Tags['exclude']); if (!empty($Tags)) { $QueryParts[] = implode(' ', $Tags); } - } else { // 'Any' tags + } + // 'Any' tags + else { $_GET['tags_type'] = '0'; if (!empty($Tags['include'])) { $QueryParts[] = '( '.implode(' | ', $Tags['include']).' )'; @@ -311,9 +386,13 @@ function header_link($SortKey, $DefaultWay = 'desc') { $Filtered = true; } unset($SearchWords['taglist']); -} elseif (!isset($_GET['tags_type'])) { +} +elseif (!isset($_GET['tags_type'])) { $_GET['tags_type'] = '1'; } +if (!isset($TagListString)) { + $TagListString = ""; +} foreach ($SearchWords as $Search => $Words) { $QueryParts = array(); @@ -385,7 +464,8 @@ function header_link($SortKey, $DefaultWay = 'desc') { $SphQLTor->where($Search, $_GET[$Search]); } if ($_GET[$Search] !== 0) { - // Hack! Deleted torrents may show up if we set to true unconditionally. Hope no one notices + // This condition is required because all attributes are 0 + // for deleted torrents and we abuse that to detect them $Filtered = true; } } @@ -457,7 +537,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { if (check_perms('site_search_many')) { $Page = $_GET['page']; } else { - $Page = min(SPHINX_MAX_MATCHES/TORRENTS_PER_PAGE, $_GET['page']); + $Page = min(SPHINX_MAX_MATCHES / TORRENTS_PER_PAGE, $_GET['page']); } $Offset = ($Page - 1) * TORRENTS_PER_PAGE; $SphQL->limit($Offset, TORRENTS_PER_PAGE, $Offset + TORRENTS_PER_PAGE); @@ -482,6 +562,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { if ($TorrentCount) { $Groups = Torrents::get_groups($GroupIDs); + if (!empty($Groups) && $GroupResults) { $TorrentIDs = array(); foreach ($Groups as $Group) { @@ -489,11 +570,12 @@ function header_link($SortKey, $DefaultWay = 'desc') { $TorrentIDs = array_merge($TorrentIDs, array_keys($Group['Torrents'])); } } - - // Get a list of all torrent IDs that match the search query - $SphQLTor->where('id', $TorrentIDs)->limit(0, count($TorrentIDs), count($TorrentIDs)); - $SphQLResultTor = $SphQLTor->query(); - $TorrentIDs = array_fill_keys($SphQLResultTor->collect('id'), true); + if (!empty($TorrentIDs)) { + // Get a list of all torrent ids that match the search query + $SphQLTor->where('id', $TorrentIDs)->limit(0, count($TorrentIDs), count($TorrentIDs)); + $SphQLResultTor = $SphQLTor->query(); + $TorrentIDs = array_fill_keys($SphQLResultTor->collect('id'), true); + } } } /** End run search query and collect results **/ diff --git a/sections/torrents/browse2.php b/sections/torrents/browse2.php index d95b825f..26edcf2e 100644 --- a/sections/torrents/browse2.php +++ b/sections/torrents/browse2.php @@ -20,10 +20,8 @@ * *************************************************************************/ - include(SERVER_ROOT.'/sections/torrents/functions.php'); - // The "order by x" links on columns headers function header_link($SortKey, $DefaultWay = 'desc') { global $OrderBy, $OrderWay; @@ -170,7 +168,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { array_pop($Bitrates); // remove 'other' $SearchBitrates = array_merge($Bitrates, array('v0', 'v1', 'v2', '24bit')); -foreach ($SearchBitrates as $ID=>$Val) { +foreach ($SearchBitrates as $ID => $Val) { $SearchBitrates[$ID] = strtolower($Val); } foreach ($Formats as $ID => $Val) { @@ -208,7 +206,7 @@ function header_link($SortKey, $DefaultWay = 'desc') { // File list searches make use of the proximity operator to ensure that all keywords match the same file if (!empty($_GET['filelist'])) { $SearchString = trim($_GET['filelist']); - if ($SearchString != '') { + if ($SearchString !== '') { $SearchString = '"'.Sphinxql::sph_escape_string($_GET['filelist']).'"~20'; $SphQL->where_match($SearchString, 'filelist', false); $SphQLTor->where_match($SearchString, 'filelist', false); @@ -218,15 +216,13 @@ function header_link($SortKey, $DefaultWay = 'desc') { } // Collect all entered search terms to find out whether to enable the NOT operator -$GroupFields = array('artistname', 'groupname', 'recordlabel', 'cataloguenumber', 'taglist'); -$TorrentFields = array('remastertitle', 'remasteryear', 'remasterrecordlabel', 'remastercataloguenumber', 'encoding', 'format', 'media'); $SearchWords = array(); foreach (array('artistname', 'groupname', 'recordlabel', 'cataloguenumber', 'taglist', 'remastertitle', 'remasteryear', 'remasterrecordlabel', - 'remastercataloguenumber', 'encoding', 'format', 'media') as $Search) { + 'remastercataloguenumber', 'encoding', 'format', 'media', 'description') as $Search) { if (!empty($_GET[$Search])) { $SearchString = trim($_GET[$Search]); - if ($SearchString != '') { + if ($SearchString !== '') { $SearchWords[$Search] = array('include' => array(), 'exclude' => array()); if ($Search == 'taglist') { $SearchString = strtr($SearchString, '.', '_'); @@ -237,17 +233,17 @@ function header_link($SortKey, $DefaultWay = 'desc') { foreach ($Words as $Word) { $Word = trim($Word); // Skip isolated hyphens to enable "Artist - Title" searches - if ($Word == '-') { + if ($Word === '-') { continue; } - if ($Word[0] == '!' && strlen($Word) >= 2) { + if ($Word[0] === '!' && strlen($Word) >= 2) { if (strpos($Word, '!', 1) === false) { $SearchWords[$Search]['exclude'][] = $Word; } else { $SearchWords[$Search]['include'][] = $Word; $EnableNegation = true; } - } elseif ($Word != '') { + } elseif ($Word !== '') { $SearchWords[$Search]['include'][] = $Word; $EnableNegation = true; } @@ -266,11 +262,11 @@ function header_link($SortKey, $DefaultWay = 'desc') { foreach ($Words as $Word) { $Word = trim($Word); // Skip isolated hyphens to enable "Artist - Title" searches - if ($Word == '-') { + if ($Word === '-') { continue; } - if ($Word[0] == '!' && strlen($Word) >= 2) { - if ($Word == '!100%') { + if ($Word[0] === '!' && strlen($Word) >= 2) { + if ($Word === '!100%') { $_GET['haslog'] = '-1'; } elseif (strpos($Word, '!', 1) === false) { $BasicSearch['exclude'][] = $Word; @@ -284,9 +280,9 @@ function header_link($SortKey, $DefaultWay = 'desc') { } elseif (in_array($Word, $SearchFormats)) { $FilterFormats[] = $Word; $EnableNegation = true; - } elseif ($Word == '100%') { + } elseif ($Word === '100%') { $_GET['haslog'] = '100'; - } elseif ($Word != '') { + } elseif ($Word !== '') { $BasicSearch['include'][] = $Word; $EnableNegation = true; } @@ -327,18 +323,17 @@ function header_link($SortKey, $DefaultWay = 'desc') { // Tag list if (!empty($SearchWords['taglist'])) { - global $Cache, $DB; - //Get tag aliases. + // Get tag aliases. $TagAliases = $Cache->get_value('tag_aliases_search'); - if (!$TagAliases) { + if ($TagAliases === false) { $DB->query(' SELECT ID, BadTag, AliasTag FROM tag_aliases ORDER BY BadTag'); - $TagAliases = $DB->to_array(); - //Unify tag aliases to be in_this_format as tags not in.this.format + $TagAliases = $DB->to_array(false, MYSQLI_ASSOC, false); + // Unify tag aliases to be in_this_format as tags not in.this.format array_walk_recursive($TagAliases, create_function('&$val', '$val = preg_replace("/\./","_", $val);')); - //Clean up the array for smaller cache size + // Clean up the array for smaller cache size foreach ($TagAliases as &$TagAlias) { foreach (array_keys($TagAlias) as $Key) { if (is_numeric($Key)) { @@ -348,11 +343,11 @@ function header_link($SortKey, $DefaultWay = 'desc') { } $Cache->cache_value('tag_aliases_search', $TagAliases, 3600 * 24 * 7); // cache for 7 days } - //Get tags + // Get tags $Tags = $SearchWords['taglist']; - //Replace bad tags with tag aliases - //In other news oh God I'm going to hell for all this preg_replace, but they're kept in two separate formats - for ($i = 0; $i < sizeof($Tags['include']) ; $i++) { + // Replace bad tags with tag aliases + $End = count($Tags['include']); + for ($i = 0; $i < $End; $i++) { foreach ($TagAliases as $TagAlias) { if ($Tags['include'][$i] === $TagAlias['BadTag']) { $Tags['include'][$i] = $TagAlias['AliasTag']; @@ -360,15 +355,16 @@ function header_link($SortKey, $DefaultWay = 'desc') { } } } - for ($i = 0; $i < sizeof($Tags['exclude']) ; $i++) { + $End = count($Tags['exclude']); + for ($i = 0; $i < $End; $i++) { foreach ($TagAliases as $TagAlias) { - if (preg_replace('/^!/', '', $Tags['exclude'][$i]) === $TagAlias['BadTag']) { + if (substr($Tags['exclude'][$i], 1) === $TagAlias['BadTag']) { $Tags['exclude'][$i] = '!'.$TagAlias['AliasTag']; break; } } } - //Only keep unique entries after unifying tag standard + // Only keep unique entries after unifying tag standard $Tags['include'] = array_unique($Tags['include']); $Tags['exclude'] = array_unique($Tags['exclude']); $TagListString = implode(', ', array_merge($Tags['include'], $Tags['exclude'])); @@ -488,8 +484,8 @@ function header_link($SortKey, $DefaultWay = 'desc') { $SphQLTor->where($Search, $_GET[$Search]); } if ($_GET[$Search] !== 0) { - //TODO: Clean up this hack - // Hack! Deleted torrents may show up if we set to true unconditionally. Hope no one notices + // This condition is required because all attributes are 0 + // for deleted torrents and we abuse that to detect them $Filtered = true; } } @@ -713,6 +709,12 @@ function header_link($SortKey, $DefaultWay = 'desc') { + + Torrent description: + + + + Rip specifics: @@ -782,9 +784,9 @@ function header_link($SortKey, $DefaultWay = 'desc') { - Tags (comma-separated): + Tags (comma-separated): -   +   />   /> diff --git a/sphinx.conf b/sphinx.conf index 5f07082b..b8a14df2 100644 --- a/sphinx.conf +++ b/sphinx.conf @@ -48,12 +48,12 @@ source torrents : torrents_base { sql_query_pre = truncate sphinx_t sql_query_pre = insert into sphinx_t \ (id, gid, size, snatched, seeders, leechers, time, logscore, scene, \ - haslog, hascue, freetorrent, media, format, encoding, \ + haslog, hascue, freetorrent, description, media, format, encoding, \ remyear, remtitle, remrlabel, remcnumber, filelist, uid, remident) \ select id, groupid, size, snatched, seeders, leechers, unix_timestamp(time), \ logscore, cast(scene as char), cast(haslog as char), \ - cast(hascue as char), cast(freetorrent as char), media, \ - format, encoding, remasteryear, remastertitle, \ + cast(hascue as char), cast(freetorrent as char), description, \ + media, format, encoding, remasteryear, remastertitle, \ remasterrecordlabel, remastercataloguenumber, filelist, userid, \ crc32(concat_ws(' ', media, remasteryear, remastertitle, \ remasterrecordlabel, remastercataloguenumber)) \ @@ -77,7 +77,7 @@ source torrents : torrents_base { cnumber cataloguenumber, catid categoryid, \ t.time, reltype releasetype, size>>10 size, \ snatched, seeders, leechers, logscore, scene, \ - vanityhouse, haslog, hascue, freetorrent, \ + vanityhouse, haslog, hascue, freetorrent, description, \ media, format, encoding, remyear remasteryear, \ remtitle remastertitle, remrlabel remasterrecordlabel, \ remcnumber remastercataloguenumber, \