mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-09-01 02:38:55 +00:00
Add trending shows and movies rss
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -36,7 +36,12 @@
|
||||
</h1>
|
||||
<p class="text-blue-100">Most downloaded movies in the last 48 hours - Updated every hour</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-right flex gap-2">
|
||||
@if(auth()->check())
|
||||
<a href="{{ url('/rss/trending-movies?dl=1&api_token=' . auth()->user()->api_token) }}" class="inline-flex items-center px-4 py-2 bg-orange-500 hover:bg-orange-600 text-white rounded-lg transition shadow-md" title="RSS Feed">
|
||||
<i class="fas fa-rss mr-2"></i> RSS Feed
|
||||
</a>
|
||||
@endif
|
||||
<a href="{{ route('Movies') }}" class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white rounded-lg transition">
|
||||
<i class="fas fa-film mr-2"></i> Browse All Movies
|
||||
</a>
|
||||
|
||||
@@ -165,6 +165,50 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Trending Feeds -->
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm mb-6 dark:bg-gray-800 dark:border-gray-600">
|
||||
<div class="bg-gray-50 dark:bg-gray-900 px-6 py-4 border-b border-gray-200 dark:border-gray-700 dark:bg-gray-700 dark:border-gray-600">
|
||||
<h5 class="text-lg font-semibold text-gray-900 dark:text-gray-100 dark:text-white flex items-center">
|
||||
<i class="fa fa-fire mr-2 text-orange-600 dark:text-orange-400"></i>Trending Feeds
|
||||
</h5>
|
||||
<p class="text-sm text-gray-600 dark:text-gray-400 mt-1">Most downloaded content in the last 48 hours (updated hourly)</p>
|
||||
</div>
|
||||
<div class="divide-y divide-gray-200 dark:divide-gray-700">
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<strong class="text-gray-900 dark:text-gray-100 dark:text-white flex items-center">
|
||||
<i class="fa fa-film mr-2 text-blue-600 dark:text-blue-400"></i>Trending Movies
|
||||
</strong>
|
||||
<a href="{{ url('/rss/trending-movies?dl=1&api_token=' . ($userdata->api_token ?? '')) }}" class="inline-flex items-center px-3 py-1.5 border border-blue-300 rounded text-xs font-medium text-blue-700 bg-white dark:bg-gray-800 hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-blue-400 dark:border-blue-600 dark:hover:bg-gray-600" target="_blank">
|
||||
<i class="fa fa-external-link mr-1"></i>Open Feed
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex rounded-md shadow-sm">
|
||||
<input type="text" class="flex-1 rounded-l-md border-gray-300 dark:border-gray-600 font-mono text-xs focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" value="{{ url('/rss/trending-movies?dl=1&api_token=' . ($userdata->api_token ?? '')) }}" readonly id="trendingMoviesFeedUrl">
|
||||
<button class="inline-flex items-center px-3 py-2 border border-l-0 border-gray-300 dark:border-gray-600 rounded-r-md bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-gray-600 dark:text-gray-200 dark:border-gray-500 dark:hover:bg-gray-500 copy-btn" type="button" data-copy-target="trendingMoviesFeedUrl">
|
||||
<i class="fa fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<strong class="text-gray-900 dark:text-gray-100 dark:text-white flex items-center">
|
||||
<i class="fa fa-tv mr-2 text-purple-600 dark:text-purple-400"></i>Trending TV Shows
|
||||
</strong>
|
||||
<a href="{{ url('/rss/trending-shows?dl=1&api_token=' . ($userdata->api_token ?? '')) }}" class="inline-flex items-center px-3 py-1.5 border border-blue-300 rounded text-xs font-medium text-blue-700 bg-white dark:bg-gray-800 hover:bg-blue-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-gray-700 dark:text-blue-400 dark:border-blue-600 dark:hover:bg-gray-600" target="_blank">
|
||||
<i class="fa fa-external-link mr-1"></i>Open Feed
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex rounded-md shadow-sm">
|
||||
<input type="text" class="flex-1 rounded-l-md border-gray-300 dark:border-gray-600 font-mono text-xs focus:border-blue-500 focus:ring-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:text-white" value="{{ url('/rss/trending-shows?dl=1&api_token=' . ($userdata->api_token ?? '')) }}" readonly id="trendingShowsFeedUrl">
|
||||
<button class="inline-flex items-center px-3 py-2 border border-l-0 border-gray-300 dark:border-gray-600 rounded-r-md bg-white dark:bg-gray-800 text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:bg-gray-600 dark:text-gray-200 dark:border-gray-500 dark:hover:bg-gray-500 copy-btn" type="button" data-copy-target="trendingShowsFeedUrl">
|
||||
<i class="fa fa-copy"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Category Feeds -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
<div class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm dark:bg-gray-800 dark:border-gray-600">
|
||||
|
||||
@@ -36,7 +36,12 @@
|
||||
</h1>
|
||||
<p class="text-indigo-100">Most downloaded TV shows in the last 48 hours - Updated every hour</p>
|
||||
</div>
|
||||
<div class="text-right">
|
||||
<div class="text-right flex gap-2">
|
||||
@if(auth()->check())
|
||||
<a href="{{ url('/rss/trending-shows?dl=1&api_token=' . auth()->user()->api_token) }}" class="inline-flex items-center px-4 py-2 bg-orange-500 hover:bg-orange-600 text-white rounded-lg transition shadow-md" title="RSS Feed">
|
||||
<i class="fas fa-rss mr-2"></i> RSS Feed
|
||||
</a>
|
||||
@endif
|
||||
<a href="{{ route('series') }}" class="inline-flex items-center px-4 py-2 bg-white bg-opacity-20 hover:bg-opacity-30 text-white rounded-lg transition">
|
||||
<i class="fas fa-tv mr-2"></i> Browse All TV Shows
|
||||
</a>
|
||||
|
||||
@@ -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']);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user