mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-02-12 22:49:41 -06:00
update: top10 to be grouped by the torrent category
This commit is contained in:
@@ -13,73 +13,100 @@
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Models\Category;
|
||||
use App\Models\Torrent;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Livewire\Component;
|
||||
|
||||
/**
|
||||
* @property \Illuminate\Database\Eloquent\Collection<int, Torrent> $works
|
||||
* @property array<string, string> $metaTypes
|
||||
*/
|
||||
class Top10 extends Component
|
||||
{
|
||||
final public function getTorrentsDayProperty()
|
||||
{
|
||||
$matches = Cache::remember('top10DayMatches', 3_600, fn () => DB::select('SELECT torrent_id, count(*) FROM history WHERE completed_at >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 DAY) GROUP BY torrent_id ORDER BY count(*) DESC LIMIT 10'));
|
||||
public string $metaType = 'movie_meta';
|
||||
|
||||
return Cache::remember('top10DayTorrents', 3_600, fn () => Torrent::with(['user:id,username,group_id' => ['group:id,name,color,icon,effect'], 'category', 'type', 'resolution'])
|
||||
->whereIntegerInRaw('id', collect($matches)->pluck('torrent_id')->toArray())
|
||||
->get());
|
||||
public string $interval = 'day';
|
||||
|
||||
/**
|
||||
* @var array<string, mixed>
|
||||
*/
|
||||
protected $queryString = [
|
||||
'metaType' => ['except' => 'movie_meta'],
|
||||
'interval' => ['except' => 'day'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<string, string>
|
||||
*/
|
||||
protected $rules = [
|
||||
'metaType' => 'in:movie_meta,tv_meta',
|
||||
'interval' => 'in:day,week,month,year,all',
|
||||
];
|
||||
|
||||
/**
|
||||
* @return \Illuminate\Database\Eloquent\Collection<int, Torrent>
|
||||
*/
|
||||
final public function getWorksProperty(): Collection
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
return cache()->remember(
|
||||
'top10-'.$this->interval.'-'.$this->metaType,
|
||||
3600,
|
||||
fn () => Torrent::query()
|
||||
->when(
|
||||
$this->metaType === 'tv_meta',
|
||||
fn ($query) => $query->with('tv'),
|
||||
fn ($query) => $query->with('movie'),
|
||||
)
|
||||
->select([
|
||||
'tmdb',
|
||||
DB::raw('MIN(category_id) as category_id'),
|
||||
DB::raw('COUNT(*) as download_count'),
|
||||
])
|
||||
->join('history', 'history.torrent_id', '=', 'torrents.id')
|
||||
->where('tmdb', '!=', 0)
|
||||
->when($this->interval === 'day', fn ($query) => $query->whereBetween('history.completed_at', [now()->subDay(), now()]))
|
||||
->when($this->interval === 'week', fn ($query) => $query->whereBetween('history.completed_at', [now()->subWeek(), now()]))
|
||||
->when($this->interval === 'month', fn ($query) => $query->whereBetween('history.completed_at', [now()->subMonth(), now()]))
|
||||
->when($this->interval === 'year', fn ($query) => $query->whereBetween('history.completed_at', [now()->subYear(), now()]))
|
||||
->when($this->interval === 'all', fn ($query) => $query->whereNotNull('history.completed_at'))
|
||||
->whereIn('torrents.category_id', Category::select('id')->where($this->metaType, '=', true))
|
||||
// Small torrents screw the stats since users download them only to farm bon.
|
||||
->where('torrents.size', '>', 1024 * 1024 * 1024)
|
||||
->groupBy('tmdb')
|
||||
->orderByRaw('COUNT(*) DESC')
|
||||
->limit(250)
|
||||
->get('tmdb')
|
||||
);
|
||||
}
|
||||
|
||||
final public function getTorrentsWeekProperty()
|
||||
/**
|
||||
* @return array<string, string>
|
||||
*/
|
||||
final public function getMetaTypesProperty(): array
|
||||
{
|
||||
$matches = Cache::remember('top10WeekMatches', 3_600, fn () => DB::select('SELECT torrent_id, count(*) FROM history WHERE completed_at >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 WEEK) GROUP BY torrent_id ORDER BY count(*) DESC LIMIT 10'));
|
||||
$metaTypes = [];
|
||||
|
||||
return Cache::remember('top10WeekTorrents', 3_600, fn () => Torrent::with(['user:id,username,group_id' => ['group:id,name,color,icon,effect'], 'category', 'type', 'resolution'])
|
||||
->whereIntegerInRaw('id', collect($matches)->pluck('torrent_id')->toArray())
|
||||
->get());
|
||||
}
|
||||
if (Category::where('movie_meta', '=', true)->exists()) {
|
||||
$metaTypes[__('mediahub.movie')] = 'movie_meta';
|
||||
}
|
||||
|
||||
final public function getTorrentsMonthProperty()
|
||||
{
|
||||
$matches = Cache::remember('top10MonthMatches', 3_600, fn () => DB::select('SELECT torrent_id, count(*) FROM history WHERE completed_at >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 MONTH) GROUP BY torrent_id ORDER BY count(*) DESC LIMIT 10'));
|
||||
if (Category::where('tv_meta', '=', true)->exists()) {
|
||||
$metaTypes[__('mediahub.show')] = 'tv_meta';
|
||||
}
|
||||
|
||||
return Cache::remember('top10MonthTorrents', 3_600, fn () => Torrent::with(['user:id,username,group_id' => ['group:id,name,color,icon,effect'], 'category', 'type', 'resolution'])
|
||||
->whereIntegerInRaw('id', collect($matches)->pluck('torrent_id')->toArray())
|
||||
->get());
|
||||
}
|
||||
|
||||
final public function getTorrentsYearProperty()
|
||||
{
|
||||
$matches = Cache::remember('top10YearMatches', 3_600, fn () => DB::select('SELECT torrent_id, count(*) FROM history WHERE completed_at >= DATE_ADD(CURRENT_TIMESTAMP, INTERVAL -1 YEAR) GROUP BY torrent_id ORDER BY count(*) DESC LIMIT 10'));
|
||||
|
||||
return Cache::remember('top10YearTorrents', 3_600, fn () => Torrent::with(['user:id,username,group_id' => ['group:id,name,color,icon,effect'], 'category', 'type', 'resolution'])
|
||||
->whereIntegerInRaw('id', collect($matches)->pluck('torrent_id')->toArray())
|
||||
->get());
|
||||
}
|
||||
|
||||
final public function getTorrentsAllProperty()
|
||||
{
|
||||
$matches = Cache::remember('top10AllMatches', 3_600, fn () => DB::select('SELECT torrent_id, count(*) FROM history GROUP BY torrent_id ORDER BY count(*) DESC LIMIT 10'));
|
||||
|
||||
return Cache::remember('top10AllTorrents', 3_600, fn () => Torrent::with(['user:id,username,group_id' => ['group:id,name,color,icon,effect'], 'category', 'type', 'resolution'])
|
||||
->whereIntegerInRaw('id', collect($matches)->pluck('torrent_id')->toArray())
|
||||
->get());
|
||||
}
|
||||
|
||||
final public function getPersonalFreeleechProperty()
|
||||
{
|
||||
return cache()->get('personal_freeleech:'.auth()->id());
|
||||
return $metaTypes;
|
||||
}
|
||||
|
||||
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
return view('livewire.top10', [
|
||||
'user' => auth()->user(),
|
||||
'torrentsDay' => $this->torrentsDay,
|
||||
'torrentsWeek' => $this->torrentsWeek,
|
||||
'torrentsMonth' => $this->torrentsMonth,
|
||||
'torrentsYear' => $this->torrentsYear,
|
||||
'torrentsAll' => $this->torrentsAll,
|
||||
'personalFreeleech' => $this->personalFreeleech,
|
||||
'user' => auth()->user(),
|
||||
'works' => $this->works,
|
||||
'metaTypes' => $this->metaTypes,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3620,66 +3620,6 @@ parameters:
|
||||
count: 1
|
||||
path: app/Http/Livewire/TicketSearch.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$personalFreeleech\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$torrentsAll\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$torrentsDay\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$torrentsMonth\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$torrentsWeek\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\Top10\\:\\:\\$torrentsYear\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getPersonalFreeleechProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getTorrentsAllProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getTorrentsDayProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getTorrentsMonthProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getTorrentsWeekProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Http\\\\Livewire\\\\Top10\\:\\:getTorrentsYearProperty\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: app/Http/Livewire/Top10.php
|
||||
|
||||
-
|
||||
message: "#^Access to an undefined property App\\\\Http\\\\Livewire\\\\TopicPostSearch\\:\\:\\$posts\\.$#"
|
||||
count: 1
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
@import 'pages/request';
|
||||
@import 'pages/staff';
|
||||
@import 'pages/stats';
|
||||
@import 'pages/top10';
|
||||
@import 'pages/torrent';
|
||||
@import 'pages/torrents';
|
||||
@import 'pages/user';
|
||||
|
||||
23
resources/sass/pages/_top10.scss
Normal file
23
resources/sass/pages/_top10.scss
Normal file
@@ -0,0 +1,23 @@
|
||||
.top10-poster {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 1fr auto;
|
||||
}
|
||||
|
||||
.top10-poster > .torrent-search--poster__result {
|
||||
grid-area: 1 / 1 / 3 / 3;
|
||||
}
|
||||
|
||||
.top10-poster__download-count {
|
||||
grid-area: 2 / 3 / 1 / 2;
|
||||
border-radius: 9999px;
|
||||
margin: 6px;
|
||||
background: #161A42;
|
||||
border: 2px solid #73904b;
|
||||
height: 36px;
|
||||
line-height: 32px;
|
||||
width: 36px;
|
||||
box-shadow: 0 8px 10px 1px rgba(0,0,0,0.14), 0 3px 14px 2px rgba(0,0,0,0.12), 0 5px 5px -3px rgba(0,0,0,0.20);
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -1,33 +1,60 @@
|
||||
<div style="display: contents">
|
||||
@foreach([
|
||||
'Top 10 (Day)' => $torrentsDay,
|
||||
'Top 10 (Week)' => $torrentsWeek,
|
||||
'Top 10 (Month)' => $torrentsMonth,
|
||||
'Top 10 (Year)' => $torrentsYear,
|
||||
'Top 10 (All Time)' => $torrentsAll
|
||||
] as $title => $torrents)
|
||||
<section class="panelV2">
|
||||
<h2 class="panel__heading">{{ $title }}</h2>
|
||||
<div class="data-table-wrapper">
|
||||
<table class="data-table">
|
||||
<tbody>
|
||||
@foreach($torrents->loadExists([
|
||||
'bookmarks' => fn ($query) => $query->where('user_id', '=', auth()->id()),
|
||||
'freeleechTokens' => fn ($query) => $query->where('user_id', '=', auth()->id()),
|
||||
]) as $torrent)
|
||||
@php
|
||||
$meta = match(true) {
|
||||
$torrent->category->tv_meta && $torrent->tmdb != 0 => App\Models\Tv::find($torrent->tmdb),
|
||||
$torrent->category->movie_meta && $torrent->tmdb != 0 => App\Models\Movie::find($torrent->tmdb),
|
||||
$torrent->category->game_meta && $torrent->igdb != 0 => MarcReichel\IGDBLaravel\Models\Game::with(['cover' => ['url', 'image_id']])->find($torrent->igdb),
|
||||
default => null,
|
||||
};
|
||||
@endphp
|
||||
<x-torrent.row :$torrent :$meta :$personalFreeleech />
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h2 class="panel__heading">Top Titles</h2>
|
||||
<div class="panel__actions">
|
||||
<div class="panel__action">
|
||||
<div class="form__group">
|
||||
<select id="interval" class="form__select" type="date" name="interval" wire:model="interval">
|
||||
<option value="day">Past Day</option>
|
||||
<option value="week">Past Week</option>
|
||||
<option value="month">Past Month</option>
|
||||
<option value="year">Past Year</option>
|
||||
<option value="all">All-time</option>
|
||||
</select>
|
||||
<label class="form__label form__label--floating" for="interval">
|
||||
Interval
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="panel__action">
|
||||
<div class="form__group">
|
||||
<select id="metaType" class="form__select" type="date" name="metaType" wire:model="metaType">
|
||||
@foreach ($metaTypes as $name => $type)
|
||||
<option value="{{ $type }}">{{ $name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<label class="form__label form__label--floating" for="metaType">
|
||||
Category
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div class="panel__body torrent-search--poster__results">
|
||||
<div wire:loading.delay>Computing...</div>
|
||||
@switch ($this->metaType)
|
||||
@case ('movie_meta')
|
||||
@foreach($works as $work)
|
||||
<figure class="top10-poster">
|
||||
<x-movie.poster :media="$work" />
|
||||
<figcaption class="top10-poster__download-count" title="{{ __('torrent.completed-times') }}">
|
||||
{{ $work->download_count }}
|
||||
</figcaption>
|
||||
</figure>
|
||||
@endforeach
|
||||
|
||||
@break
|
||||
@case ('tv_meta')
|
||||
@foreach($works as $work)
|
||||
<figure class="top10-poster">
|
||||
<x-tv.poster :media="$work" />
|
||||
<figcaption class="top10-poster__download-count" title="{{ __('torrent.completed-times') }}">
|
||||
{{ $work->download_count }}
|
||||
</figcaption>
|
||||
</figure>
|
||||
@endforeach
|
||||
|
||||
@break
|
||||
@endswitch
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user