diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index a5ee8c8..a3e9a64 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -9,7 +9,6 @@ class HomeController extends Controller { public function __invoke(Request $request) { - return Inertia::render('Temp'); return Inertia::render('Converter/Show'); } } diff --git a/app/Models/Conversion.php b/app/Models/Conversion.php index 1aed3bd..18b763d 100644 --- a/app/Models/Conversion.php +++ b/app/Models/Conversion.php @@ -177,4 +177,54 @@ public function getFormatOperations(): array return $operations; } + + public function statistic(): BelongsTo + { + return $this->belongsTo(Statistic::class); + } + + public function trackStatistic(): void + { + $conversionEnd = $this->status === ConversionStatus::FINISHED ? now() : null; + + $updateValues = [ + 'mime_type' => $this->file->mime_type ?? '', + 'extension' => $this->file->extension ?? '', + 'size' => $this->file->size ?? 0, + 'status' => $this->status, + 'keep_resolution' => $this->keep_resolution, + 'audio' => $this->audio, + 'auto_crop' => $this->auto_crop, + 'watermark' => $this->watermark, + 'interpolation' => $this->interpolation, + 'audio_quality' => $this->audio_quality, + 'trim_start' => $this->trim_start, + 'trim_end' => $this->trim_end, + 'max_size' => $this->max_size, + 'url' => $this->url, + 'conversion_started_at' => $this->created_at, + 'conversion_ended_at' => $conversionEnd, + ]; + + $stat = Statistic::where('conversion_id', $this->id)->first(); + + if ($stat) { + if ($stat->mime_type !== '' && $stat->mime_type !== $updateValues['mime_type']) { + $updateValues['mime_type'] = $stat->mime_type; + } + if ($stat->extension !== '' && $stat->extension !== $updateValues['extension']) { + $updateValues['extension'] = $stat->extension; + } + if ($stat->size !== 0 && $stat->size !== $updateValues['size']) { + $updateValues['size'] = $stat->size; + } + if ($stat->size === 0) { + $updateValues['size'] = $this->file->size ?? 0; + } + + $stat->update($updateValues); + } else { + Statistic::create(array_merge($updateValues, ['conversion_id' => $this->id])); + } + } } diff --git a/app/Models/Statistic.php b/app/Models/Statistic.php new file mode 100644 index 0000000..aa52397 --- /dev/null +++ b/app/Models/Statistic.php @@ -0,0 +1,30 @@ + 'boolean', + 'interpolation' => 'boolean', + 'auto_crop' => 'boolean', + 'max_size' => 'integer', + 'audio_quality' => 'float', + 'watermark' => 'boolean', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + ]; + + public function conversion(): BelongsTo + { + return $this->belongsTo(Conversion::class); + } +} diff --git a/app/Observers/ConversionObserver.php b/app/Observers/ConversionObserver.php index 3862740..1ce22b0 100644 --- a/app/Observers/ConversionObserver.php +++ b/app/Observers/ConversionObserver.php @@ -12,6 +12,8 @@ class ConversionObserver { public function updated(Conversion $conversion): void { + $conversion->trackStatistic(); + ConversionUpdated::dispatch($conversion->id); if ($conversion->status === ConversionStatus::FINISHED) { @@ -21,9 +23,16 @@ public function updated(Conversion $conversion): void public function created(Conversion $conversion): void { + $conversion->trackStatistic(); + if ($conversion->status === ConversionStatus::PENDING && $conversion->url !== null && $conversion->file_id === null) { //DownloadVideoJob::dispatchSync($conversion->id); DownloadVideoJob::dispatch($conversion->id)->onQueue('downloader'); } } + + public function deleting(Conversion $conversion): void + { + $conversion->trackStatistic(); + } } diff --git a/database/migrations/2024_12_15_140118_create_files_table.php b/database/migrations/2024_12_15_140118_create_files_table.php index 460bba8..3b3b62f 100644 --- a/database/migrations/2024_12_15_140118_create_files_table.php +++ b/database/migrations/2024_12_15_140118_create_files_table.php @@ -23,7 +23,7 @@ public function up(): void $table->foreign('session_id') ->references('id') ->on('sessions') - ->cascadeOnDelete() + ->cascadeOnUpdate() ->cascadeOnDelete(); }); } diff --git a/database/migrations/2024_12_15_143417_create_conversions_table.php b/database/migrations/2024_12_15_143417_create_conversions_table.php index f8c362a..aa35708 100644 --- a/database/migrations/2024_12_15_143417_create_conversions_table.php +++ b/database/migrations/2024_12_15_143417_create_conversions_table.php @@ -31,7 +31,7 @@ public function up(): void $table->foreign('session_id') ->references('id') ->on('sessions') - ->cascadeOnDelete() + ->cascadeOnUpdate() ->cascadeOnDelete(); }); } diff --git a/database/migrations/2024_12_24_220649_create_statistics_table.php b/database/migrations/2024_12_24_220649_create_statistics_table.php new file mode 100644 index 0000000..61cf2d6 --- /dev/null +++ b/database/migrations/2024_12_24_220649_create_statistics_table.php @@ -0,0 +1,43 @@ +comment('Each row represents a single conversion'); + + $table->uuid('id')->primary(); + $table->foreignUuid('conversion_id')->nullable()->constrained()->nullOnDelete()->cascadeOnUpdate(); + $table->string('mime_type'); + $table->string('extension'); + $table->string('status'); + $table->boolean('keep_resolution')->default(false); + $table->boolean('audio')->default(true); + $table->boolean('auto_crop')->default(false); + $table->boolean('watermark')->default(false); + $table->boolean('interpolation')->default(false); + $table->float('audio_quality'); + $table->unsignedInteger('trim_start')->nullable(); + $table->unsignedInteger('trim_end')->nullable(); + $table->unsignedInteger('max_size')->nullable(); + $table->text('url')->nullable(); + $table->bigInteger('size'); + $table->dateTime('conversion_started_at')->nullable(); + $table->dateTime('conversion_ended_at')->nullable(); + // create a new generated column for the time difference between conversion_started_at and conversion_ended_at + $table->integer('conversion_time')->virtualAs('TIMESTAMPDIFF(SECOND, conversion_started_at, conversion_ended_at)'); + // virtualAs Column for + $table->timestamps(); + }); + } + + public function down(): void + { + Schema::dropIfExists('statistics'); + } +}; diff --git a/resources/js/Pages/Converter/Show.vue b/resources/js/Pages/Converter/Show.vue index c185cce..2e299fb 100644 --- a/resources/js/Pages/Converter/Show.vue +++ b/resources/js/Pages/Converter/Show.vue @@ -54,7 +54,7 @@ const { isOverDropZone } = useDropZone(dropZoneRef, { const formSchema = toTypedSchema( z.object({ file: z.any().optional(), - url: z.string().url('Keine valide URL').optional().default(''), + url: z.string().url('Keine valide URL').nullish().optional().default(null), // keepResolution: z.boolean().default(false), audio: z.boolean().default(true), audioQuality: z @@ -74,6 +74,7 @@ const formSchema = toTypedSchema( const form = useForm({ validationSchema: formSchema, name: 'converterSettings', + validateOnMount: true, }); const inertiaForm = useInertiaForm({ @@ -90,6 +91,7 @@ const inertiaForm = useInertiaForm({ }); const onSubmit = form.handleSubmit(async (values) => { + console.log(values); if (inertiaForm.processing) { return; } diff --git a/routes/web.php b/routes/web.php index c7bea86..bd380c7 100644 --- a/routes/web.php +++ b/routes/web.php @@ -14,20 +14,17 @@ return redirect()->route('home'); })->name('login'); -Route::middleware('auth')->group(function () { - Route::get('/conversions', [ListConverterController::class, 'index']) - ->name('conversions.list'); +Route::get('/conversions', [ListConverterController::class, 'index']) + ->name('conversions.list'); - Route::middleware([VerifyCsrfToken::class]) - ->group(function () { - Route::post('/conversions', [ListConverterController::class, 'myConversions']) - ->name('conversions.my'); - Route::post('/converter/start', StartConverterController::class) - ->name('converter.start') - ->middleware(['throttle']); - }); - - Route::get('conversions/download/{conversion}', [ConversionController::class, 'download']) - ->name('conversions.download'); -}); +Route::middleware([VerifyCsrfToken::class]) + ->group(function () { + Route::post('/conversions', [ListConverterController::class, 'myConversions']) + ->name('conversions.my'); + Route::post('/converter/start', StartConverterController::class) + ->name('converter.start') + ->middleware(['throttle']); + }); +Route::get('conversions/download/{conversion}', [ConversionController::class, 'download']) + ->name('conversions.download');