mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 01:08:56 +00:00
Move stats to their own models
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\DownloadStat;
|
||||
use App\Models\GrabStat;
|
||||
use App\Models\ReleaseStat;
|
||||
use App\Models\RoleStat;
|
||||
use App\Models\SignupStat;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class CollectStats extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'nntmux:collect-stats';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Collects and stores various statistics about the site.';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$this->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.');
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DownloadStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function insertTopDownloads(): void
|
||||
{
|
||||
$releases = 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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class GrabStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function insertTopGrabbers(): void
|
||||
{
|
||||
$users = User::query()->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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ReleaseStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function insertRecentlyAdded(): void
|
||||
{
|
||||
$categories = 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();
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
class RoleStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function insertUsersByRole(): void
|
||||
{
|
||||
$roles = Role::query()->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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class SignupStat extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
public static function insertUsersByMonth(): void
|
||||
{
|
||||
$users = 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();
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('grab_stats', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
$table->string('username')->nullable();
|
||||
$table->integer('grabs')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('grab_stats');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('signup_stats', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
$table->string('month')->nullable();
|
||||
$table->integer('signups')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('signup_stats');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('role_stats', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
$table->string('role')->nullable();
|
||||
$table->integer('users')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('role_stats');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('download_stats', function (Blueprint $table) {
|
||||
$table->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');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('release_stats', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->timestamps();
|
||||
$table->string('category', 255)->index();
|
||||
$table->integer('count')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('release_stats');
|
||||
}
|
||||
};
|
||||
@@ -33,10 +33,10 @@
|
||||
</tr>
|
||||
|
||||
{foreach from=$usersbymonth item=result}
|
||||
{assign var="totusers" value=$totusers+$result.num}
|
||||
{assign var="totusers" value=$totusers+$result.signups}
|
||||
<tr class="{cycle values=",alt"}">
|
||||
<td width="75%">{$result.mth}</td>
|
||||
<td>{$result.num}</td>
|
||||
<td width="75%">{$result.month}</td>
|
||||
<td>{$result.signups}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
<tr>
|
||||
@@ -57,10 +57,10 @@
|
||||
</tr>
|
||||
|
||||
{foreach from=$usersbyrole item=result}
|
||||
{assign var="totrusers" value=$totrusers+$result.users_count}
|
||||
{assign var="totrusers" value=$totrusers+$result.users}
|
||||
<tr class="{cycle values=",alt"}">
|
||||
<td width="75%">{$result.name}</td>
|
||||
<td>{$result.users_count}</td>
|
||||
<td width="75%">{$result.role}</td>
|
||||
<td>{$result.users}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
<tr>
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
{foreach from=$recent item=result}
|
||||
<tr class="{cycle values=",alt"}">
|
||||
<td>{$result->parent->title} > {$result->title}</td>
|
||||
<td>{$result.category} > {$result.category}</td>
|
||||
<td>{$result.count}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
@@ -114,26 +114,4 @@
|
||||
</table>
|
||||
|
||||
<br/><br/>
|
||||
|
||||
{if $topcomments|count > 0}
|
||||
<h2>Top Comments</h2>
|
||||
<table style="width:100%;margin-top:10px;" class="data table table-striped responsive-utilities jambo-table">
|
||||
<tr>
|
||||
<th>Release</th>
|
||||
<th>Comments</th>
|
||||
<th>Days Ago</th>
|
||||
</tr>
|
||||
|
||||
{foreach from=$topcomments item=result}
|
||||
<tr class="{cycle values=",alt"}">
|
||||
<td width="75%"><a
|
||||
href="{{url("/details/{$result.guid}/#comments")}}">{$result.searchname|escape:"htmlall"|replace:".":" "}</a>
|
||||
</td>
|
||||
<td>{$result.comments}</td>
|
||||
<td>{$result.adddate|timeago}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
|
||||
</table>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user