Fixes files deletion and listing of existing bundles

This commit is contained in:
Axel 2023-05-17 11:29:30 +02:00
parent 879242cad8
commit 50af3bbe1c
Signed by: axel
GPG key ID: 73C0A5961B6BC740
4 changed files with 92 additions and 98 deletions

View file

@ -24,7 +24,8 @@ class Upload {
return [];
}
public static function setMetadata(string $bundleId, array $metadata = []) {
public static function setMetadata(String $bundleId, Array $metadata = []) {
$origin = self::getMetadata($bundleId);
$updated = array_merge($origin, $metadata);
@ -35,7 +36,7 @@ class Upload {
return $updated;
}
public static function addFileMetaData(string $bundleId, array $file) {
public static function addFileMetaData(String $bundleId, Array $file) {
$metadata = self::getMetadata($bundleId);
if (empty($metadata)) {
@ -45,15 +46,12 @@ class Upload {
}
array_push($metadata['files'], $file);
if (! Storage::disk('uploads')->put($bundleId.'/bundle.json', json_encode($metadata))) {
throw new Exception('Cannot store metadata');
}
self::setMetadata($bundleId, $metadata);
return $metadata;
}
public static function deleteFile(string $bundleId, string $uuid) {
public static function deleteFile(String $bundleId, String $uuid) {
$metadata = self::getMetadata($bundleId);
if (! empty($metadata['files'])) {
@ -65,10 +63,8 @@ class Upload {
unset($metadata['files'][$key]);
}
}
}
if (! Storage::disk('uploads')->put($bundleId.'/bundle.json', json_encode($metadata))) {
throw new Exception('Cannot store metadata');
self::setMetadata($bundleId, $metadata);
}
return $metadata;
@ -112,7 +108,6 @@ class Upload {
return $min;
}
public static function canUpload($current_ip) {
// Getting the IP limit configuration

View file

@ -29,8 +29,6 @@ class UploadController extends Controller
// The upload form
public function storeBundle(Request $request, String $bundleId) {
$original = Upload::getMetadata($bundleId);
$metadata = [
'expiry' => $request->expiry ?? null,
'password' => $request->password ?? null,
@ -49,15 +47,10 @@ class UploadController extends Controller
public function uploadFile(Request $request, String $bundleId) {
// Getting metadata
$metadata = Upload::getMetadata($bundleId);
// Validating file
abort_if(! $request->hasFile('file'), 422);
abort_if(! $request->file('file')->isValid(), 422);
$this->validate($request, [
'file' => 'required|file|max:'.(Upload::fileMaxSize() / 1000)
// Validating form data
$request->validate([
'uuid' => 'required|uuid',
'file' => 'required|file|max:'.(Upload::fileMaxSize() / 1000)
]);
// Generating the file name
@ -72,7 +65,7 @@ class UploadController extends Controller
// Generating file metadata
$file = [
'uuid' => Str::uuid(),
'uuid' => $request->uuid,
'original' => $original,
'filesize' => Storage::disk('uploads')->size($fullpath),
'fullpath' => $fullpath,
@ -84,7 +77,8 @@ class UploadController extends Controller
$metadata = Upload::addFileMetaData($bundleId, $file);
return response()->json([
'result' => true
'result' => true,
'file' => $file
]);
}
catch (Exception $e) {
@ -99,12 +93,12 @@ class UploadController extends Controller
public function deleteFile(Request $request, String $bundleId) {
$metadata = Upload::getMetadata($bundleId);
abort_if(empty($request->file), 422);
$request->validate([
'uuid' => 'required|uuid'
]);
try {
$metadata = Upload::deleteFile($bundleId, $request->file);
$metadata = Upload::deleteFile($bundleId, $request->uuid);
return response()->json($metadata);
}
catch (Exception $e) {

View file

@ -6,6 +6,8 @@
document.addEventListener('alpine:init', () => {
Alpine.data('bundle', () => ({
bundles: null,
active: null,
expired: null,
currentBundle: null,
init: function() {
@ -15,25 +17,21 @@
this.bundles = JSON.parse(bundles)
if (this.bundles != null && Object.keys(this.bundles).length > 0) {
this.bundles.active = []
this.bundles.expired = []
this.active = []
this.expired = []
this.bundles.forEach( (bundle) => {
if (bundle.title == null || bundle.title == '') {
bundle.title = 'untitled'
}
//bundle.title += ' - '+Object.keys(bundle.files).length+' {{ __('app.files') }} - {{ __('app.created-at') }} '+moment.unix(bundle.created_at).fromNow()
if (bundle.expires_at != null && moment.unix(bundle.expires_at).isBefore(moment())) {
this.bundles.expired.push(bundle)
this.expired.push(bundle)
}
else {
this.bundles.active.push(bundle)
this.active.push(bundle)
}
})
console.log(this.bundles)
}
// If bundle is empty, initializing it
@ -126,17 +124,17 @@
>
<option>-</option>
<template x-if="Object.keys(bundles.active).length > 0">
<template x-if="Object.keys(active).length > 0">
<optgroup label="{{ __('app.active') }}">
<template x-for="bundle in bundles.active">
<template x-for="bundle in active">
<option :value="bundle.bundle_id" x-text="bundle.title"></option>
</template>
</optgroup>
</template>
<template x-if="Object.keys(bundles.expired).length > 0">
<template x-if="Object.keys(expired).length > 0">
<optgroup label="{{ __('app.expired') }}">
<template x-for="bundle in bundles.expired">
<template x-for="bundle in expired">
<option :value="bundle.bundle_id" x-text="bundle.title"></option>
</template>
</optgroup>

View file

@ -1,6 +1,6 @@
@extends('layout')
@section('page_title', __('app.upload'))
@section('page_title', __('app.upload-files-title'))
@push('scripts')
<script>
@ -201,10 +201,13 @@
dictResponseError: '@lang('app.server-answered')',
})
this.dropzone.on("addedfile", (file) => {
this.dropzone.on('addedfile', (file) => {
console.log('added file')
file.uuid = this.uuid()
this.metadata.files.push({
uuid: file.upload.uuid,
uuid: file.uuid,
original: file.name,
filesize: file.size,
fullpath: '',
@ -212,24 +215,28 @@
created_at: moment().unix(),
status: 'uploading'
});
});
})
this.dropzone.on("uploadprogress", (file, progress, bytes) => {
this.dropzone.on('sending', (file, xhr, data) => {
data.append('uuid', file.uuid)
})
this.dropzone.on('uploadprogress', (file, progress, bytes) => {
let fileIndex = null
if (fileIndex = this.findFileIndex(file.upload.uuid)) {
this.metadata.files[fileIndex].progress = Math.round(progress)
}
}),
})
this.dropzone.on('error', (file, message) => {
let fileIndex = this.findFileIndex(file.upload.uuid)
this.metadata.files[fileIndex].status = false
this.metadata.files[fileIndex].message = message
}),
})
this.dropzone.on("complete", (file) => {
let fileIndex = this.findFileIndex(file.upload.uuid)
this.dropzone.on('complete', (file) => {
let fileIndex = this.findFileIndex(file.uuid)
this.metadata.files[fileIndex].progress = 0
if (file.status == 'success') {
@ -240,23 +247,6 @@
}
},
findFile: function(uuid) {
let index = this.findFileIndex(uuid)
if (index != null) {
return this.metadata.files[index]
}
return null
},
findFileIndex: function (uuid) {
for (i in this.metadata.files) {
if (this.metadata.files[i].uuid == uuid) {
return i
}
}
return null
},
deleteFile: function(file) {
// File status is valid so it must be deleted from server
if (file.status == true) {
@ -267,7 +257,7 @@
url: '/upload/'+this.metadata.bundle_id+'/file',
method: 'DELETE',
data: {
file: lfile.uuid,
uuid: lfile.uuid,
auth: this.bundles[this.bundle].owner_token
}
})
@ -290,6 +280,40 @@
}
},
deleteBundle: function() {
this.showModal('{{ __('app.confirm-delete-bundle') }}', () => {
axios({
url: '/upload/'+this.metadata.bundle_id+'/delete',
method: 'DELETE',
data: {
auth: this.bundles[this.bundle].owner_token
}
})
.then( (response) => {
if (! response.data.success) {
this.syncData(response.data)
}
})
})
},
findFile: function(uuid) {
let index = this.findFileIndex(uuid)
if (index != null) {
return this.metadata.files[index]
}
return null
},
findFileIndex: function (uuid) {
for (i in this.metadata.files) {
if (this.metadata.files[i].uuid == uuid) {
return i
}
}
return null
},
syncData: function(metadata) {
if (Object.keys(metadata).length > 0) {
this.metadata = metadata
@ -313,6 +337,13 @@
}
},
uuid: function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
showModal: function(text, callback) {
this.modal.text = text
this.modal.callback = callback
@ -339,11 +370,14 @@
countFilesOnServer: function() {
count = 0
this.metadata.files.forEach( (file) => {
if (file.status == true) {
count ++
if (this.metadata.hasOwnProperty('files') && Object.keys(this.metadata.files).length > 0) {
for (i in this.metadata.files) {
if (this.metadata.files[i].status == true) {
count ++
}
}
});
}
return count
},
@ -353,23 +387,6 @@
}
return moment.unix(this.metadata.expires_at).isBefore(moment())
},
deleteBundle: function() {
this.showModal('{{ __('app.confirm-delete-bundle') }}', () => {
axios({
url: '/upload/'+this.metadata.bundle_id+'/delete',
method: 'DELETE',
data: {
auth: this.bundles[this.bundle].owner_token
}
})
.then( (response) => {
if (! response.data.success) {
this.syncData(response.data)
}
})
})
}
}))
})
@ -685,16 +702,6 @@
</div>
</div>
{{-- Delete link --}}
<div class="flex flex-wrap items-center mt-5">
<div class="w-1/3 text-right px-2">
@lang('app.delete-link')
</div>
<div class="w-2/3 shadow">
<input x-model="metadata.deletion_link" class="w-full bg-transparent text-slate-700 h-8 px-2 py-1 rounded-none border border-primary-superlight outline-none" type="text" readonly x-on:click="selectCopy($el)" />
</div>
</div>
{{-- Buttons --}}
<div class="grid grid-cols-2 gap-10 mt-10 text-center">
<div>