From ce4d47e0f015108636ed832b3b82ca878a1b4b1c Mon Sep 17 00:00:00 2001 From: DariusIII Date: Tue, 10 Sep 2024 22:22:01 +0200 Subject: [PATCH] Move stats to their own models --- app/Console/Commands/CollectStats.php | 46 +++++++++ .../Controllers/Admin/AdminSiteController.php | 15 ++- app/Models/DownloadStat.php | 40 ++++++++ app/Models/GrabStat.php | 27 ++++++ app/Models/ReleaseStat.php | 34 +++++++ app/Models/RoleStat.php | 27 ++++++ app/Models/SignupStat.php | 26 +++++ app/Models/SiteStat.php | 95 ------------------- ...4_09_08_151127_create_grab_stats_table.php | 29 ++++++ ...09_08_151135_create_signup_stats_table.php | 29 ++++++ ...4_09_08_151158_create_role_stats_table.php | 29 ++++++ ..._08_151214_create_download_stats_table.php | 31 ++++++ ...9_08_151223_create_release_stats_table.php | 29 ++++++ resources/views/themes/admin/site-stats.tpl | 36 ++----- routes/console.php | 1 + 15 files changed, 365 insertions(+), 129 deletions(-) create mode 100644 app/Console/Commands/CollectStats.php create mode 100644 app/Models/DownloadStat.php create mode 100644 app/Models/GrabStat.php create mode 100644 app/Models/ReleaseStat.php create mode 100644 app/Models/RoleStat.php create mode 100644 app/Models/SignupStat.php create mode 100644 database/migrations/2024_09_08_151127_create_grab_stats_table.php create mode 100644 database/migrations/2024_09_08_151135_create_signup_stats_table.php create mode 100644 database/migrations/2024_09_08_151158_create_role_stats_table.php create mode 100644 database/migrations/2024_09_08_151214_create_download_stats_table.php create mode 100644 database/migrations/2024_09_08_151223_create_release_stats_table.php diff --git a/app/Console/Commands/CollectStats.php b/app/Console/Commands/CollectStats.php new file mode 100644 index 000000000..5ca733b37 --- /dev/null +++ b/app/Console/Commands/CollectStats.php @@ -0,0 +1,46 @@ +info('Collecting site stats...'); + GrabStat::insertTopGrabbers(); + $this->info('Top grabbers collected.'); + DownloadStat::insertTopDownloads(); + $this->info('Top downloads collected.'); + ReleaseStat::insertRecentlyAdded(); + $this->info('Recently added releases collected.'); + SignupStat::insertUsersByMonth(); + $this->info('New users by month collected.'); + RoleStat::insertUsersByRole(); + $this->info('Users by role collected.'); + $this->info('Site stats collected.'); + } +} diff --git a/app/Http/Controllers/Admin/AdminSiteController.php b/app/Http/Controllers/Admin/AdminSiteController.php index 6f5487984..90820b3d5 100644 --- a/app/Http/Controllers/Admin/AdminSiteController.php +++ b/app/Http/Controllers/Admin/AdminSiteController.php @@ -4,7 +4,12 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\BasePageController; use App\Models\Category; +use App\Models\DownloadStat; +use App\Models\GrabStat; +use App\Models\ReleaseStat; +use App\Models\RoleStat; use App\Models\Settings; +use App\Models\SignupStat; use App\Models\SiteStat; use Blacklight\utility\Utility; use Illuminate\Http\Request; @@ -182,19 +187,19 @@ class AdminSiteController extends BasePageController $meta_title = $title = 'Site Stats'; - $topGrabs = SiteStat::getTopGrabbers(); + $topGrabs = GrabStat::getTopGrabbers(); $this->smarty->assign('topgrabs', $topGrabs); - $topDownloads = SiteStat::getTopDownloads(); + $topDownloads = DownloadStat::getTopDownloads(); $this->smarty->assign('topdownloads', $topDownloads); - $recent = SiteStat::getRecentlyAdded(); + $recent = ReleaseStat::getRecentlyAdded(); $this->smarty->assign('recent', $recent); - $usersByMonth = SiteStat::getUsersByMonth(); + $usersByMonth = SignupStat::getUsersByMonth(); $this->smarty->assign('usersbymonth', $usersByMonth); - $usersByRole = SiteStat::usersByRole(); + $usersByRole = RoleStat::getUsersByRole(); $this->smarty->assign('usersbyrole', $usersByRole); $this->smarty->assign('totusers', 0); $this->smarty->assign('totrusers', 0); diff --git a/app/Models/DownloadStat.php b/app/Models/DownloadStat.php new file mode 100644 index 000000000..a24c39f43 --- /dev/null +++ b/app/Models/DownloadStat.php @@ -0,0 +1,40 @@ +where('grabs', '>', 0) + ->select(['id', 'searchname', 'guid', 'adddate']) + ->selectRaw('SUM(grabs) as grabs') + ->groupBy('id', 'searchname', 'adddate') + ->havingRaw('SUM(grabs) > 0') + ->orderByDesc('grabs') + ->limit(10) + ->get(); + + foreach ($releases as $release) { + self::updateOrCreate([ + 'searchname' => $release->searchname, + 'guid' => $release->guid, + 'adddate' => $release->adddate, + 'grabs' => $release->grabs, + ]); + } + } + + public static function getTopDownloads(): array + { + return self::query()->select(['searchname', 'guid', 'adddate', 'grabs'])->get()->toArray(); + } +} diff --git a/app/Models/GrabStat.php b/app/Models/GrabStat.php new file mode 100644 index 000000000..20d89fe6b --- /dev/null +++ b/app/Models/GrabStat.php @@ -0,0 +1,27 @@ +selectRaw('id, username, SUM(grabs) as grabs')->groupBy('id', 'username')->having('grabs', '>', 0)->orderByDesc('grabs')->limit(10)->get(); + // Insert data into the grab_stats table + foreach ($users as $user) { + self::updateOrCreate(['username' => $user->username], ['grabs' => $user->grabs]); + } + } + + public static function getTopGrabbers(): array + { + return self::query()->select(['username', 'grabs'])->get()->toArray(); + } +} diff --git a/app/Models/ReleaseStat.php b/app/Models/ReleaseStat.php new file mode 100644 index 000000000..1d374d3b9 --- /dev/null +++ b/app/Models/ReleaseStat.php @@ -0,0 +1,34 @@ +with('parent')->where('r.adddate', '>', now()->subWeek())->select([ + 'root_categories_id', DB::raw('COUNT(r.id) as count'), 'title', + ])->join('releases as r', 'r.categories_id', '=', + 'categories.id')->groupBy('title')->orderByDesc('count')->get(); + + foreach($categories as $category) { + self::updateOrCreate([ + 'category' => $category->title, + 'count' => $category->count, + ]); + } + } + + public static function getRecentlyAdded(): array + { + return self::query()->select(['category', 'count'])->get()->toArray(); + } +} diff --git a/app/Models/RoleStat.php b/app/Models/RoleStat.php new file mode 100644 index 000000000..6bb6986cc --- /dev/null +++ b/app/Models/RoleStat.php @@ -0,0 +1,27 @@ +select(['name'])->withCount('users')->groupBy('name')->having('users_count', '>', 0)->orderByDesc('users_count')->get(); + foreach ($roles as $role) { + self::updateOrCreate(['role' => $role->name, 'users' => $role->users_count]); + } + } + + public static function getUsersByRole(): array + { + return self::query()->select(['role', 'users'])->get()->toArray(); + } +} diff --git a/app/Models/SignupStat.php b/app/Models/SignupStat.php new file mode 100644 index 000000000..fec2e4254 --- /dev/null +++ b/app/Models/SignupStat.php @@ -0,0 +1,26 @@ +whereNotNull('created_at')->where('created_at', '<>', '0000-00-00 00:00:00')->selectRaw("DATE_FORMAT(created_at, '%M %Y') as mth, COUNT(id) as num")->groupBy(['mth'])->orderByDesc('created_at')->get(); + foreach ($users as $user) { + self::updateOrCreate(['month' => $user->mth], ['signups' => $user->num]); + } + } + + public static function getUsersByMonth(): array + { + return self::query()->select(['month', 'signups'])->get()->toArray(); + } +} diff --git a/app/Models/SiteStat.php b/app/Models/SiteStat.php index 00e72fcd1..3efc9506b 100644 --- a/app/Models/SiteStat.php +++ b/app/Models/SiteStat.php @@ -2,7 +2,6 @@ namespace App\Models; -use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Cache; @@ -14,98 +13,4 @@ class SiteStat extends Model use HasFactory; protected $guarded = []; - - /** - * @return Collection|\Illuminate\Support\Collection|static[] - */ - public static function getTopGrabbers() - { - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - $result = Cache::get(md5('topGrabbers')); - if ($result !== null) { - return $result; - } - $result = User::query()->selectRaw('id, username, SUM(grabs) as grabs')->groupBy('id', 'username')->having('grabs', '>', 0)->orderByDesc('grabs')->limit(10)->get(); - Cache::put(md5('topGrabbers'), $result, $expiresAt); - - return $result; - } - - /** - * @return Collection|\Illuminate\Support\Collection|static[] - */ - public static function getUsersByMonth() - { - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - $result = Cache::get(md5('usersByMonth')); - if ($result !== null) { - return $result; - } - $result = User::query()->whereNotNull('created_at')->where('created_at', '<>', '0000-00-00 00:00:00')->selectRaw("DATE_FORMAT(created_at, '%M %Y') as mth, COUNT(id) as num")->groupBy(['mth'])->orderByDesc('created_at')->get(); - - Cache::put(md5('usersByMonth'), $result, $expiresAt); - - return $result; - } - - /** - * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[] - */ - public static function getTopDownloads() - { - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - $result = Cache::get(md5('topDownloads')); - if ($result !== null) { - return $result; - } - $result = Release::query() - ->where('grabs', '>', 0) - ->select(['id', 'searchname', 'guid', 'adddate']) - ->selectRaw('SUM(grabs) as grabs') - ->groupBy('id', 'searchname', 'adddate') - ->havingRaw('SUM(grabs) > 0') - ->orderByDesc('grabs') - ->limit(10) - ->get(); - - Cache::put(md5('topDownloads'), $result, $expiresAt); - - return $result; - } - - /** - * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|static[] - */ - public static function getRecentlyAdded() - { - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - $result = Cache::get(md5('RecentlyAdded')); - if ($result !== null) { - return $result; - } - - $result = Category::query()->with('parent')->where('r.adddate', '>', now()->subWeek())->select([ - 'root_categories_id', DB::raw('COUNT(r.id) as count'), 'title', - ])->join('releases as r', 'r.categories_id', '=', - 'categories.id')->groupBy('title')->orderByDesc('count')->get(); - - Cache::put(md5('RecentlyAdded'), $result, $expiresAt); - - return $result; - } - - public static function usersByRole() - { - $expiresAt = now()->addMinutes(config('nntmux.cache_expiry_long')); - $result = Cache::get(md5('usersByRole')); - if ($result !== null) { - return $result; - } - - $result = Role::query()->select(['name'])->withCount('users')->groupBy('name')->having('users_count', '>', 0)->orderByDesc('users_count')->get(); - - Cache::put(md5('usersByRole'), $result, $expiresAt); - - return $result; - } } diff --git a/database/migrations/2024_09_08_151127_create_grab_stats_table.php b/database/migrations/2024_09_08_151127_create_grab_stats_table.php new file mode 100644 index 000000000..e92be2adf --- /dev/null +++ b/database/migrations/2024_09_08_151127_create_grab_stats_table.php @@ -0,0 +1,29 @@ +id(); + $table->timestamps(); + $table->string('username')->nullable(); + $table->integer('grabs')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('grab_stats'); + } +}; diff --git a/database/migrations/2024_09_08_151135_create_signup_stats_table.php b/database/migrations/2024_09_08_151135_create_signup_stats_table.php new file mode 100644 index 000000000..1766fdf4b --- /dev/null +++ b/database/migrations/2024_09_08_151135_create_signup_stats_table.php @@ -0,0 +1,29 @@ +id(); + $table->timestamps(); + $table->string('month')->nullable(); + $table->integer('signups')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('signup_stats'); + } +}; diff --git a/database/migrations/2024_09_08_151158_create_role_stats_table.php b/database/migrations/2024_09_08_151158_create_role_stats_table.php new file mode 100644 index 000000000..47d540394 --- /dev/null +++ b/database/migrations/2024_09_08_151158_create_role_stats_table.php @@ -0,0 +1,29 @@ +id(); + $table->timestamps(); + $table->string('role')->nullable(); + $table->integer('users')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('role_stats'); + } +}; diff --git a/database/migrations/2024_09_08_151214_create_download_stats_table.php b/database/migrations/2024_09_08_151214_create_download_stats_table.php new file mode 100644 index 000000000..894768961 --- /dev/null +++ b/database/migrations/2024_09_08_151214_create_download_stats_table.php @@ -0,0 +1,31 @@ +id(); + $table->timestamps(); + $table->string('searchname')->nullable(); + $table->integer('grabs')->default(0); + $table->string('guid')->nullable(); + $table->dateTime('adddate')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('download_stats'); + } +}; diff --git a/database/migrations/2024_09_08_151223_create_release_stats_table.php b/database/migrations/2024_09_08_151223_create_release_stats_table.php new file mode 100644 index 000000000..f9c6e7560 --- /dev/null +++ b/database/migrations/2024_09_08_151223_create_release_stats_table.php @@ -0,0 +1,29 @@ +id(); + $table->timestamps(); + $table->string('category', 255)->index(); + $table->integer('count')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('release_stats'); + } +}; diff --git a/resources/views/themes/admin/site-stats.tpl b/resources/views/themes/admin/site-stats.tpl index 1b8307020..857e7aeb1 100644 --- a/resources/views/themes/admin/site-stats.tpl +++ b/resources/views/themes/admin/site-stats.tpl @@ -33,10 +33,10 @@ {foreach from=$usersbymonth item=result} - {assign var="totusers" value=$totusers+$result.num} + {assign var="totusers" value=$totusers+$result.signups} - {$result.mth} - {$result.num} + {$result.month} + {$result.signups} {/foreach} @@ -57,10 +57,10 @@ {foreach from=$usersbyrole item=result} - {assign var="totrusers" value=$totrusers+$result.users_count} + {assign var="totrusers" value=$totrusers+$result.users} - {$result.name} - {$result.users_count} + {$result.role} + {$result.users} {/foreach} @@ -106,7 +106,7 @@ {foreach from=$recent item=result} - {$result->parent->title} > {$result->title} + {$result.category} > {$result.category} {$result.count} {/foreach} @@ -114,26 +114,4 @@

- - {if $topcomments|count > 0} -

Top Comments

- - - - - - - - {foreach from=$topcomments item=result} - - - - - - {/foreach} - -
ReleaseCommentsDays Ago
{$result.searchname|escape:"htmlall"|replace:".":" "} - {$result.comments}{$result.adddate|timeago}
- {/if} diff --git a/routes/console.php b/routes/console.php index 1febec52c..b0e61085b 100644 --- a/routes/console.php +++ b/routes/console.php @@ -28,6 +28,7 @@ Schedule::command('telescope:prune')->daily(); Schedule::command('horizon:snapshot')->everyFiveMinutes()->withoutOverlapping(); Schedule::command('cloudflare:reload')->daily(); Schedule::command('cache:prune-stale-tags')->hourly(); +Schedule::command('nntmux:collect-stats')->hourly(); if (config('nntmux.purge_inactive_users') === true) { Schedule::job(new RemoveInactiveAccounts)->daily(); }