Files
nexusphp/public/torrentrss.php

290 lines
11 KiB
PHP
Raw Permalink Normal View History

2020-12-26 01:42:23 +08:00
<?php
2021-01-13 19:32:26 +08:00
require "../include/bittorrent.php";
$passkey = $_GET['passkey'] ?? $CURUSER['passkey'] ?? '';
if (!$passkey) {
die("require passkey");
}
2026-01-04 21:23:44 +08:00
$exactParams = ['inclbookmarked', 'paid', 'rows', 'icat', 'ismalldescr', 'isize', 'iuplder', 'search', 'search_mode', 'sticky', 'linktype'];
$prefixedParams = ['cat', 'sou', 'med', 'cod', 'sta', 'pro', 'tea', 'aud'];
foreach ($_GET as $key => $value) {
if (in_array($key, $exactParams, true)) {
continue;
}
if (preg_match('/^(cat|sou|med|cod|sta|pro|tea|aud)\d+$/', $key)) {
continue;
}
unset($_GET[$key]);
}
2025-09-15 14:25:21 +07:00
$cacheKey = "nexus_rss:$passkey:" . md5(http_build_query($_GET));
$cacheData = \Nexus\Database\NexusDB::cache_get($cacheKey);
2023-01-16 19:43:56 +08:00
if ($cacheData && nexus_env('APP_ENV') != 'local') {
do_log("rss get from cache");
header ("Content-type: text/xml");
die($cacheData);
2022-07-18 15:13:03 +08:00
}
2023-05-29 19:55:51 +08:00
dbconn(doLogin: false);
2020-12-26 01:42:23 +08:00
function hex_esc($matches) {
return sprintf("%02x", ord($matches[0]));
}
$dllink = false;
2025-09-20 17:22:53 +07:00
$where = "";
2020-12-26 01:42:23 +08:00
if ($passkey){
2023-05-29 19:55:51 +08:00
$user = \Nexus\Database\NexusDB::remember('user_passkey_'.$passkey.'_rss', 3600, function () use ($passkey) {
$res = sql_query("SELECT id, enabled, parked, passkey FROM users WHERE passkey=". sqlesc($passkey)." LIMIT 1");
return mysql_fetch_array($res);
});
2020-12-26 01:42:23 +08:00
if (!$user)
die("invalid passkey");
elseif ($user['enabled'] == 'no' || $user['parked'] == 'yes')
die("account disabed or parked");
2021-05-15 12:59:59 +08:00
elseif (isset($_GET['linktype']) && $_GET['linktype'] == 'dl')
2020-12-26 01:42:23 +08:00
$dllink = true;
$inclbookmarked=intval($_GET['inclbookmarked'] ?? 0);
2020-12-26 01:42:23 +08:00
if($inclbookmarked == 1)
{
$bookmarkarray = return_torrent_bookmark_array($user['id']);
if ($bookmarkarray){
$whereidin = implode(",", $bookmarkarray);
$where .= ($where ? " AND " : "") . "torrents.id IN(" . $whereidin . ")";
}
}
}
2025-09-08 03:05:55 +07:00
//$searchstr = mysql_real_escape_string(trim($_GET["search"] ?? ''));
$searchstr = null;//don't support search, use client self filter instead
2020-12-26 01:42:23 +08:00
if (empty($searchstr))
unset($searchstr);
if (isset($searchstr)){
$search_mode = intval($_GET["search_mode"] ?? 0);
2023-03-04 13:26:20 +08:00
if (!in_array($search_mode,array(0,2)))
2020-12-26 01:42:23 +08:00
{
$search_mode = 0;
}
switch ($search_mode)
{
case 0: // AND, OR
case 1 :
$searchstr = str_replace(".", " ", $searchstr);
$searchstr_exploded = explode(" ", $searchstr);
$searchstr_exploded_count= 0;
foreach ($searchstr_exploded as $searchstr_element)
{
$searchstr_element = trim($searchstr_element); // furthur trim to ensure that multi space seperated words still work
$searchstr_exploded_count++;
if ($searchstr_exploded_count > 10) // maximum 10 keywords
break;
$like_expression_array[] = " LIKE '%" . $searchstr_element. "%'";
}
break;
case 2 : // exact
{
$like_expression_array[] = " LIKE '%" . $searchstr. "%'";
break;
}
}
$ANDOR = ($search_mode == 0 ? " AND " : " OR "); // only affects mode 0 and mode 1
foreach ($like_expression_array as &$like_expression_array_element)
2024-09-26 23:29:14 +08:00
$like_expression_array_element = "(torrents.name" . $like_expression_array_element . (isset($_GET['ismalldescr']) && $_GET['ismalldescr'] ? " OR torrents.small_descr" . $like_expression_array_element : "") . ")";
2020-12-26 01:42:23 +08:00
$wherea[] = implode($ANDOR, $like_expression_array);
$where .= ($where ? " AND " : "") . implode(" AND ", $wherea);
}
$limit = "";
2023-01-17 06:13:50 +08:00
$showrows = intval($_GET['rows'] ?? 0);
2025-09-08 03:05:55 +07:00
if($showrows < 1 || $showrows > 50) {
$showrows = 50;
2023-01-17 06:13:50 +08:00
}
$limit .= $showrows;
2020-12-26 01:42:23 +08:00
//approval status
$approvalStatusNoneVisible = get_setting('torrent.approval_status_none_visible');
if ($approvalStatusNoneVisible == 'no' && !user_can('staffmem', false, $user['id'])) {
2022-07-02 21:22:12 +08:00
$where .= ($where ? " AND " : "") . "torrents.approval_status = " . \App\Models\Torrent::APPROVAL_STATUS_ALLOW;
}
//check special section permission
2023-01-17 06:13:50 +08:00
$browseMode = get_setting('main.browsecat');
$onlyBrowseSection = get_setting('main.spsct') != 'yes' || !user_can('view_special_torrent', false, $user['id']);
if ($onlyBrowseSection) {
2025-09-20 17:22:53 +07:00
$allBrowseCategoryId = \App\Models\SearchBox::listCategoryId($browseMode);
$where .= ($where ? " AND " : "") . sprintf("torrents.category in (%s)", implode(",", $allBrowseCategoryId));
}
2025-09-20 17:22:53 +07:00
//visible
$where .= ($where ? " AND " : "") . "torrents.visible = 'yes'";
2023-02-11 16:08:48 +08:00
//check price
if (isset($_GET['paid']) && in_array($_GET['paid'], ['0', '1', '2'], true)) {
$paidFilter = $_GET['paid'];
} else {
$paidFilter = '0';
}
if ($paidFilter === '0') {
$where .= ($where ? " AND " : "") . "torrents.price = 0";
} elseif ($paidFilter === '1') {
$where .= ($where ? " AND " : "") . "torrents.price > 0";
}
2020-12-26 01:42:23 +08:00
function get_where($tablename = "sources", $itemname = "source", $getname = "sou")
{
global $where;
2022-11-09 21:56:03 +08:00
$items = searchbox_item_list($tablename, 0);
2020-12-26 01:42:23 +08:00
$whereitemina = array();
foreach ($items as $item)
{
2020-12-29 21:49:37 +08:00
if (!empty($_GET[$getname.$item['id']]))
2020-12-26 01:42:23 +08:00
{
2020-12-29 21:49:37 +08:00
$whereitemina[] = $item['id'];
2020-12-26 01:42:23 +08:00
}
}
if (count($whereitemina) >= 1){
$whereitemin = implode(",",$whereitemina);
$where .= ($where ? " AND " : "") . $itemname." IN(" . $whereitemin . ")";
}
}
get_where("categories", "category", "cat");
get_where("sources", "source", "sou");
get_where("media", "medium", "med");
get_where("codecs", "codec", "cod");
get_where("standards", "standard", "sta");
get_where("processings", "processing", "pro");
get_where("teams", "team", "tea");
get_where("audiocodecs", "audiocodec", "aud");
2023-01-17 06:13:50 +08:00
$hasStickyFirst = $hasStickySecond = $hasStickyNormal = $noNormalResults = false;
$prependIdArr = $prependRows = $normalRows = [];
$stickyWhere = $normalWhere = '';
2023-01-21 13:58:35 +08:00
if (isset($_GET['sticky']) && $inclbookmarked == 0) {
2023-01-17 06:13:50 +08:00
$stickyArr = explode(',', $_GET['sticky']);
//Only handle sticky first + second
$posStates = [];
if (in_array('0', $stickyArr, true)) {
$hasStickyNormal = true;
}
if (in_array('1', $stickyArr, true)) {
$hasStickyFirst = true;
$posStates[] = \App\Models\Torrent::POS_STATE_STICKY_FIRST;
}
if (in_array('2', $stickyArr, true)) {
$hasStickySecond = true;
$posStates[] = \App\Models\Torrent::POS_STATE_STICKY_SECOND;
}
if (!empty($posStates)) {
$prependIdArr = \App\Models\Torrent::query()->whereIn('pos_state', $posStates)->pluck('id')->toArray();
}
}
$prependIdArr = apply_filter("sticky_promotion_torrent_ids", $prependIdArr);
if ($hasStickyNormal) {
$stickyWhere = sprintf("torrents.pos_state = '%s'", \App\Models\Torrent::POS_STATE_STICKY_NONE);
} elseif ($hasStickyFirst || $hasStickySecond) {
$noNormalResults = true;
}
if ($where) {
$normalWhere = "WHERE ".$where;
if ($stickyWhere) {
$normalWhere .= " and $stickyWhere";
}
}
2023-01-16 19:43:56 +08:00
$sort = "id desc";
2025-01-20 12:02:59 +08:00
$fieldStr = "torrents.id, torrents.category, torrents.name, torrents.small_descr, torrent_extras.descr, torrents.info_hash, torrents.size, torrents.added, torrents.anonymous, torrents.owner, categories.name AS category_name";
2023-01-17 06:13:50 +08:00
if (!$noNormalResults) {
2025-09-20 17:22:53 +07:00
$query = "SELECT $fieldStr FROM torrents LEFT JOIN categories ON torrents.category = categories.id left join torrent_extras on torrent_extras.torrent_id = torrents.id $normalWhere ORDER BY $sort LIMIT $limit";
2025-09-21 00:34:41 +07:00
$normalRows = \Nexus\Database\NexusDB::remember(sprintf("nexus_rss:normal:%s", md5($query)), 300, function () use ($query) {
return \Nexus\Database\NexusDB::select($query);
});
2023-01-17 06:13:50 +08:00
}
2026-01-04 21:23:44 +08:00
if (!empty($prependIdArr)) {
2023-01-17 06:13:50 +08:00
$prependIdStr = implode(',', $prependIdArr);
2025-09-21 00:34:41 +07:00
$query = "SELECT $fieldStr FROM torrents LEFT JOIN categories ON torrents.category = categories.id left join torrent_extras on torrent_extras.torrent_id = torrents.id where torrents.id in ($prependIdStr) and $where ORDER BY field(torrents.id, $prependIdStr)";
$prependRows = \Nexus\Database\NexusDB::remember(sprintf("nexus_rss:prepend:%s", md5($query)), 300, function () use ($query) {
return \Nexus\Database\NexusDB::select($query);
});
2023-01-17 06:13:50 +08:00
}
$list = [];
foreach ($prependRows as $row) {
$list[$row['id']] = $row;
}
foreach ($normalRows as $row) {
if (!isset($list[$row['id']])) {
$list[$row['id']] = $row;
}
}
2023-01-12 03:50:39 +08:00
2023-01-20 22:52:17 +08:00
//dd($prependIdArr, $prependRows, $normalRows, $list, $startindex,last_query());
$torrentRep = new \App\Repositories\TorrentRepository();
2020-12-26 01:42:23 +08:00
$url = get_protocol_prefix().$BASEURL;
$year = substr($datefounded, 0, 4);
$yearfounded = ($year ? $year : 2007);
$copyright = "Copyright (c) ".$SITENAME." ".(date("Y") != $yearfounded ? $yearfounded."-" : "").date("Y").", all rights reserved";
2022-07-18 15:13:03 +08:00
$xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";
2020-12-26 01:42:23 +08:00
//The commented version passed feed validator at http://www.feedvalidator.org
/*print('
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">');*/
2022-07-18 15:13:03 +08:00
$xml .= '<rss version="2.0">';
$xml .= '<channel>
2020-12-26 01:42:23 +08:00
<title>' . addslashes($SITENAME.' Torrents'). '</title>
<link><![CDATA[' . $url . ']]></link>
<description><![CDATA[' . addslashes('Latest torrents from '.$SITENAME.' - '.htmlspecialchars($SLOGAN)) . ']]></description>
<language>zh-cn</language>
<copyright>'.$copyright.'</copyright>
<managingEditor>'.$SITEEMAIL.' ('.$SITENAME.' Admin)</managingEditor>
<webMaster>'.$SITEEMAIL.' ('.$SITENAME.' Webmaster)</webMaster>
<pubDate>'.date('r').'</pubDate>
<generator>'.PROJECTNAME.' RSS Generator</generator>
<docs><![CDATA[http://www.rssboard.org/rss-specification]]></docs>
<ttl>60</ttl>
<image>
<url><![CDATA[' . $url.'/pic/rss_logo.jpg'. ']]></url>
<title>' . addslashes($SITENAME.' Torrents') . '</title>
<link><![CDATA[' . $url . ']]></link>
<width>100</width>
<height>100</height>
<description>' . addslashes($SITENAME.' Torrents') . '</description>
2022-07-18 15:13:03 +08:00
</image>';
2020-12-26 01:42:23 +08:00
/*print('
<atom:link href="'.$url.$_SERVER['REQUEST_URI'].'" rel="self" type="application/rss+xml" />');*/
2022-07-18 15:13:03 +08:00
//print('
//');
2022-06-09 01:47:33 +08:00
foreach ($list as $row)
2020-12-26 01:42:23 +08:00
{
2022-11-10 01:52:41 +08:00
$ownerInfo = get_user_row($row['owner']);
2020-12-26 01:42:23 +08:00
$title = "";
if ($row['anonymous'] == 'yes') {
$author = 'anonymous';
} elseif (!empty($ownerInfo)) {
$author = $ownerInfo['username'];
} else {
$author = nexus_trans("nexus.user_not_exists");
}
2020-12-26 01:42:23 +08:00
$itemurl = $url."/details.php?id=".$row['id'];
if ($dllink)
2024-12-24 01:10:48 +08:00
$itemdlurl = $torrentRep->getDownloadUrl($row['id'], $user);
2020-12-26 01:42:23 +08:00
else $itemdlurl = $url."/download.php?id=".$row['id'];
2022-11-10 01:52:41 +08:00
if (!empty($_GET['icat'])) $title .= "[".$row['category_name']."]";
2020-12-26 01:42:23 +08:00
$title .= $row['name'];
2021-05-14 01:00:59 +08:00
if (!empty($_GET['ismalldescr']) && !empty($row['small_descr'])) $title .= "[".$row['small_descr']."]";
if (!empty($_GET['isize'])) $title .= "[".mksize($row['size'])."]";
if (!empty($_GET['iuplder'])) $title .= "[".$author."]";
2020-12-26 01:42:23 +08:00
$content = format_comment($row['descr'], true, false, false, false);
2022-07-18 15:13:03 +08:00
$xml .= '<item>
2020-12-26 01:42:23 +08:00
<title><![CDATA['.$title.']]></title>
<link>'.$itemurl.'</link>
<description><![CDATA['.$content.']]></description>
2022-07-18 15:13:03 +08:00
';
2020-12-26 01:42:23 +08:00
//print(' <dc:creator>'.$author.'</dc:creator>');
2022-07-18 15:13:03 +08:00
$xml .= '<author>'.$author.'@'.$_SERVER['HTTP_HOST'].' ('.$author.')</author>';
2022-11-10 01:52:41 +08:00
$xml .= '<category domain="'.$url.'/torrents.php?cat='.$row['category'].'">'.$row['category_name'].'</category>
2020-12-26 01:42:23 +08:00
<comments><![CDATA['.$url.'/details.php?id='.$row['id'].'&cmtpage=0#startcomments]]></comments>
<enclosure url="'.$itemdlurl.'" length="'.$row['size'].'" type="application/x-bittorrent" />
<guid isPermaLink="false">'.preg_replace_callback('/./s', 'hex_esc', hash_pad($row['info_hash'])).'</guid>
<pubDate>'.date('r',strtotime($row['added'])).'</pubDate>
</item>
2022-07-18 15:13:03 +08:00
';
2020-12-26 01:42:23 +08:00
}
2022-07-18 15:13:03 +08:00
$xml .= '</channel>
</rss>';
do_log("rss cache generated");
\Nexus\Database\NexusDB::cache_put($cacheKey, $xml, 300);
2022-07-18 15:13:03 +08:00
header ("Content-type: text/xml");
echo $xml;
2020-12-26 01:42:23 +08:00
?>