update: top10 to be grouped by the torrent category

This commit is contained in:
Roardom
2023-08-29 12:02:49 +00:00
parent a4dae73489
commit 87ae4a8a5f
5 changed files with 159 additions and 141 deletions

View File

@@ -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,
]);
}
}

View File

@@ -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

View File

@@ -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';

View 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;
}

View File

@@ -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>