diff --git a/app/Http/Controllers/Api/RSS.php b/app/Http/Controllers/Api/RSS.php index 7eef105e1..c95859d7b 100644 --- a/app/Http/Controllers/Api/RSS.php +++ b/app/Http/Controllers/Api/RSS.php @@ -149,6 +149,105 @@ class RSS extends ApiController return $result; } + /** + * Get trending movies RSS (top 15 most downloaded in last 48 hours) + * + * @return \Illuminate\Support\Collection + */ + public function getTrendingMoviesRss() + { + $cacheKey = 'rss_trending_movies_48h'; + + return Cache::remember($cacheKey, 3600, function () { + $fortyEightHoursAgo = \Illuminate\Support\Carbon::now()->subHours(48); + + $sql = sprintf( + "SELECT DISTINCT + r.searchname, r.guid, r.postdate, r.categories_id, r.size, + r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, + r.adddate, r.imdbid, + m.title, m.year, m.rating, m.plot, m.genre, m.cover, m.tmdbid, m.traktid, + g.name AS group_name, + CONCAT(cp.title, ' > ', c.title) AS category_name, + COALESCE(cp.id,0) AS parentid, + COUNT(DISTINCT ud.id) as total_downloads, + COUNT(DISTINCT r.id) as release_count + FROM releases r + INNER JOIN movieinfo m ON m.imdbid = r.imdbid + LEFT JOIN user_downloads ud ON r.id = ud.releases_id + LEFT JOIN categories c ON c.id = r.categories_id + INNER JOIN root_categories cp ON cp.id = c.root_categories_id + LEFT JOIN usenet_groups g ON g.id = r.groups_id + WHERE m.title != '' + AND m.imdbid != '0000000' + AND ud.timestamp >= '%s' + AND r.passwordstatus %s + GROUP BY r.id, r.searchname, r.guid, r.postdate, r.categories_id, r.size, + r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, + r.adddate, r.imdbid, m.title, m.year, m.rating, m.plot, m.genre, + m.cover, m.tmdbid, m.traktid, g.name, cp.title, c.title, cp.id + HAVING COUNT(DISTINCT ud.id) > 0 + ORDER BY total_downloads DESC, r.postdate DESC + LIMIT 15", + $fortyEightHoursAgo->format('Y-m-d H:i:s'), + $this->releases->showPasswords() + ); + + return Release::fromQuery($sql); + }); + } + + /** + * Get trending TV shows RSS (top 15 most downloaded in last 48 hours) + * + * @return \Illuminate\Support\Collection + */ + public function getTrendingShowsRss() + { + $cacheKey = 'rss_trending_shows_48h'; + + return Cache::remember($cacheKey, 3600, function () { + $fortyEightHoursAgo = \Illuminate\Support\Carbon::now()->subHours(48); + + $sql = sprintf( + "SELECT DISTINCT + r.searchname, r.guid, r.postdate, r.categories_id, r.size, + r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, + r.adddate, r.videos_id, r.tv_episodes_id, + v.title, v.started, v.tvdb, v.tvmaze, v.trakt, v.tmdb, v.countries_id, + ti.summary, ti.image, + g.name AS group_name, + CONCAT(cp.title, ' > ', c.title) AS category_name, + COALESCE(cp.id,0) AS parentid, + COUNT(DISTINCT ud.id) as total_downloads, + COUNT(DISTINCT r.id) as release_count + FROM releases r + INNER JOIN videos v ON v.id = r.videos_id + INNER JOIN tv_info ti ON ti.videos_id = v.id + LEFT JOIN user_downloads ud ON r.id = ud.releases_id + LEFT JOIN categories c ON c.id = r.categories_id + INNER JOIN root_categories cp ON cp.id = c.root_categories_id + LEFT JOIN usenet_groups g ON g.id = r.groups_id + WHERE v.type = 0 + AND v.title != '' + AND ud.timestamp >= '%s' + AND r.passwordstatus %s + GROUP BY r.id, r.searchname, r.guid, r.postdate, r.categories_id, r.size, + r.totalpart, r.fromname, r.passwordstatus, r.grabs, r.comments, + r.adddate, r.videos_id, r.tv_episodes_id, v.title, v.started, v.tvdb, + v.tvmaze, v.trakt, v.tmdb, v.countries_id, ti.summary, ti.image, + g.name, cp.title, c.title, cp.id + HAVING COUNT(DISTINCT ud.id) > 0 + ORDER BY total_downloads DESC, r.postdate DESC + LIMIT 15", + $fortyEightHoursAgo->format('Y-m-d H:i:s'), + $this->releases->showPasswords() + ); + + return Release::fromQuery($sql); + }); + } + /** * Get the first instance of a column from a table where the column is greater than 0, ordered by a specified column. * diff --git a/app/Http/Controllers/BasePageController.php b/app/Http/Controllers/BasePageController.php index aa7daa949..2a8f31185 100644 --- a/app/Http/Controllers/BasePageController.php +++ b/app/Http/Controllers/BasePageController.php @@ -48,7 +48,7 @@ class BasePageController extends Controller */ public function __construct() { - $this->middleware(['auth', 'web', '2fa'])->except('api', 'contact', 'showContactForm', 'callback', 'btcPayCallback', 'getNzb', 'terms', 'privacyPolicy', 'capabilities', 'movie', 'apiSearch', 'tv', 'details', 'failed', 'showRssDesc', 'fullFeedRss', 'categoryFeedRss', 'cartRss', 'myMoviesRss', 'myShowsRss', 'release', 'reset', 'showLinkRequestForm'); + $this->middleware(['auth', 'web', '2fa'])->except('api', 'contact', 'showContactForm', 'callback', 'btcPayCallback', 'getNzb', 'terms', 'privacyPolicy', 'capabilities', 'movie', 'apiSearch', 'tv', 'details', 'failed', 'showRssDesc', 'fullFeedRss', 'categoryFeedRss', 'cartRss', 'myMoviesRss', 'myShowsRss', 'trendingMoviesRss', 'trendingShowsRss', 'release', 'reset', 'showLinkRequestForm'); // Load settings as collection $this->settings = Settings::query()->pluck('value', 'name'); diff --git a/app/Http/Controllers/RssController.php b/app/Http/Controllers/RssController.php index cae88930d..0426cdc2a 100644 --- a/app/Http/Controllers/RssController.php +++ b/app/Http/Controllers/RssController.php @@ -172,6 +172,42 @@ class RssController extends BasePageController $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); } + /** + * @throws \Throwable + */ + public function trendingMoviesRss(Request $request) + { + $rss = new RSS; + $offset = 0; + $user = $this->userCheck($request); + if (is_object($user)) { + return $user; + } + $outputXML = (! ($request->has('o') && $request->input('o') === 'json')); + + $relData = $rss->getTrendingMoviesRss(); + + $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + } + + /** + * @throws \Throwable + */ + public function trendingShowsRss(Request $request) + { + $rss = new RSS; + $offset = 0; + $user = $this->userCheck($request); + if (is_object($user)) { + return $user; + } + $outputXML = (! ($request->has('o') && $request->input('o') === 'json')); + + $relData = $rss->getTrendingShowsRss(); + + $rss->output($relData, $user['params'], $outputXML, $offset, 'rss'); + } + /** * @throws \Throwable */ diff --git a/resources/views/movies/trending.blade.php b/resources/views/movies/trending.blade.php index 7c17ebdff..5b95b9953 100644 --- a/resources/views/movies/trending.blade.php +++ b/resources/views/movies/trending.blade.php @@ -36,7 +36,12 @@

Most downloaded movies in the last 48 hours - Updated every hour

-
+
+ @if(auth()->check()) + + RSS Feed + + @endif Browse All Movies diff --git a/resources/views/rss/rssdesc.blade.php b/resources/views/rss/rssdesc.blade.php index 104e87363..96fa73ebf 100644 --- a/resources/views/rss/rssdesc.blade.php +++ b/resources/views/rss/rssdesc.blade.php @@ -165,6 +165,50 @@
+ +
+
+
+ Trending Feeds +
+

Most downloaded content in the last 48 hours (updated hourly)

+
+
+
+
+ + Trending Movies + + + Open Feed + +
+
+ + +
+
+
+
+ + Trending TV Shows + + + Open Feed + +
+
+ + +
+
+
+
+
diff --git a/resources/views/series/trending.blade.php b/resources/views/series/trending.blade.php index b2d9772ee..23cdede99 100644 --- a/resources/views/series/trending.blade.php +++ b/resources/views/series/trending.blade.php @@ -36,7 +36,12 @@

Most downloaded TV shows in the last 48 hours - Updated every hour

-
+
+ @if(auth()->check()) + + RSS Feed + + @endif Browse All TV Shows diff --git a/routes/rss.php b/routes/rss.php index ef1e928b0..61f399112 100644 --- a/routes/rss.php +++ b/routes/rss.php @@ -6,6 +6,8 @@ |-------------------------------------------------------------------------- | | RSS feed routes +| Note: Authentication is handled manually in the controller via userCheck() +| method which validates the api_token parameter. | */ @@ -22,4 +24,8 @@ Route::middleware(['auth:api', 'auth:rss'])->group(function () { Route::post('cart', [RssController::class, 'cartRss']); Route::get('category', [RssController::class, 'categoryFeedRss']); Route::post('category', [RssController::class, 'categoryFeedRss']); + Route::get('trending-movies', [RssController::class, 'trendingMoviesRss']); + Route::post('trending-movies', [RssController::class, 'trendingMoviesRss']); + Route::get('trending-shows', [RssController::class, 'trendingShowsRss']); + Route::post('trending-shows', [RssController::class, 'trendingShowsRss']); });