18
18
19
19
use App \Models \Category ;
20
20
use App \Models \History ;
21
+ use App \Models \TmdbMovie ;
22
+ use App \Models \TmdbTv ;
21
23
use App \Models \Torrent ;
22
24
use Illuminate \Database \Eloquent \Collection ;
23
25
use Illuminate \Database \Query \JoinClause ;
@@ -42,7 +44,7 @@ class Top10 extends Component
42
44
public string $ metaType = 'movie_meta ' ;
43
45
44
46
#[Url(history: true )]
45
- #[Validate('in:day,week,weekly,month,monthly,year,all,custom ' )]
47
+ #[Validate('in:day,week,weekly,month,monthly,year,release_year, all,custom ' )]
46
48
public string $ interval = 'day ' ;
47
49
48
50
#[Url(history: true )]
@@ -207,6 +209,61 @@ final public function monthly(): Collection
207
209
);
208
210
}
209
211
212
+ /**
213
+ * @return Collection<int|string, Collection<int, Torrent>>
214
+ * @phpstan-ignore generics.notSubtype (I can't figure out the correct return type to silence this error)
215
+ */
216
+ #[Computed]
217
+ final public function releaseYear (): Collection
218
+ {
219
+ $ this ->validate ();
220
+
221
+ $ metaIdColumn = match ($ this ->metaType ) {
222
+ 'tv_meta ' => 'tmdb_tv_id ' ,
223
+ default => 'tmdb_movie_id ' ,
224
+ };
225
+
226
+ return cache ()->remember (
227
+ 'top10-by-release-year: ' .$ this ->metaType ,
228
+ 24 * 3600 ,
229
+ fn () => Torrent::query ()
230
+ ->withoutGlobalScopes ()
231
+ ->with ($ this ->metaType === 'movie_meta ' ? 'movie ' : 'tv ' )
232
+ ->fromSub (
233
+ Torrent::query ()
234
+ ->withoutGlobalScopes ()
235
+ ->whereRelation ('category ' , $ this ->metaType , '= ' , true )
236
+ ->leftJoin ('tmdb_movies ' , 'torrents.tmdb_movie_id ' , '= ' , 'tmdb_movies.id ' )
237
+ ->leftJoin ('tmdb_tv ' , 'torrents.tmdb_tv_id ' , '= ' , 'tmdb_tv.id ' )
238
+ ->select ([
239
+ $ metaIdColumn ,
240
+ DB ::raw ('MIN(category_id) as category_id ' ),
241
+ DB ::raw ('SUM(times_completed) AS download_count ' ),
242
+ 'the_year ' => $ this ->metaType === 'movie_meta '
243
+ ? TmdbMovie::query ()
244
+ ->selectRaw ('EXTRACT(YEAR FROM tmdb_movies.release_date) ' )
245
+ ->whereColumn ('tmdb_movies.id ' , '= ' , 'torrents.tmdb_movie_id ' )
246
+ : TmdbTv::query ()
247
+ ->selectRaw ('EXTRACT(YEAR FROM first_air_date) ' )
248
+ ->whereColumn ('tmdb_tv.id ' , '= ' , 'torrents.tmdb_movie_id ' ),
249
+ DB ::raw ('ROW_NUMBER() OVER (PARTITION BY COALESCE(EXTRACT(YEAR FROM MAX(tmdb_movies.release_date)), EXTRACT(YEAR FROM MAX(tmdb_tv.first_air_date))) ORDER BY SUM(times_completed) DESC) AS place ' ),
250
+ ])
251
+ ->where ($ metaIdColumn , '!= ' , 0 )
252
+ // Small torrents screw the stats since users download them only to farm bon.
253
+ ->where ('torrents.size ' , '> ' , 1024 * 1024 * 1024 )
254
+ ->havingNotNull ('the_year ' )
255
+ ->where (fn ($ query ) => $ query ->whereNotNull ('tmdb_movies.id ' )->orWhereNotNull ('tmdb_tv.id ' ))
256
+ ->groupBy ('the_year ' , $ metaIdColumn ),
257
+ 'ranked_groups ' ,
258
+ )
259
+ ->where ('place ' , '<= ' , 10 )
260
+ ->orderByDesc ('the_year ' )
261
+ ->orderBy ('place ' )
262
+ ->get ()
263
+ ->groupBy ('the_year ' )
264
+ );
265
+ }
266
+
210
267
/**
211
268
* @return array<string, string>
212
269
*/
@@ -241,9 +298,10 @@ final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\C
241
298
return view ('livewire.top10 ' , [
242
299
'user ' => auth ()->user (),
243
300
'works ' => match ($ this ->interval ) {
244
- 'weekly ' => $ this ->weekly ,
245
- 'monthly ' => $ this ->monthly ,
246
- default => $ this ->works ,
301
+ 'weekly ' => $ this ->weekly ,
302
+ 'monthly ' => $ this ->monthly ,
303
+ 'release_year ' => $ this ->releaseYear ,
304
+ default => $ this ->works ,
247
305
},
248
306
'metaTypes ' => $ this ->metaTypes ,
249
307
]);
0 commit comments