Oppaitime'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 14KB

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