record daily usage

This commit is contained in:
Čarodej
2021-12-10 16:37:00 +01:00
parent 26f367031e
commit 9275487cfa
8 changed files with 186 additions and 27 deletions

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

View File

@@ -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');
}
/**

View File

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

View File

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

View File

@@ -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());

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

View File

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

View File

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