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.

notify.php 15KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. <?php
  2. declare(strict_types=1);
  3. if (!check_perms('site_torrents_notify')) {
  4. error(403);
  5. }
  6. define('NOTIFICATIONS_PER_PAGE', 50);
  7. define('NOTIFICATIONS_MAX_SLOWSORT', 10000);
  8. $OrderBys = array(
  9. 'time' => array('unt' => 'unt.TorrentID'),
  10. 'size' => array('t' => 't.Size'),
  11. 'snatches' => array('t' => 't.Snatched'),
  12. 'seeders' => array('t' => 't.Seeders'),
  13. 'leechers' => array('t' => 't.Leechers'),
  14. 'year' => array('tg' => 'tnt.Year'));
  15. if (empty($_GET['order_by']) || !isset($OrderBys[$_GET['order_by']])) {
  16. $_GET['order_by'] = 'time';
  17. }
  18. $OrderTbl = key($OrderBys[$_GET['order_by']]);
  19. $OrderCol = current($OrderBys[$_GET['order_by']]);
  20. if (!empty($_GET['order_way']) && $_GET['order_way'] === 'asc') {
  21. $OrderWay = 'ASC';
  22. } else {
  23. $OrderWay = 'DESC';
  24. }
  25. if (!empty($_GET['filterid']) && is_number($_GET['filterid'])) {
  26. $FilterID = $_GET['filterid'];
  27. } else {
  28. $FilterID = false;
  29. }
  30. list($Page, $Limit) = Format::page_limit(NOTIFICATIONS_PER_PAGE);
  31. // The "order by x" links on columns headers
  32. function header_link($SortKey, $DefaultWay = 'desc')
  33. {
  34. global $OrderWay;
  35. if ($SortKey === $_GET['order_by']) {
  36. if ($OrderWay === 'DESC') {
  37. $NewWay = 'asc';
  38. } else {
  39. $NewWay = 'desc';
  40. }
  41. } else {
  42. $NewWay = $DefaultWay;
  43. }
  44. return "?action=notify&amp;order_way=$NewWay&amp;order_by=$SortKey&amp;".Format::get_url(array('page', 'order_way', 'order_by'));
  45. }
  46. //Perhaps this should be a feature at some point
  47. if (check_perms('users_mod') && !empty($_GET['userid']) && is_number($_GET['userid']) && $_GET['userid'] != $LoggedUser['ID']) {
  48. $UserID = $_GET['userid'];
  49. $Sneaky = true;
  50. } else {
  51. $Sneaky = false;
  52. $UserID = $LoggedUser['ID'];
  53. }
  54. // Sorting by release year requires joining torrents_group, which is slow. Using a temporary table
  55. // makes it speedy enough as long as there aren't too many records to create
  56. if ($OrderTbl === 'tg') {
  57. $DB->query("
  58. SELECT COUNT(*)
  59. FROM users_notify_torrents AS unt
  60. JOIN torrents AS t ON t.ID=unt.TorrentID
  61. WHERE unt.UserID=$UserID".
  62. ($FilterID
  63. ? " AND FilterID=$FilterID"
  64. : ''));
  65. list($TorrentCount) = $DB->next_record();
  66. if ($TorrentCount > NOTIFICATIONS_MAX_SLOWSORT) {
  67. error('Due to performance issues, torrent lists with more than '.number_format(NOTIFICATIONS_MAX_SLOWSORT).' items cannot be ordered by release year.');
  68. }
  69. $DB->query("
  70. CREATE TEMPORARY TABLE temp_notify_torrents
  71. (TorrentID int, GroupID int, UnRead tinyint, FilterID int, Year smallint, PRIMARY KEY(GroupID, TorrentID), KEY(Year))
  72. ENGINE=MyISAM");
  73. $DB->query("
  74. INSERT IGNORE INTO temp_notify_torrents (TorrentID, GroupID, UnRead, FilterID)
  75. SELECT t.ID, t.GroupID, unt.UnRead, unt.FilterID
  76. FROM users_notify_torrents AS unt
  77. JOIN torrents AS t ON t.ID=unt.TorrentID
  78. WHERE unt.UserID=$UserID".
  79. ($FilterID
  80. ? " AND unt.FilterID=$FilterID"
  81. : ''));
  82. $DB->query("
  83. UPDATE temp_notify_torrents AS tnt
  84. JOIN torrents_group AS tg ON tnt.GroupID = tg.ID
  85. SET tnt.Year = tg.Year");
  86. $DB->query("
  87. SELECT TorrentID, GroupID, UnRead, FilterID
  88. FROM temp_notify_torrents AS tnt
  89. ORDER BY $OrderCol $OrderWay, GroupID $OrderWay
  90. LIMIT $Limit");
  91. $Results = $DB->to_array(false, MYSQLI_ASSOC, false);
  92. } else {
  93. $DB->query("
  94. SELECT
  95. SQL_CALC_FOUND_ROWS
  96. unt.TorrentID,
  97. unt.UnRead,
  98. unt.FilterID,
  99. t.GroupID
  100. FROM users_notify_torrents AS unt
  101. JOIN torrents AS t ON t.ID = unt.TorrentID
  102. WHERE unt.UserID = $UserID".
  103. ($FilterID
  104. ? " AND unt.FilterID = $FilterID"
  105. : '')."
  106. ORDER BY $OrderCol $OrderWay
  107. LIMIT $Limit");
  108. $Results = $DB->to_array(false, MYSQLI_ASSOC, false);
  109. $DB->query('SELECT FOUND_ROWS()');
  110. list($TorrentCount) = $DB->next_record();
  111. }
  112. $GroupIDs = $FilterIDs = $UnReadIDs = [];
  113. foreach ($Results as $Torrent) {
  114. $GroupIDs[$Torrent['GroupID']] = 1;
  115. $FilterIDs[$Torrent['FilterID']] = 1;
  116. if ($Torrent['UnRead']) {
  117. $UnReadIDs[] = $Torrent['TorrentID'];
  118. }
  119. }
  120. $Pages = Format::get_pages($Page, $TorrentCount, NOTIFICATIONS_PER_PAGE, 9);
  121. if (!empty($GroupIDs)) {
  122. $GroupIDs = array_keys($GroupIDs);
  123. $FilterIDs = array_keys($FilterIDs);
  124. $TorrentGroups = Torrents::get_groups($GroupIDs);
  125. // Get the relevant filter labels
  126. $DB->query('
  127. SELECT ID, Label, Artists
  128. FROM users_notify_filters
  129. WHERE ID IN ('.implode(',', $FilterIDs).')');
  130. $Filters = $DB->to_array('ID', MYSQLI_ASSOC, array('Artists'));
  131. foreach ($Filters as &$Filter) {
  132. $Filter['Artists'] = explode('|', trim($Filter['Artists'], '|'));
  133. foreach ($Filter['Artists'] as &$FilterArtist) {
  134. $FilterArtist = mb_strtolower($FilterArtist, 'UTF-8');
  135. }
  136. $Filter['Artists'] = array_flip($Filter['Artists']);
  137. }
  138. unset($Filter);
  139. if (!empty($UnReadIDs)) {
  140. //Clear before header but after query so as to not have the alert bar on this page load
  141. $DB->query("
  142. UPDATE users_notify_torrents
  143. SET UnRead = '0'
  144. WHERE UserID = ".$LoggedUser['ID'].'
  145. AND TorrentID IN ('.implode(',', $UnReadIDs).')');
  146. $Cache->delete_value('notifications_new_'.$LoggedUser['ID']);
  147. }
  148. }
  149. if ($Sneaky) {
  150. $UserInfo = Users::user_info($UserID);
  151. View::show_header($UserInfo['Username'].'\'s notifications', 'notifications');
  152. } else {
  153. View::show_header('My notifications', 'notifications');
  154. }
  155. ?>
  156. <div>
  157. <div class="header">
  158. <h2>Latest notifications</h2>
  159. </div>
  160. <div class="linkbox">
  161. <?php if ($FilterID) { ?>
  162. <a href="torrents.php?action=notify<?=($Sneaky ? "&amp;userid=$UserID" : '')?>"
  163. class="brackets">View all</a>&nbsp;&nbsp;&nbsp;
  164. <?php } elseif (!$Sneaky) { ?>
  165. <a href="torrents.php?action=notify_clear&amp;auth=<?=$LoggedUser['AuthKey']?>"
  166. class="brackets">Clear all old</a>&nbsp;&nbsp;&nbsp;
  167. <a href="#" onclick="clearSelected(); return false;" class="brackets">Clear selected</a>&nbsp;&nbsp;&nbsp;
  168. <a href="torrents.php?action=notify_catchup&amp;auth=<?=$LoggedUser['AuthKey']?>"
  169. class="brackets">Catch up</a>&nbsp;&nbsp;&nbsp;
  170. <?php } ?>
  171. <a href="user.php?action=notify" class="brackets">Edit filters</a>&nbsp;&nbsp;&nbsp;
  172. </div>
  173. <?php if ($TorrentCount > NOTIFICATIONS_PER_PAGE) { ?>
  174. <div class="linkbox">
  175. <?=$Pages?>
  176. </div>
  177. <?php
  178. }
  179. if (empty($Results)) {
  180. ?>
  181. <table class="layout border slight_margin">
  182. <tr class="row">
  183. <td colspan="8" class="center">
  184. No new notifications found! <a href="user.php?action=notify" class="brackets">Edit notification filters</a>
  185. </td>
  186. </tr>
  187. </table>
  188. <?php
  189. } else {
  190. $FilterGroups = [];
  191. foreach ($Results as $Result) {
  192. if (!isset($FilterGroups[$Result['FilterID']])) {
  193. $FilterGroups[$Result['FilterID']] = [];
  194. $FilterGroups[$Result['FilterID']]['FilterLabel'] = isset($Filters[$Result['FilterID']])
  195. ? $Filters[$Result['FilterID']]['Label']
  196. : false;
  197. }
  198. $FilterGroups[$Result['FilterID']][] = $Result;
  199. }
  200. foreach ($FilterGroups as $FilterID => $FilterResults) {
  201. ?>
  202. <div class="header">
  203. <h3>
  204. <?php if ($FilterResults['FilterLabel'] !== false) { ?>
  205. Matches for <a
  206. href="torrents.php?action=notify&amp;filterid=<?=$FilterID.($Sneaky ? "&amp;userid=$UserID" : '')?>"><?=$FilterResults['FilterLabel']?></a>
  207. <?php } else { ?>
  208. Matches for unknown filter[<?=$FilterID?>]
  209. <?php } ?>
  210. </h3>
  211. </div>
  212. <div class="linkbox notify_filter_links">
  213. <?php if (!$Sneaky) { ?>
  214. <a href="#"
  215. onclick="clearSelected(<?=$FilterID?>); return false;"
  216. class="brackets">Clear selected in filter</a>
  217. <a href="torrents.php?action=notify_clear_filter&amp;filterid=<?=$FilterID?>&amp;auth=<?=$LoggedUser['AuthKey']?>"
  218. class="brackets">Clear all old in filter</a>
  219. <a href="torrents.php?action=notify_catchup_filter&amp;filterid=<?=$FilterID?>&amp;auth=<?=$LoggedUser['AuthKey']?>"
  220. class="brackets">Mark all in filter as read</a>
  221. <?php } ?>
  222. </div>
  223. <form class="manage_form" name="torrents"
  224. id="notificationform_<?=$FilterID?>" action="">
  225. <table class="torrent_table cats checkboxes border slight_margin">
  226. <tr class="colhead">
  227. <td style="text-align: center;"><input type="checkbox" name="toggle"
  228. onclick="toggleChecks('notificationform_<?=$FilterID?>', this, '.notify_box')" />
  229. </td>
  230. <td class="small cats_col"></td>
  231. <td style="width: 100%;">Name<?=$TorrentCount <= NOTIFICATIONS_MAX_SLOWSORT ? ' / <a href="'.header_link('year').'">Year</a>' : ''?>
  232. </td>
  233. <td>Files</td>
  234. <td><a
  235. href="<?=header_link('time')?>">Time</a>
  236. </td>
  237. <td><a
  238. href="<?=header_link('size')?>">Size</a>
  239. </td>
  240. <td class="sign snatches"><a
  241. href="<?=header_link('snatches')?>">↻</a>
  242. </td>
  243. <td class="sign seeders"><a
  244. href="<?=header_link('seeders')?>">&uarr;</a>
  245. </td>
  246. <td class="sign leechers"><a
  247. href="<?=header_link('leechers')?>">&darr;</a>
  248. </td>
  249. </tr>
  250. <?php
  251. unset($FilterResults['FilterLabel']);
  252. foreach ($FilterResults as $Result) {
  253. $TorrentID = $Result['TorrentID'];
  254. $GroupID = $Result['GroupID'];
  255. $GroupInfo = $TorrentGroups[$Result['GroupID']];
  256. if (!isset($GroupInfo['Torrents'][$TorrentID]) || !isset($GroupInfo['ID'])) {
  257. // If $GroupInfo['ID'] is unset, the torrent group associated with the torrent doesn't exist
  258. continue;
  259. }
  260. $GroupName = empty($GroupInfo['Name']) ? (empty($GroupInfo['Title2']) ? $GroupInfo['NameJP'] : $GroupInfo['Title2']) : $GroupInfo['Name'];
  261. $TorrentInfo = $GroupInfo['Torrents'][$TorrentID];
  262. // generate torrent's title
  263. $DisplayName = '';
  264. if (!empty($GroupInfo['Artists'])) {
  265. $MatchingArtists = [];
  266. foreach ($GroupInfo['Artists'] as $GroupArtists) {
  267. foreach ($GroupArtists as $GroupArtist) {
  268. if (isset($Filters[$FilterID]['Artists'][mb_strtolower($GroupArtist['name'], 'UTF-8')])) {
  269. $MatchingArtists[] = $GroupArtist['name'];
  270. }
  271. }
  272. }
  273. $MatchingArtistsText = (!empty($MatchingArtists) ? 'Caught by filter for '.implode(', ', $MatchingArtists) : '');
  274. $DisplayName = Artists::display_artists($GroupInfo['Artists'], true, true);
  275. }
  276. $DisplayName .= "<a href=\"torrents.php?id=$GroupID&amp;torrentid=$TorrentID#torrent$TorrentID\" ";
  277. if (!isset($LoggedUser['CoverArt']) || $LoggedUser['CoverArt']) {
  278. $DisplayName .= 'data-cover="'.ImageTools::process($GroupInfo['WikiImage'], 'thumb').'" ';
  279. }
  280. $DisplayName .= "class=\"tooltip\" title=\"View torrent\" dir=\"ltr\">" . $GroupName . '</a>';
  281. $GroupCategoryID = $GroupInfo['CategoryID'];
  282. /*
  283. if ($GroupCategoryID === 1) {
  284. */
  285. if ($GroupInfo['Year'] > 0) {
  286. $DisplayName .= " [$GroupInfo[Year]]";
  287. }
  288. /*
  289. if ($GroupInfo['ReleaseType'] > 0) {
  290. $DisplayName .= ' ['.$ReleaseTypes[$GroupInfo['ReleaseType']].']';
  291. }
  292. }
  293. */
  294. // append extra info to torrent title
  295. $ExtraInfo = Torrents::torrent_info($TorrentInfo, true, true);
  296. $TorrentTags = new Tags($GroupInfo['TagList']);
  297. if ($GroupInfo['TagList'] === '') {
  298. $TorrentTags->set_primary($Categories[$GroupCategoryID - 1]);
  299. }
  300. // echo row?>
  301. <tr
  302. class="torrent torrent_row<?=($TorrentInfo['IsSnatched'] ? ' snatched_torrent' : '') . ($GroupInfo['Flags']['IsSnatched'] ? ' snatched_group' : '') . ($MatchingArtistsText ? ' tooltip" title="'.display_str($MatchingArtistsText) : '')?>"
  303. id="torrent<?=$TorrentID?>">
  304. <td style="text-align: center;">
  305. <input type="checkbox"
  306. class="notify_box notify_box_<?=$FilterID?>"
  307. value="<?=$TorrentID?>"
  308. id="clear_<?=$TorrentID?>" tabindex="1" />
  309. </td>
  310. <td class="center cats_col">
  311. <div title="<?=$TorrentTags->title()?>"
  312. class="tooltip <?=Format::css_category($GroupCategoryID)?> <?=$TorrentTags->css_name()?>">
  313. </div>
  314. </td>
  315. <td class="big_info">
  316. <div class="group_info clear">
  317. <span>
  318. [ <a
  319. href="torrents.php?action=download&amp;id=<?=$TorrentID?>&amp;authkey=<?=$LoggedUser['AuthKey']?>&amp;torrent_pass=<?=$LoggedUser['torrent_pass']?>"
  320. class="tooltip" title="Download">DL</a>
  321. <?php if (Torrents::can_use_token($TorrentInfo)) { ?>
  322. | <a
  323. href="torrents.php?action=download&amp;id=<?=$TorrentID?>&amp;authkey=<?=$LoggedUser['AuthKey']?>&amp;torrent_pass=<?=$LoggedUser['torrent_pass']?>&amp;usetoken=1"
  324. class="tooltip" title="Use a FL Token"
  325. onclick="return confirm('Are you sure you want to use a freeleech token here?');">FL</a>
  326. <?php
  327. }
  328. if (!$Sneaky) { ?>
  329. | <a href="#"
  330. onclick="clearItem(<?=$TorrentID?>); return false;"
  331. class="tooltip" title="Remove from notifications list">CL</a>
  332. <?php } ?> ]
  333. </span>
  334. <?=$DisplayName?>
  335. <div class="torrent_info">
  336. <?=$ExtraInfo?>
  337. <?php if ($Result['UnRead']) {
  338. echo '<strong class="new">New!</strong>';
  339. } ?>
  340. <?php if (Bookmarks::has_bookmarked('torrent', $GroupID)) { ?>
  341. <span class="remove_bookmark float_right">
  342. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  343. class="brackets"
  344. onclick="Unbookmark('torrent', <?=$GroupID?>, 'Bookmark'); return false;">Remove
  345. bookmark</a>
  346. </span>
  347. <?php } else { ?>
  348. <span class="add_bookmark float_right">
  349. <a href="#" id="bookmarklink_torrent_<?=$GroupID?>"
  350. class="brackets"
  351. onclick="Bookmark('torrent', <?=$GroupID?>, 'Remove bookmark'); return false;">Bookmark</a>
  352. <?php } ?>
  353. </span>
  354. </div>
  355. <div class="tags"><?=$TorrentTags->format()?>
  356. </div>
  357. </div>
  358. </td>
  359. <td><?=$TorrentInfo['FileCount']?>
  360. </td>
  361. <td class="number_column nobr"><?=time_diff($TorrentInfo['Time'])?>
  362. </td>
  363. <td class="number_column nobr"><?=Format::get_size($TorrentInfo['Size'])?>
  364. </td>
  365. <td class="number_column"><?=number_format($TorrentInfo['Snatched'])?>
  366. </td>
  367. <td class="number_column"><?=number_format($TorrentInfo['Seeders'])?>
  368. </td>
  369. <td class="number_column"><?=number_format($TorrentInfo['Leechers'])?>
  370. </td>
  371. </tr>
  372. <?php
  373. } ?>
  374. </table>
  375. </form>
  376. <?php
  377. }
  378. }
  379. if ($Pages) { ?>
  380. <div class="linkbox"><?=$Pages?>
  381. </div>
  382. <?php } ?>
  383. </div>
  384. <?php View::show_footer();