BioTorrents.de’s version of Gazelle
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

browse.php 40KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033
  1. <?php
  2. include(SERVER_ROOT.'/sections/torrents/functions.php');
  3. // The "order by x" links on columns headers
  4. function header_link($SortKey, $DefaultWay = 'desc')
  5. {
  6. global $OrderBy, $OrderWay;
  7. if ($SortKey === $OrderBy) {
  8. if ($OrderWay === 'desc') {
  9. $NewWay = 'asc';
  10. } else {
  11. $NewWay = 'desc';
  12. }
  13. } else {
  14. $NewWay = $DefaultWay;
  15. }
  16. return "torrents.php?order_way=$NewWay&amp;order_by=$SortKey&amp;".Format::get_url(['order_way', 'order_by']);
  17. }
  18. if (!empty($_GET['searchstr']) || !empty($_GET['groupname'])) {
  19. if (!empty($_GET['searchstr'])) {
  20. $InfoHash = $_GET['searchstr'];
  21. } else {
  22. $InfoHash = $_GET['groupname'];
  23. }
  24. // Search by info hash
  25. if ($InfoHash = is_valid_torrenthash($InfoHash)) {
  26. $InfoHash = db_string(pack('H*', $InfoHash));
  27. $DB->query("
  28. SELECT ID, GroupID
  29. FROM torrents
  30. WHERE info_hash = '$InfoHash'");
  31. if ($DB->has_results()) {
  32. list($ID, $GroupID) = $DB->next_record();
  33. header("Location: torrents.php?id=$GroupID&torrentid=$ID");
  34. die();
  35. }
  36. }
  37. }
  38. // Setting default search options
  39. if (!empty($_GET['setdefault'])) {
  40. $UnsetList = ['page', 'setdefault'];
  41. $UnsetRegexp = '/(&|^)('.implode('|', $UnsetList).')=.*?(&|$)/i';
  42. $DB->query("
  43. SELECT SiteOptions
  44. FROM users_info
  45. WHERE UserID = ?", $LoggedUser['ID']);
  46. list($SiteOptions) = $DB->next_record(MYSQLI_NUM, false);
  47. $SiteOptions = json_decode($SiteOptions, true) ?? [];
  48. $SiteOptions['DefaultSearch'] = preg_replace($UnsetRegexp, '', $_SERVER['QUERY_STRING']);
  49. $DB->query("
  50. UPDATE users_info
  51. SET SiteOptions = ?
  52. WHERE UserID = ?", json_encode($SiteOptions), $LoggedUser['ID']);
  53. $Cache->begin_transaction("user_info_heavy_$UserID");
  54. $Cache->update_row(false, ['DefaultSearch' => $SiteOptions['DefaultSearch']]);
  55. $Cache->commit_transaction(0);
  56. // Clearing default search options
  57. } elseif (!empty($_GET['cleardefault'])) {
  58. $DB->query("
  59. SELECT SiteOptions
  60. FROM users_info
  61. WHERE UserID = ?", $LoggedUser['ID']);
  62. list($SiteOptions) = $DB->next_record(MYSQLI_NUM, false);
  63. $SiteOptions = json_decode($SiteOptions, true) ?? [];
  64. $SiteOptions['DefaultSearch'] = '';
  65. $DB->query("
  66. UPDATE users_info
  67. SET SiteOptions = ?
  68. WHERE UserID = ?", json_encode($SiteOptions), $LoggedUser['ID']);
  69. $Cache->begin_transaction("user_info_heavy_$UserID");
  70. $Cache->update_row(false, ['DefaultSearch' => '']);
  71. $Cache->commit_transaction(0);
  72. // Use default search options
  73. } elseif (empty($_SERVER['QUERY_STRING']) || (count($_GET) === 1 && isset($_GET['page']))) {
  74. if (!empty($LoggedUser['DefaultSearch'])) {
  75. if (!empty($_GET['page'])) {
  76. $Page = $_GET['page'];
  77. parse_str($LoggedUser['DefaultSearch'], $_GET);
  78. $_GET['page'] = $Page;
  79. } else {
  80. parse_str($LoggedUser['DefaultSearch'], $_GET);
  81. }
  82. }
  83. }
  84. // Terms were not submitted via the search form
  85. if (isset($_GET['searchsubmit'])) {
  86. $GroupResults = !empty($_GET['group_results']);
  87. } else {
  88. $GroupResults = !$LoggedUser['DisableGrouping2'];
  89. }
  90. if (!empty($_GET['order_way']) && $_GET['order_way'] === 'asc') {
  91. $OrderWay = 'asc';
  92. } else {
  93. $OrderWay = 'desc';
  94. }
  95. if (empty($_GET['order_by']) || !isset(TorrentSearch::$SortOrders[$_GET['order_by']])) {
  96. $OrderBy = 'time'; // For header links
  97. } else {
  98. $OrderBy = $_GET['order_by'];
  99. }
  100. $Page = !empty($_GET['page']) ? (int) $_GET['page'] : 1;
  101. $Search = new TorrentSearch($GroupResults, $OrderBy, $OrderWay, $Page, TORRENTS_PER_PAGE);
  102. # Three profile toggle options
  103. if (isset($LoggedUser['HideLolicon']) && $LoggedUser['HideLolicon'] === 1) {
  104. $Search->insert_hidden_tags('!lolicon !shotacon !toddlercon');
  105. }
  106. # 2
  107. if (isset($LoggedUser['HideScat']) && $LoggedUser['HideScat'] === 1) {
  108. $Search->insert_hidden_tags('!scat');
  109. }
  110. # 3
  111. if (isset($LoggedUser['HideSnuff']) && $LoggedUser['HideSnuff'] === 1) {
  112. $Search->insert_hidden_tags('!snuff');
  113. }
  114. $Results = $Search->query($_GET);
  115. $Groups = $Search->get_groups();
  116. $NumResults = $Search->record_count();
  117. $HideFilter = isset($LoggedUser['ShowTorFilter']) && $LoggedUser['ShowTorFilter'] === 0;
  118. // This is kinda ugly, but the enormous if paragraph was really hard to read
  119. $AdvancedSearch = !empty($_GET['action']) && $_GET['action'] === 'advanced';
  120. $AdvancedSearch |= !empty($LoggedUser['SearchType']) && (empty($_GET['action']) || $_GET['action'] === 'advanced');
  121. $AdvancedSearch &= check_perms('site_advanced_search');
  122. if ($AdvancedSearch) {
  123. $Action = 'action=advanced';
  124. $HideBasic = ' hidden';
  125. $HideAdvanced = '';
  126. } else {
  127. $Action = 'action=basic';
  128. $HideBasic = '';
  129. $HideAdvanced = ' hidden';
  130. }
  131. # Start the search form
  132. # Fortunately it's very easy to search via
  133. # torrentsearch.class.php
  134. View::show_header('Browse Torrents', 'browse');
  135. ?>
  136. <div class="thin widethin">
  137. <div class="header">
  138. <h2>Torrents</h2>
  139. </div>
  140. <form class="search_form" name="torrents" method="get" onsubmit="$(this).disableUnset();">
  141. <div class="box filter_torrents">
  142. <div class="head">
  143. <strong>
  144. <span id="ft_basic" class="<?=$HideBasic?>">Basic Search
  145. (<a class="clickable" onclick="toggleTorrentSearch('advanced')">Advanced</a>)</span>
  146. <span id="ft_advanced" class="<?=$HideAdvanced?>">Advanced
  147. Search (<a class="clickable" onclick="toggleTorrentSearch('basic')">Basic</a>)</span>
  148. </strong>
  149. <span class="float_right">
  150. <a onclick="return toggleTorrentSearch(0);" id="ft_toggle" class="brackets"><?=$HideFilter ? 'Show' : 'Hide'?></a>
  151. </span>
  152. </div>
  153. <div id="ft_container"
  154. class="pad<?=$HideFilter ? ' hidden' : ''?>">
  155. <?php
  156. # Three profile toggles
  157. if ((isset($LoggedUser['HideLolicon']) && $LoggedUser['HideLolicon'] === 1)
  158. || (isset($LoggedUser['HideScat']) && $LoggedUser['HideScat'] === 1)
  159. || (isset($LoggedUser['HideSnuff']) && $LoggedUser['HideSnuff'] === 1)
  160. ) { ?>
  161. <svg title="Your profile settings exclude some results" class="search_warning tooltip" width="10" height="15">
  162. <rect x=3 width="4" height="10" rx="2" ry="2" />
  163. <circle cx="5" cy="13" r="2" /></svg>
  164. <?php
  165. } ?>
  166. <table class="layout">
  167. <tr id="numbers"
  168. class="ftr_advanced<?=$HideAdvanced?>">
  169. <td class="label">
  170. <!--
  171. Catalogue Number / AudioFormat
  172. Accession Number / Version
  173. -->
  174. </td>
  175. <td class="ft_numbers">
  176. <input type="search" size="30" name="numbers" class="inputtext smallest fti_advanced"
  177. placeholder="Accession Number / Version"
  178. value="<?Format::form('numbers')?>" />
  179. </td>
  180. </tr>
  181. <tr id="album_torrent_name"
  182. class="ftr_advanced<?=$HideAdvanced?>">
  183. <td class="label">
  184. <!-- Torrent Title / Organism / Strain or Variety -->
  185. </td>
  186. <td class="ft_groupname">
  187. <input type="search" spellcheck="false" size="65" name="advgroupname"
  188. class="inputtext smaller fti_advanced" placeholder="Torrent Title / Organism / Strain or Variety"
  189. value="<?Format::form('advgroupname')?>" />
  190. </td>
  191. </tr>
  192. <tr id="artist_name"
  193. class="ftr_advanced<?=$HideAdvanced?>">
  194. <td class="label">
  195. <!-- Artist Name -->
  196. </td>
  197. <td class="ft_artistname">
  198. <input type="search" spellcheck="false" size="65" id="artist" name="artistname"
  199. class="inputtext smaller fti_advanced" placeholder="Author (ORCiD pending)"
  200. value="<?Format::form('artistname')?>"
  201. <?php Users::has_autocomplete_enabled('other'); ?>/>
  202. </td>
  203. </tr>
  204. <tr id="location" class="ftr_advanced<?=$HideAdvanced?>">
  205. <td class="label">
  206. <!-- Studio / Series -->
  207. </td>
  208. <td class="ft_location">
  209. <input type="search" name="location" class="inputtext smallest fti_advanced"
  210. placeholder="Department or Lab / Location"
  211. value="<?Format::form('location')?>"
  212. size="40" />
  213. <!-- Year -->
  214. <input type="search" name="year" class="inputtext smallest fti_advanced" placeholder="Year"
  215. value="<?Format::form('year')?>"
  216. size="20" />
  217. </td>
  218. </tr>
  219. <tr id="torrent_description"
  220. class="ftr_advanced<?=$HideAdvanced?>">
  221. <td class="label">
  222. <!-- Torrent Description -->
  223. </td>
  224. <td class="ft_description">
  225. <input type="search" spellcheck="false" size="65" name="description" class="inputtext fti_advanced"
  226. placeholder="Torrent Description"
  227. value="<?php Format::form('description') ?>" /><br /><br />
  228. Search torrent descriptions (not group information)
  229. </td>
  230. </tr>
  231. <tr id="file_list" class="ftr_advanced<?=$HideAdvanced?>">
  232. <td class="label">
  233. <!-- File List -->
  234. </td>
  235. <td class="ft_filelist">
  236. <input type="search" spellcheck="false" size="65" name="filelist" class="inputtext fti_advanced"
  237. placeholder="File List"
  238. value="<?Format::form('filelist')?>" /><br /><br />
  239. Universal Search finds info hashes
  240. </td>
  241. </tr>
  242. <!-- Platforms -->
  243. <tr id="rip_specifics"
  244. class="ftr_advanced<?=$HideAdvanced?>">
  245. <td class="label">Platforms</td>
  246. <td class="nobr ft_ripspecifics">
  247. <select name="media" class="ft_media fti_advanced">
  248. <option value="">Sequencing</option>
  249. <?php foreach ($Media as $MediaName) { ?>
  250. <option value="<?=display_str($MediaName); # pcs-comment-start; keep quote ?>"
  251. <?Format::selected('media', $MediaName)?>><?=display_str($MediaName); ?>
  252. </option>
  253. <?php } ?>
  254. </select>
  255. <select name="media" class="ft_media fti_advanced">
  256. <option value="">Imaging</option>
  257. <?php foreach ($MediaManga as $MediaName) { ?>
  258. <option value="<?=display_str($MediaName); # pcs-comment-start; keep quote ?>"
  259. <?Format::selected('media', $MediaName)?>><?=display_str($MediaName); ?>
  260. </option>
  261. <?php } ?>
  262. </select>
  263. </td>
  264. </tr>
  265. <!-- Formats -->
  266. <tr id="rip_specifics"
  267. class="ftr_advanced<?=$HideAdvanced?>">
  268. <td class="label">Formats</td>
  269. <td class="nobr ft_ripspecifics">
  270. <!-- 1 -->
  271. <select id=" container" name="container" class="ft_container fti_advanced">
  272. <option value="">DNA/RNA</option>
  273. <?php foreach ($Containers as $Key => $Container) { ?>
  274. <option value="<?=display_str($Key);?>" <?Format::selected('container', $Key)?>><?=display_str($Key);?>
  275. </option>
  276. <?php } ?>
  277. </select>
  278. <!-- 2 -->
  279. <select id=" container" name="container" class="ft_container fti_advanced">
  280. <option value="">Proteins</option>
  281. <?php foreach ($ContainersProt as $Key => $Container) { ?>
  282. <option value="<?=display_str($Key);?>" <?Format::selected('container', $Key)?>><?=display_str($Key);?>
  283. </option>
  284. <?php } ?>
  285. </select>
  286. <!-- 3 -->
  287. <select id=" container" name="container" class="ft_container fti_advanced">
  288. <option value="">Imaging</option>
  289. <?php foreach ($ContainersGames as $Key => $Container) { ?>
  290. <option value="<?=display_str($Key);?>" <?Format::selected('container', $Key)?>><?=display_str($Key);?>
  291. </option>
  292. <?php } ?>
  293. </select>
  294. <!-- 4 -->
  295. <select id=" container" name="container" class="ft_container fti_advanced">
  296. <option value="">Extras</option>
  297. <?php foreach ($ContainersExtra as $Key => $Container) { ?>
  298. <option value="<?=display_str($Key);?>" <?Format::selected('container', $Key)?>><?=display_str($Key);?>
  299. </option>
  300. <?php } ?>
  301. </select>
  302. </td>
  303. </tr>
  304. <!-- Misc -->
  305. <tr id="misc" class="ftr_advanced<?=$HideAdvanced?>">
  306. <td class="label">Misc</td>
  307. <td class="nobr ft_misc">
  308. <select name="resolution" class="ft_resolution fti_advanced">
  309. <option value="">Assembly Level</option>
  310. <?php foreach ($Resolutions as $Resolution) { ?>
  311. <option value="<?=display_str($Resolution); # pcs-comment-start; keep quote ?>"
  312. <?Format::selected('resolution', $Resolution)?>><?=display_str($Resolution); ?>
  313. </option>
  314. <?php } ?>
  315. </select>
  316. <!-- Aligned/Censored -->
  317. <select name=" censored" class="ft_censored fti_advanced">
  318. <option value="">Alignment</option>
  319. <option value="1" <?Format::selected('censored', 1)?>>Aligned
  320. </option>
  321. <option value="0" <?Format::selected('censored', 0)?>>Not Aligned
  322. </option>
  323. </select>
  324. <!-- Leech Status -->
  325. <select name="freetorrent" class="ft_freetorrent fti_advanced">
  326. <option value="">Leech Status</option>
  327. <option value="1" <?Format::selected('freetorrent', 1)?>>Freeleech
  328. </option>
  329. <option value="2" <?Format::selected('freetorrent', 2)?>>Neutral
  330. Leech</option>
  331. <option value="3" <?Format::selected('freetorrent', 3)?>>Either
  332. </option>
  333. <option value="0" <?Format::selected('freetorrent', 0)?>>Normal
  334. </option>
  335. </select>
  336. <!-- Codec/License -->
  337. <select name="codec" class="ft_codec fti_advanced">
  338. <option value="">License</option>
  339. <?php foreach ($Codecs as $Codec) { ?>
  340. <option value="<?=display_str($Codec); ?>" <?Format::selected('codec', $Codec)?>><?=display_str($Codec); ?>
  341. </option>
  342. <?php } ?>
  343. </select>
  344. </td>
  345. </tr>
  346. <!-- Size -->
  347. <tr id="size" class="ftr_advanced<?=$HideAdvanced?>">
  348. <td class="label">Size</td>
  349. <td class="ft_size">
  350. <input type="size_min" spellcheck="false" size="6" name="size_min" class="inputtext smaller fti_advanced"
  351. placeholder="Min"
  352. value="<?Format::form('size_min')?>" />
  353. &ndash;
  354. <input type="size_max" spellcheck="false" size="6" name="size_max" class="inputtext smaller fti_advanced"
  355. placeholder="Max"
  356. value="<?Format::form('size_max')?>" />
  357. <select name="size_unit" class="ft_size fti_advanced">
  358. <option value="">Unit</option>
  359. <option value="0" <?Format::selected('size_unit', 0)?>>B
  360. </option>
  361. <option value="1" <?Format::selected('size_unit', 1)?>>KiB
  362. </option>
  363. <option value="2" <?Format::selected('size_unit', 2)?>>MiB
  364. </option>
  365. <option value="3" <?Format::selected('size_unit', 3)?>>GiB
  366. </option>
  367. <option value="4" <?Format::selected('size_unit', 4)?>>TiB
  368. </option>
  369. </select>
  370. </td>
  371. </tr>
  372. <!-- Start basic search options -->
  373. <tr id="search_terms" class="ftr_basic<?=$HideBasic?>">
  374. <td class="label">
  375. <!-- Universal Search -->
  376. </td>
  377. <td class="ftb_searchstr">
  378. <input type="search" spellcheck="false" size="48" name="searchstr" class="inputtext fti_basic"
  379. placeholder="Universal Search"
  380. value="<?Format::form('searchstr')?>"
  381. aria-label="Terms to search">
  382. </td>
  383. </tr>
  384. <tr id="tagfilter">
  385. <td class="label">
  386. <!-- Tags (comma-separated) -->
  387. </td>
  388. <td class="ft_taglist">
  389. <input type="search" size="37" id="tags" name="taglist" class="inputtext smaller"
  390. placeholder="Tags (comma-separated)"
  391. value="<?=display_str($Search->get_terms('taglist'))?>"
  392. <?php Users::has_autocomplete_enabled('other'); ?>
  393. aria-label="Tags to search">&nbsp;
  394. <input type="radio" name="tags_type" id="tags_type0" value="0" <?Format::selected('tags_type', 0, 'checked')?>
  395. /><label for="tags_type0"> Any</label>&nbsp;&nbsp;
  396. <input type="radio" name="tags_type" id="tags_type1" value="1" <?Format::selected('tags_type', 1, 'checked')?>
  397. /><label for="tags_type1"> All</label><br /><br />
  398. Use !tag to exclude tags
  399. </td>
  400. </tr>
  401. <!-- Order By -->
  402. <tr id="order">
  403. <td class="label">Order By</td>
  404. <td class="ft_order">
  405. <select name="order_by" style="width: auto;" class="ft_order_by" aria-label="Property to order by">
  406. <option value="time" <?Format::selected('order_by', 'time')?>>Time
  407. Added</option>
  408. <option value="year" <?Format::selected('order_by', 'year')?>>Year
  409. </option>
  410. <option value="size" <?Format::selected('order_by', 'size')?>>Size
  411. </option>
  412. <option value="snatched" <?Format::selected('order_by', 'snatched')?>>Snatched
  413. </option>
  414. <option value="seeders" <?Format::selected('order_by', 'seeders')?>>Seeders
  415. </option>
  416. <option value="leechers" <?Format::selected('order_by', 'leechers')?>>Leechers
  417. </option>
  418. <option value="cataloguenumber" <?Format::selected('order_by', 'cataloguenumber')?>>Accession
  419. Number</option>
  420. <option value="random" <?Format::selected('order_by', 'random')?>>Random
  421. </option>
  422. </select>
  423. <select name="order_way" class="ft_order_way" aria-label="Direction to order">
  424. <option value="desc" <?Format::selected('order_way', 'desc')?>>Descending
  425. </option>
  426. <option value="asc" <?Format::selected('order_way', 'asc')?>>Ascending
  427. </option>
  428. </select>
  429. </td>
  430. </tr>
  431. <!-- Use torrent groups? -->
  432. <tr id="search_group_results">
  433. <td class="label">
  434. <label for="group_results">Group Torrents</label>
  435. </td>
  436. <td class="ft_group_results">
  437. <input type="checkbox" value="1" name="group_results" id="group_results" <?=$GroupResults ? ' checked="checked"' : ''?>
  438. />
  439. </td>
  440. </tr>
  441. </table>
  442. <table class="layout cat_list ft_cat_list">
  443. <?php
  444. $x = 0;
  445. reset($Categories);
  446. foreach ($Categories as $CatKey => $CatName) {
  447. if ($x % 7 === 0) {
  448. if ($x > 0) {
  449. ?>
  450. </tr>
  451. <?php
  452. } ?>
  453. <tr>
  454. <?php
  455. }
  456. $x++; ?>
  457. <td>
  458. <input type="checkbox"
  459. name="filter_cat[<?=($CatKey + 1)?>]"
  460. id="cat_<?=($CatKey + 1)?>" value="1" <?php if (isset($_GET['filter_cat'][$CatKey + 1])) { ?>
  461. checked="checked"<?php } ?> />
  462. <label for="cat_<?=($CatKey + 1)?>"><?=$CatName?></label>
  463. </td>
  464. <?php
  465. } ?>
  466. </tr>
  467. </table>
  468. <table
  469. class="layout cat_list<?php if (empty($LoggedUser['ShowTags'])) { ?> hidden<?php } ?>"
  470. id="taglist">
  471. <tr>
  472. <?php
  473. $GenreTags = $Cache->get_value('genre_tags');
  474. if (!$GenreTags) {
  475. $DB->query('
  476. SELECT Name
  477. FROM tags
  478. WHERE TagType = \'genre\'
  479. ORDER BY Name');
  480. $GenreTags = $DB->collect('Name');
  481. $Cache->cache_value('genre_tags', $GenreTags, 3600 * 6);
  482. }
  483. $x = 0;
  484. foreach ($GenreTags as $Tag) {
  485. ?>
  486. <td><a href="#"
  487. onclick="add_tag('<?=$Tag?>'); return false;"><?=$Tag?></a></td>
  488. <?php
  489. $x++;
  490. if ($x % 7 === 0) {
  491. ?>
  492. </tr>
  493. <tr>
  494. <?php
  495. }
  496. }
  497. if ($x % 7 !== 0) { // Padding
  498. ?>
  499. <td colspan="<?=(7 - ($x % 7))?>"> </td>
  500. <?php } ?>
  501. </tr>
  502. </table>
  503. <!-- Categories -->
  504. <table class="layout cat_list">
  505. <tr>
  506. <td class="label">
  507. <a class="brackets" data-toggle-target="#taglist"
  508. data-toggle-replace="<?=(empty($LoggedUser['ShowTags']) ? 'Hide tags' : 'View tags')?>"><?=(empty($LoggedUser['ShowTags']) ? 'View tags' : 'Hide tags')?></a>
  509. </td>
  510. </tr>
  511. </table>
  512. <!-- Result count and submit button -->
  513. <div class="submit ft_submit">
  514. <span class="float_left"><?=number_format($NumResults)?>
  515. Results</span>
  516. <input type="submit" value="Search" />
  517. <input type="hidden" name="action" id="ft_type"
  518. value="<?=($AdvancedSearch ? 'advanced' : 'basic')?>" />
  519. <input type="hidden" name="searchsubmit" value="1" />
  520. <input type="button" value="Reset"
  521. onclick="location.href = 'torrents.php<?php if (isset($_GET['action']) && $_GET['action'] === 'advanced') { ?>?action=advanced<?php } ?>'" />
  522. &nbsp;&nbsp;
  523. <?php if ($Search->has_filters()) { ?>
  524. <input type="submit" name="setdefault" value="Make Default" />
  525. <?php }
  526. if (!empty($LoggedUser['DefaultSearch'])) { ?>
  527. <input type="submit" name="cleardefault" value="Clear Default" />
  528. <?php } ?>
  529. </div>
  530. </div>
  531. </div>
  532. </form>
  533. <!-- No results message -->
  534. <?php if ($NumResults === 0) { ?>
  535. <div class="torrents_nomatch box pad" align="center">
  536. <h2>Your search did not match anything</h2>
  537. <p>Make sure all names are spelled correctly, or try making your search less specific</p>
  538. </div>
  539. </div>
  540. <?php
  541. View::show_footer();
  542. die();
  543. }
  544. if ($NumResults < ($Page - 1) * TORRENTS_PER_PAGE + 1) {
  545. $LastPage = ceil($NumResults / TORRENTS_PER_PAGE);
  546. $Pages = Format::get_pages(0, $NumResults, TORRENTS_PER_PAGE); ?>
  547. <div class="torrents_nomatch box pad" align="center">
  548. <h2>The requested page contains no matches</h2>
  549. <p>You are requesting page <?=$Page?>, but the search returned only
  550. <?=number_format($LastPage) ?> pages</p>
  551. </div>
  552. <div class="linkbox">Go to page <?=$Pages?>
  553. </div>
  554. </div>
  555. <?php
  556. View::show_footer();
  557. die();
  558. }
  559. // List of pages
  560. $Pages = Format::get_pages($Page, $NumResults, TORRENTS_PER_PAGE);
  561. $Bookmarks = Bookmarks::all_bookmarks('torrent');
  562. ?>
  563. <div class="linkbox"><?=$Pages?>
  564. </div>
  565. <!-- Results table headings -->
  566. <table
  567. class="box torrent_table cats <?=$GroupResults ? 'grouping' : 'no_grouping'?>"
  568. id="torrent_table">
  569. <tr class="colhead">
  570. <?php if ($GroupResults) { ?>
  571. <td class="small"></td>
  572. <?php } ?>
  573. <td class="small cats_col"></td>
  574. <td>Name / <a
  575. href="<?=header_link('year')?>">Year</a>
  576. </td>
  577. <td>Files</td>
  578. <td><a
  579. href="<?=header_link('time')?>">Time</a>
  580. </td>
  581. <td><a
  582. href="<?=header_link('size')?>">Size</a>
  583. </td>
  584. <td class="sign snatches">
  585. <a href="<?=header_link('snatched')?>"
  586. aria-label="Sort by snatches">
  587. <svg width="15" height="15" fill="black" class="tooltip" alt="Snatches" title="Snatches" viewBox="3 0 88 98">
  588. <path d="M20 20 A43 43,0,1,0,77 23 L90 10 L55 10 L55 45 L68 32 A30.27 30.27,0,1,1,28 29"></path>
  589. </svg>
  590. </a>
  591. </td>
  592. <td class="sign seeders">
  593. <a href="<?=header_link('seeders')?>"
  594. aria-label="Sort by seeders">
  595. <svg width="11" height="15" fill="black" class="tooltip" alt="Seeders" title="Seeders">
  596. <polygon points="0,7 5.5,0 11,7 8,7 8,15 3,15 3,7"></polygon>
  597. </svg>
  598. </a>
  599. </td>
  600. <td class="sign leechers">
  601. <a href="<?=header_link('leechers')?>"
  602. aria-label="Sort by leechers">
  603. <svg width="11" height="15" fill="black" class="tooltip" alt="Leechers" title="Leechers">
  604. <polygon points="0,8 5.5,15 11,8 8,8 8,0 3,0 3,8"></polygon>
  605. </svg>
  606. </a>
  607. </td>
  608. </tr>
  609. <?php
  610. // Start printing torrent list
  611. foreach ($Results as $Key => $GroupID) {
  612. $GroupInfo = $Groups[$GroupID];
  613. if (empty($GroupInfo['Torrents'])) {
  614. continue;
  615. }
  616. $CategoryID = $GroupInfo['CategoryID'];
  617. $GroupYear = $GroupInfo['Year'];
  618. $Artists = $GroupInfo['Artists'];
  619. $GroupCatalogueNumber = $GroupInfo['CatalogueNumber'];
  620. $GroupPages = $GroupInfo['Pages'];
  621. $GroupStudio = $GroupInfo['Studio'];
  622. $GroupDLsiteID = $GroupInfo['DLSiteID'];
  623. $GroupName = empty($GroupInfo['Name']) ? (empty($GroupInfo['NameRJ']) ? $GroupInfo['NameJP'] : $GroupInfo['NameRJ']) : $GroupInfo['Name'];
  624. if ($GroupResults) {
  625. $Torrents = $GroupInfo['Torrents'];
  626. $GroupTime = $MaxSize = $TotalLeechers = $TotalSeeders = $TotalSnatched = 0;
  627. foreach ($Torrents as $T) {
  628. $GroupTime = max($GroupTime, strtotime($T['Time']));
  629. $MaxSize = max($MaxSize, $T['Size']);
  630. $TotalLeechers += $T['Leechers'];
  631. $TotalSeeders += $T['Seeders'];
  632. $TotalSnatched += $T['Snatched'];
  633. }
  634. } else {
  635. $TorrentID = $Key;
  636. $Torrents = [$TorrentID => $GroupInfo['Torrents'][$TorrentID]];
  637. }
  638. $TorrentTags = new Tags($GroupInfo['TagList']);
  639. if (isset($Artists)) {
  640. $DisplayName = '<div class="torrent_artists">'.Artists::display_artists($Artists).'</div> ';
  641. } else {
  642. $DisplayName = '';
  643. }
  644. $SnatchedGroupClass = $GroupInfo['Flags']['IsSnatched'] ? ' snatched_group' : '';
  645. # Similar to the logic down the page, and on
  646. # torrents.class.php and sections/artist/artist.php
  647. # todo: Find out exactly whhere this displays (it's not the search results)
  648. if ($GroupResults && (count($Torrents) > 1 && isset($GroupedCategories[$CategoryID - 1]))) {
  649. // These torrents are in a group
  650. $CoverArt = $GroupInfo['WikiImage'];
  651. $DisplayName .= "<a class=\"torrent_title\" href=\"torrents.php?id=$GroupID\" ";
  652. # No cover art
  653. if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
  654. $DisplayName .= 'data-cover="'.ImageTools::process($CoverArt, 'thumb').'" ';
  655. }
  656. # Japanese
  657. $DisplayName .= "dir=\"ltr\">$GroupName</a>";
  658. # Year
  659. if ($GroupYear) {
  660. $DisplayName .= "<br /><a href='torrents.php?action=advanced&year=$GroupYear'>$GroupYear</a>";
  661. }
  662. # Studio
  663. if ($GroupStudio) {
  664. $DisplayName .= " &ndash; <a href='torrents.php?action=advanced&location=$GroupStudio'>$GroupStudio</a>";
  665. }
  666. # Catalogue Number
  667. if ($GroupCatalogueNumber) {
  668. $DisplayName .= " &ndash; <a href='torrents.php?action=advanced&numbers=$GroupCatalogueNumber'>$GroupCatalogueNumber</a>";
  669. }
  670. /*
  671. if ($GroupPages) {
  672. $DisplayName .= " [{$GroupPages}p]";
  673. }
  674. */
  675. /*
  676. if ($GroupDLsiteID) {
  677. $DisplayName .= " [$GroupDLsiteID]";
  678. }
  679. */ ?>
  680. <tr class="group<?=$SnatchedGroupClass?>">
  681. <?php
  682. $ShowGroups = !(!empty($LoggedUser['TorrentGrouping']) && $LoggedUser['TorrentGrouping'] === 1); ?>
  683. <td class="center">
  684. <div id="showimg_<?=$GroupID?>"
  685. class="<?=($ShowGroups ? 'hide' : 'show')?>_torrents">
  686. <a class="tooltip show_torrents_link"
  687. onclick="toggle_group(<?=$GroupID?>, this, event)"
  688. title="Toggle this group (Hold &quot;Shift&quot; to toggle all groups)"></a>
  689. </div>
  690. </td>
  691. <!-- Category icon -->
  692. <td class="center cats_col">
  693. <div title="<?=Format::pretty_category($CategoryID)?>"
  694. class="tooltip <?=Format::css_category($CategoryID)?>">
  695. </div>
  696. </td>
  697. <!-- [ DL | RP ] and [Bookmark] -->
  698. <td colspan="2" class="big_info">
  699. <div class="group_info clear">
  700. <?=$DisplayName?>
  701. <?php if (in_array($GroupID, $Bookmarks)) { ?>
  702. <span class="remove_bookmark float_right">
  703. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  704. class="brackets"
  705. onclick="Unbookmark('torrent', <?=$GroupID?>, 'Bookmark'); return false;">Remove
  706. bookmark</a>
  707. </span>
  708. <?php } else { ?>
  709. <span class="add_bookmark float_right">
  710. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  711. class="brackets"
  712. onclick="Bookmark('torrent', <?=$GroupID?>, 'Remove bookmark'); return false;">Bookmark</a>
  713. </span>
  714. <?php } ?>
  715. <br />
  716. <!-- Tags -->
  717. <div class="tags"><?=$TorrentTags->format('torrents.php?'.$Action.'&amp;taglist=')?>
  718. </div>
  719. </div>
  720. </td>
  721. <!-- Time -->
  722. <td class="nobr"><?=time_diff($GroupTime, 1)?>
  723. </td>
  724. <!-- Size -->
  725. <td class="number_column nobr"><?=Format::get_size($MaxSize)?>(Max)</td>
  726. <!-- Snatches, seeders, and leechers -->
  727. <td class="number_column"><?=number_format($TotalSnatched)?>
  728. </td>
  729. <td
  730. class="number_column<?=($TotalSeeders === 0 ? ' r00' : '')?>">
  731. <?=number_format($TotalSeeders)?>
  732. </td>
  733. <td class="number_column"><?=number_format($TotalLeechers)?>
  734. </td>
  735. </tr>
  736. <?php
  737. foreach ($Torrents as $TorrentID => $Data) {
  738. $Data['CategoryID'] = $CategoryID;
  739. // All of the individual torrents in the group
  740. // Get report info for each torrent, use the cache if available, if not, add to it
  741. $Reported = false;
  742. $Reports = Torrents::get_reports($TorrentID);
  743. if (count($Reports) > 0) {
  744. $Reported = true;
  745. }
  746. $SnatchedTorrentClass = $Data['IsSnatched'] ? ' snatched_torrent' : '';
  747. $TorrentDL = "torrents.php?action=download&amp;id=".$TorrentID."&amp;authkey=".$LoggedUser['AuthKey']."&amp;torrent_pass=".$LoggedUser['torrent_pass'];
  748. if (!empty(G::$LoggedUser) && (G::$LoggedUser['ShowMagnets'] ?? false)) {
  749. if (!($TorrentFileName = $Cache->get_value('torrent_file_name_'.$TorrentID))) {
  750. $TorrentFile = file_get_contents(TORRENT_STORE.$TorrentID.'.torrent');
  751. $Tor = new BencodeTorrent($TorrentFile, false, false);
  752. $TorrentFileName = $Tor->Dec['info']['name'];
  753. $Cache->cache_value('torrent_file_name_'.$TorrentID, $TorrentFileName);
  754. }
  755. # Magnet link 1337 h4x
  756. $TorrentMG = "magnet:?dn=".rawurlencode($TorrentFileName)."&xt=urn:btih:".$Data['info_hash']."&as=https://".SITE_DOMAIN."/".str_replace('&amp;', '%26', $TorrentDL)."&tr=".implode("/".$LoggedUser['torrent_pass']."/announce&tr=", ANNOUNCE_URLS[0])."/".$LoggedUser['torrent_pass']."/announce&xl=".$Data['Size'];
  757. } ?>
  758. <tr
  759. class="group_torrent groupid_<?=$GroupID?> <?=$SnatchedTorrentClass . $SnatchedGroupClass . (!empty($LoggedUser['TorrentGrouping']) && $LoggedUser['TorrentGrouping'] === 1 ? ' hidden' : '')?>">
  760. <td colspan="3">
  761. <span>
  762. [ <a href="<?=$TorrentDL?>" class="tooltip"
  763. title="Download"><?=$Data['HasFile'] ? 'DL' : 'Missing'?></a>
  764. <?php if (isset($TorrentMG)) { ?>
  765. | <a href="<?=$TorrentMG?>" class="tooltip"
  766. title="Magnet Link">MG</a>
  767. <?php }
  768. if (Torrents::can_use_token($Data)) { ?>
  769. | <a
  770. href="torrents.php?action=download&amp;id=<?=$TorrentID?>&amp;authkey=<?=$LoggedUser['AuthKey']?>&amp;torrent_pass=<?=$LoggedUser['torrent_pass']?>&amp;usetoken=1"
  771. class="tooltip" title="Use a FL Token"
  772. onclick="return confirm('Are you sure you want to use a freeleech token here?');">FL</a>
  773. <?php } ?>
  774. | <a
  775. href="reportsv2.php?action=report&amp;id=<?=$TorrentID?>"
  776. class="tooltip" title="Report">RP</a> ]
  777. </span>
  778. &raquo; <a
  779. href="torrents.php?id=<?=$GroupID?>&amp;torrentid=<?=$TorrentID?>"><?=Torrents::torrent_info($Data)?><?php if ($Reported) { ?> / <strong
  780. class="torrent_label tl_reported tooltip"
  781. title="Type: <?=ucfirst($Reports[0]['Type'])?><br>Comment: <?=htmlentities(htmlentities($Reports[0]['UserComment']))?>">Reported</strong><?php } ?></a>
  782. </td>
  783. <td class="number_column"><?=$Data['FileCount']?>
  784. </td>
  785. <td class="nobr"><?=time_diff($Data['Time'], 1)?>
  786. </td>
  787. <td class="number_column nobr"><?=Format::get_size($Data['Size'])?>
  788. </td>
  789. <td class="number_column"><?=number_format($Data['Snatched'])?>
  790. </td>
  791. <td
  792. class="number_column<?=($Data['Seeders'] === 0) ? ' r00' : ''?>">
  793. <?=number_format($Data['Seeders'])?>
  794. </td>
  795. <td class="number_column"><?=number_format($Data['Leechers'])?>
  796. </td>
  797. </tr>
  798. <?php
  799. }
  800. } else {
  801. // Viewing a type that does not require grouping
  802. $TorrentID = key($Torrents);
  803. $Data = current($Torrents);
  804. $Reported = false;
  805. $Reports = Torrents::get_reports($TorrentID);
  806. if (count($Reports) > 0) {
  807. $Reported = true;
  808. }
  809. # Main search result title link
  810. # These are the main torrent search results
  811. $Data['CategoryID'] = $CategoryID;
  812. $CoverArt = $GroupInfo['WikiImage'];
  813. $DisplayName .= "<a class=\"torrent_name\" href=\"torrents.php?id=$GroupID&amp;torrentid=$TorrentID#torrent$TorrentID\" ";
  814. if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
  815. $DisplayName .= 'data-cover="'.ImageTools::process($CoverArt, 'thumb').'" ';
  816. }
  817. # Japanese
  818. $DisplayName .= "dir=\"ltr\">$GroupName</a>";
  819. if (isset($GroupedCategories[$CategoryID - 1])) {
  820. # Year
  821. # Sh!t h4x; Year is mandatory
  822. if ($GroupYear) {
  823. $DisplayName .= "<br /><a href='torrents.php?action=advanced&year=$GroupYear'>$GroupYear</a>";
  824. }
  825. # Studio
  826. if ($GroupStudio) {
  827. $DisplayName .= " &ndash; <a href='torrents.php?action=advanced&location=$GroupStudio'>$GroupStudio</a>";
  828. }
  829. # Catalogue Number
  830. if ($GroupCatalogueNumber) {
  831. $DisplayName .= " &ndash; <a href='torrents.php?action=advanced&numbers=$GroupCatalogueNumber'>$GroupCatalogueNumber</a>";
  832. }
  833. /*
  834. if ($GroupPages) {
  835. $DisplayName .= " [{$GroupPages}p]";
  836. }
  837. */
  838. /*
  839. if ($GroupDLsiteID) {
  840. $DisplayName .= " [$GroupDLsiteID]";
  841. }
  842. */
  843. $ExtraInfo = Torrents::torrent_info($Data, true, true);
  844. } elseif ($Data['IsSnatched']) {
  845. $ExtraInfo = Format::torrent_label('Snatched!');
  846. } else {
  847. $ExtraInfo = '';
  848. }
  849. $SnatchedTorrentClass = $Data['IsSnatched'] ? ' snatched_torrent' : '';
  850. $TorrentDL = "torrents.php?action=download&amp;id=".$TorrentID."&amp;authkey=".$LoggedUser['AuthKey']."&amp;torrent_pass=".$LoggedUser['torrent_pass'];
  851. if (!empty(G::$LoggedUser) && (G::$LoggedUser['ShowMagnets'] ?? false)) {
  852. if (!($TorrentFileName = $Cache->get_value('torrent_file_name_'.$TorrentID))) {
  853. $TorrentFile = file_get_contents(TORRENT_STORE.$TorrentID.'.torrent');
  854. $Tor = new BencodeTorrent($TorrentFile, false, false);
  855. $TorrentFileName = $Tor->Dec['info']['name'];
  856. $Cache->cache_value('torrent_file_name_'.$TorrentID, $TorrentFileName);
  857. }
  858. $TorrentMG = "magnet:?dn=".rawurlencode($TorrentFileName)."&xt=urn:btih:".$Data['info_hash']."&as=https://".SITE_DOMAIN."/".str_replace('&amp;', '%26', $TorrentDL)."&tr=".implode("/".$LoggedUser['torrent_pass']."/announce&tr=", ANNOUNCE_URLS[0])."/".$LoggedUser['torrent_pass']."/announce&xl=".$Data['Size'];
  859. } ?>
  860. <tr
  861. class="torrent<?=$SnatchedTorrentClass . $SnatchedGroupClass?>">
  862. <?php if ($GroupResults) { ?>
  863. <td></td>
  864. <?php } ?>
  865. <td class="center cats_col">
  866. <div title="<?=Format::pretty_category($CategoryID)?>"
  867. class="tooltip <?=Format::css_category($CategoryID)?>"></div>
  868. </td>
  869. <td class="big_info">
  870. <div class="group_info clear">
  871. <div class="float_right">
  872. <span>
  873. [ <a href="<?=$TorrentDL?>" class="tooltip"
  874. title="Download">DL</a>
  875. <?php if (isset($TorrentMG)) { ?>
  876. | <a href="<?=$TorrentMG?>" class="tooltip"
  877. title="Magnet Link">MG</a>
  878. <?php }
  879. if (Torrents::can_use_token($Data)) { ?>
  880. | <a
  881. href="torrents.php?action=download&amp;id=<?=$TorrentID?>&amp;authkey=<?=$LoggedUser['AuthKey']?>&amp;torrent_pass=<?=$LoggedUser['torrent_pass']?>&amp;usetoken=1"
  882. class="tooltip" title="Use a FL Token"
  883. onclick="return confirm('Are you sure you want to use a freeleech token here?');">FL</a>
  884. <?php } ?>
  885. | <a
  886. href="reportsv2.php?action=report&amp;id=<?=$TorrentID?>"
  887. class="tooltip" title="Report">RP</a> ]
  888. </span>
  889. <br />
  890. <?php if (in_array($GroupID, $Bookmarks)) { ?>
  891. <span class="remove_bookmark float_right">
  892. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  893. class="brackets"
  894. onclick="Unbookmark('torrent', <?=$GroupID?>, 'Bookmark'); return false;">Remove
  895. bookmark</a>
  896. </span>
  897. <?php } else { ?>
  898. <span class="add_bookmark float_right">
  899. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  900. class="brackets"
  901. onclick="Bookmark('torrent', <?=$GroupID?>, 'Remove bookmark'); return false;">Bookmark</a>
  902. </span>
  903. <?php } ?>
  904. </div>
  905. <?=$DisplayName?>
  906. <br />
  907. <div style="display: inline;" class="torrent_info"><?=$ExtraInfo?><?php if ($Reported) { ?> / <strong
  908. class="torrent_label tl_reported tooltip"
  909. title="Type: <?=ucfirst($Reports[0]['Type'])?><br>Comment: <?=htmlentities(htmlentities($Reports[0]['UserComment']))?>">Reported</strong><?php } ?>
  910. </div>
  911. <div class="tags"><?=$TorrentTags->format("torrents.php?$Action&amp;taglist=")?>
  912. </div>
  913. </div>
  914. </td>
  915. <td class="number_column"><?=$Data['FileCount']?>
  916. </td>
  917. <td class="nobr"><?=time_diff($Data['Time'], 1)?>
  918. </td>
  919. <td class="number_column nobr"><?=Format::get_size($Data['Size'])?>
  920. </td>
  921. <td class="number_column"><?=number_format($Data['Snatched'])?>
  922. </td>
  923. <td
  924. class="number_column<?=($Data['Seeders'] === 0) ? ' r00' : ''?>">
  925. <?=number_format($Data['Seeders'])?>
  926. </td>
  927. <td class="number_column"><?=number_format($Data['Leechers'])?>
  928. </td>
  929. </tr>
  930. <?php
  931. }
  932. }
  933. ?>
  934. </table>
  935. <div class="linkbox"><?=$Pages?>
  936. </div>
  937. </div>
  938. <?php
  939. View::show_footer();