mirror of
https://github.com/VueFileManager/vuefilemanager.git
synced 2026-04-05 18:23:48 +00:00
record daily usage
This commit is contained in:
34
database/factories/TrafficFactory.php
Normal file
34
database/factories/TrafficFactory.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories;
|
||||
|
||||
use Domain\Sharing\Models\Share;
|
||||
use Domain\Traffic\Models\Traffic;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class TrafficFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = Traffic::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'id' => $this->faker->uuid,
|
||||
'user_id' => $this->faker->uuid,
|
||||
'upload' => rand(11111111, 99999999),
|
||||
'download' => rand(11111111, 99999999),
|
||||
'created_at' => $this->faker->dateTimeBetween('-month'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ use Support\Scheduler\Actions\DeleteFailedFilesAction;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use Support\Scheduler\Actions\DeleteUnverifiedUsersAction;
|
||||
use Support\Scheduler\Actions\DeleteExpiredShareLinksAction;
|
||||
use Support\Scheduler\Actions\ReportUsageAction;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
@@ -26,7 +27,7 @@ class Kernel extends ConsoleKernel
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
if (! is_storage_driver(['local'])) {
|
||||
if (! is_storage_driver('local')) {
|
||||
$schedule->call(
|
||||
fn () => resolve(DeleteFailedFilesAction::class)()
|
||||
)->everySixHours();
|
||||
@@ -38,7 +39,11 @@ class Kernel extends ConsoleKernel
|
||||
|
||||
$schedule->call(
|
||||
fn () => resolve(DeleteUnverifiedUsersAction::class)()
|
||||
)->daily();
|
||||
)->daily()->at('00:05');
|
||||
|
||||
$schedule->call(
|
||||
fn () => resolve(ReportUsageAction::class)()
|
||||
)->daily()->at('00:10');
|
||||
|
||||
// Run queue jobs every minute
|
||||
$schedule->command('queue:work --stop-when-empty')
|
||||
@@ -48,10 +53,10 @@ class Kernel extends ConsoleKernel
|
||||
// Backup app database daily
|
||||
$schedule->command('backup:clean')
|
||||
->daily()
|
||||
->at('01:00');
|
||||
->at('00:15');
|
||||
$schedule->command('backup:run --only-db')
|
||||
->daily()
|
||||
->at('01:30');
|
||||
->at('00:20');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,7 +76,7 @@ class UploadFileAction
|
||||
$disk_local->move("chunks/$chunkName", "files/$user_id/$fileName");
|
||||
|
||||
// Move files to external storage
|
||||
if (! is_storage_driver(['local'])) {
|
||||
if (! is_storage_driver('local')) {
|
||||
($this->moveFileToExternalStorage)($fileName, $user_id);
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class File extends Model
|
||||
$links = [];
|
||||
|
||||
// Generate thumbnail link for external storage service
|
||||
if ($this->type === 'image' && ! is_storage_driver(['local'])) {
|
||||
if ($this->type === 'image' && ! is_storage_driver('local')) {
|
||||
foreach (config('vuefilemanager.image_sizes') as $item) {
|
||||
$filePath = "files/{$this->user_id}/{$item['name']}-{$this->basename}";
|
||||
|
||||
@@ -127,7 +127,7 @@ class File extends Model
|
||||
public function getFileUrlAttribute(): string
|
||||
{
|
||||
// Get file from external storage
|
||||
if (! is_storage_driver(['local'])) {
|
||||
if (! is_storage_driver('local')) {
|
||||
$file_pretty_name = is_storage_driver('backblaze')
|
||||
? Str::snake(mb_strtolower($this->attributes['name']))
|
||||
: get_pretty_name($this->attributes['basename'], $this->attributes['name'], $this->attributes['mimetype']);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace Domain\Traffic\Models;
|
||||
|
||||
use Database\Factories\TrafficFactory;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
@@ -22,6 +23,11 @@ class Traffic extends Model
|
||||
|
||||
protected $keyType = 'string';
|
||||
|
||||
protected static function newFactory(): TrafficFactory
|
||||
{
|
||||
return TrafficFactory::new();
|
||||
}
|
||||
|
||||
public function scopeCurrentDay($query): Builder
|
||||
{
|
||||
return $query->whereDate('created_at', today());
|
||||
|
||||
49
src/Support/Scheduler/Actions/ReportUsageAction.php
Normal file
49
src/Support/Scheduler/Actions/ReportUsageAction.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Support\Scheduler\Actions;
|
||||
|
||||
use DB;
|
||||
use VueFileManager\Subscription\Domain\Subscriptions\Models\Subscription;
|
||||
|
||||
class ReportUsageAction
|
||||
{
|
||||
public function __invoke()
|
||||
{
|
||||
Subscription::whereIn('type', ['pre-paid', 'auto-renew'])
|
||||
->where('status', 'active')
|
||||
->cursor()
|
||||
->each(function($subscription) {
|
||||
$this->recordBandwidth($subscription);
|
||||
$this->recordStorageCapacity($subscription);
|
||||
});
|
||||
}
|
||||
|
||||
private function recordStorageCapacity(Subscription $subscription): void
|
||||
{
|
||||
// Sum all file size
|
||||
$filesize = DB::table('files')
|
||||
->where('user_id', $subscription->user->id)
|
||||
->sum('filesize');
|
||||
|
||||
// We count storage size in GB, e.g. 0.15 is 150mb
|
||||
$amount = $filesize / 1000000000;
|
||||
|
||||
// Record storage capacity usage
|
||||
$subscription->recordUsage('storage', $amount);
|
||||
}
|
||||
|
||||
private function recordBandwidth(Subscription $subscription): void
|
||||
{
|
||||
// We count storage size in GB, e.g. 0.15 is 150mb
|
||||
$record = $subscription
|
||||
->user
|
||||
->traffics()
|
||||
->where('created_at', today()->subDay())
|
||||
->first();
|
||||
|
||||
$amount = ($record->download ?? 0) / 1000000000;
|
||||
|
||||
// Record storage capacity usage
|
||||
$subscription->recordUsage('bandwidth', $amount);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Domain\Traffic;
|
||||
|
||||
use Domain\Traffic\Models\Traffic;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Storage;
|
||||
use Tests\TestCase;
|
||||
use App\Users\Models\User;
|
||||
@@ -9,12 +12,11 @@ use Domain\Files\Models\File;
|
||||
use Domain\Sharing\Models\Share;
|
||||
use Domain\Folders\Models\Folder;
|
||||
use Illuminate\Http\UploadedFile;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class TrafficTest extends TestCase
|
||||
{
|
||||
public UploadedFile $file;
|
||||
public User $user;
|
||||
public Model $user;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
@@ -62,9 +64,9 @@ class TrafficTest extends TestCase
|
||||
])->assertStatus(201);
|
||||
|
||||
$this->assertDatabaseHas('traffic', [
|
||||
'user_id' => $this->user->id,
|
||||
'upload' => 991,
|
||||
'created_at' => now(),
|
||||
'user_id' => $this->user->id,
|
||||
'upload' => 991,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
$this->travel(1)->day();
|
||||
@@ -82,9 +84,9 @@ class TrafficTest extends TestCase
|
||||
])->assertStatus(201);
|
||||
|
||||
$this->assertDatabaseHas('traffic', [
|
||||
'user_id' => $this->user->id,
|
||||
'upload' => 991,
|
||||
'created_at' => now(),
|
||||
'user_id' => $this->user->id,
|
||||
'upload' => 991,
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
$this->assertDatabaseCount('traffic', 2);
|
||||
@@ -193,21 +195,18 @@ class TrafficTest extends TestCase
|
||||
*/
|
||||
public function it_get_user_traffic_test()
|
||||
{
|
||||
$user = User::factory()
|
||||
->create();
|
||||
|
||||
foreach (range(0, 30) as $day) {
|
||||
DB::table('traffic')->insert([
|
||||
'id' => Str::uuid(),
|
||||
'user_id' => $user->id,
|
||||
'upload' => 10000 * $day,
|
||||
'download' => 1000000 * $day,
|
||||
'created_at' => now()->subDays($day),
|
||||
'updated_at' => now()->subDays($day),
|
||||
]);
|
||||
Traffic::factory()
|
||||
->create([
|
||||
'user_id' => $this->user->id,
|
||||
'upload' => 10000 * $day,
|
||||
'download' => 1000000 * $day,
|
||||
'created_at' => now()->subDays($day),
|
||||
'updated_at' => now()->subDays($day),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->actingAs($user)
|
||||
$this->actingAs($this->user)
|
||||
->get('/api/user/storage')
|
||||
->assertOk()
|
||||
->assertJsonFragment([
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Support\Scheduler;
|
||||
|
||||
use Domain\Files\Models\File;
|
||||
use Domain\Traffic\Models\Traffic;
|
||||
use Storage;
|
||||
use Support\Scheduler\Actions\ReportUsageAction;
|
||||
use Tests\TestCase;
|
||||
use App\Users\Models\User;
|
||||
use Domain\Sharing\Models\Share;
|
||||
@@ -9,9 +13,71 @@ use Illuminate\Http\UploadedFile;
|
||||
use Support\Scheduler\Actions\DeleteFailedFilesAction;
|
||||
use Support\Scheduler\Actions\DeleteUnverifiedUsersAction;
|
||||
use Support\Scheduler\Actions\DeleteExpiredShareLinksAction;
|
||||
use VueFileManager\Subscription\Domain\Plans\Models\Plan;
|
||||
use VueFileManager\Subscription\Domain\Plans\Models\PlanMeteredFeature;
|
||||
use VueFileManager\Subscription\Domain\Subscriptions\Models\Subscription;
|
||||
|
||||
class SchedulerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function it_report_usage_of_subscription()
|
||||
{
|
||||
$user = User::factory()
|
||||
->create();
|
||||
|
||||
$plan = Plan::factory()
|
||||
->create([
|
||||
'type' => 'metered',
|
||||
]);
|
||||
|
||||
PlanMeteredFeature::factory()
|
||||
->count(2)
|
||||
->sequence(
|
||||
['key' => 'storage'],
|
||||
['key' => 'bandwidth'],
|
||||
)
|
||||
->create([
|
||||
'plan_id' => $plan->id,
|
||||
]);
|
||||
|
||||
$subscription = Subscription::factory()
|
||||
->create([
|
||||
'status' => 'active',
|
||||
'type' => 'pre-paid',
|
||||
'plan_id' => $plan->id,
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
File::factory()
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'filesize' => 125000000,
|
||||
]);
|
||||
|
||||
Traffic::factory()
|
||||
->create([
|
||||
'user_id' => $user->id,
|
||||
'download' => 155000000,
|
||||
'created_at' => now()->subDay(),
|
||||
]);
|
||||
|
||||
resolve(ReportUsageAction::class)();
|
||||
|
||||
$this
|
||||
->assertDatabaseHas('usages', [
|
||||
'metered_feature_id' => $plan->meteredFeatures()->get()[0]->id,
|
||||
'subscription_id' => $subscription->id,
|
||||
'quantity' => 0.125,
|
||||
])
|
||||
->assertDatabaseHas('usages', [
|
||||
'metered_feature_id' => $plan->meteredFeatures()->get()[1]->id,
|
||||
'subscription_id' => $subscription->id,
|
||||
'quantity' => 0.155,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user