mirror of
https://github.com/axeloz/filesharing.git
synced 2025-05-06 10:03:55 +02:00
Fixes files deletion and listing of existing bundles
This commit is contained in:
parent
879242cad8
commit
50af3bbe1c
4 changed files with 92 additions and 98 deletions
|
@ -24,7 +24,8 @@ class Upload {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setMetadata(string $bundleId, array $metadata = []) {
|
public static function setMetadata(String $bundleId, Array $metadata = []) {
|
||||||
|
|
||||||
$origin = self::getMetadata($bundleId);
|
$origin = self::getMetadata($bundleId);
|
||||||
$updated = array_merge($origin, $metadata);
|
$updated = array_merge($origin, $metadata);
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ class Upload {
|
||||||
return $updated;
|
return $updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function addFileMetaData(string $bundleId, array $file) {
|
public static function addFileMetaData(String $bundleId, Array $file) {
|
||||||
$metadata = self::getMetadata($bundleId);
|
$metadata = self::getMetadata($bundleId);
|
||||||
|
|
||||||
if (empty($metadata)) {
|
if (empty($metadata)) {
|
||||||
|
@ -45,15 +46,12 @@ class Upload {
|
||||||
}
|
}
|
||||||
|
|
||||||
array_push($metadata['files'], $file);
|
array_push($metadata['files'], $file);
|
||||||
|
self::setMetadata($bundleId, $metadata);
|
||||||
if (! Storage::disk('uploads')->put($bundleId.'/bundle.json', json_encode($metadata))) {
|
|
||||||
throw new Exception('Cannot store metadata');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $metadata;
|
return $metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function deleteFile(string $bundleId, string $uuid) {
|
public static function deleteFile(String $bundleId, String $uuid) {
|
||||||
$metadata = self::getMetadata($bundleId);
|
$metadata = self::getMetadata($bundleId);
|
||||||
|
|
||||||
if (! empty($metadata['files'])) {
|
if (! empty($metadata['files'])) {
|
||||||
|
@ -65,10 +63,8 @@ class Upload {
|
||||||
unset($metadata['files'][$key]);
|
unset($metadata['files'][$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (! Storage::disk('uploads')->put($bundleId.'/bundle.json', json_encode($metadata))) {
|
self::setMetadata($bundleId, $metadata);
|
||||||
throw new Exception('Cannot store metadata');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $metadata;
|
return $metadata;
|
||||||
|
@ -112,7 +108,6 @@ class Upload {
|
||||||
return $min;
|
return $min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static function canUpload($current_ip) {
|
public static function canUpload($current_ip) {
|
||||||
|
|
||||||
// Getting the IP limit configuration
|
// Getting the IP limit configuration
|
||||||
|
|
|
@ -29,8 +29,6 @@ class UploadController extends Controller
|
||||||
// The upload form
|
// The upload form
|
||||||
public function storeBundle(Request $request, String $bundleId) {
|
public function storeBundle(Request $request, String $bundleId) {
|
||||||
|
|
||||||
$original = Upload::getMetadata($bundleId);
|
|
||||||
|
|
||||||
$metadata = [
|
$metadata = [
|
||||||
'expiry' => $request->expiry ?? null,
|
'expiry' => $request->expiry ?? null,
|
||||||
'password' => $request->password ?? null,
|
'password' => $request->password ?? null,
|
||||||
|
@ -49,15 +47,10 @@ class UploadController extends Controller
|
||||||
|
|
||||||
public function uploadFile(Request $request, String $bundleId) {
|
public function uploadFile(Request $request, String $bundleId) {
|
||||||
|
|
||||||
// Getting metadata
|
// Validating form data
|
||||||
$metadata = Upload::getMetadata($bundleId);
|
$request->validate([
|
||||||
|
'uuid' => 'required|uuid',
|
||||||
// Validating file
|
'file' => 'required|file|max:'.(Upload::fileMaxSize() / 1000)
|
||||||
abort_if(! $request->hasFile('file'), 422);
|
|
||||||
abort_if(! $request->file('file')->isValid(), 422);
|
|
||||||
|
|
||||||
$this->validate($request, [
|
|
||||||
'file' => 'required|file|max:'.(Upload::fileMaxSize() / 1000)
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Generating the file name
|
// Generating the file name
|
||||||
|
@ -72,7 +65,7 @@ class UploadController extends Controller
|
||||||
|
|
||||||
// Generating file metadata
|
// Generating file metadata
|
||||||
$file = [
|
$file = [
|
||||||
'uuid' => Str::uuid(),
|
'uuid' => $request->uuid,
|
||||||
'original' => $original,
|
'original' => $original,
|
||||||
'filesize' => Storage::disk('uploads')->size($fullpath),
|
'filesize' => Storage::disk('uploads')->size($fullpath),
|
||||||
'fullpath' => $fullpath,
|
'fullpath' => $fullpath,
|
||||||
|
@ -84,7 +77,8 @@ class UploadController extends Controller
|
||||||
$metadata = Upload::addFileMetaData($bundleId, $file);
|
$metadata = Upload::addFileMetaData($bundleId, $file);
|
||||||
|
|
||||||
return response()->json([
|
return response()->json([
|
||||||
'result' => true
|
'result' => true,
|
||||||
|
'file' => $file
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
|
@ -99,12 +93,12 @@ class UploadController extends Controller
|
||||||
|
|
||||||
public function deleteFile(Request $request, String $bundleId) {
|
public function deleteFile(Request $request, String $bundleId) {
|
||||||
|
|
||||||
$metadata = Upload::getMetadata($bundleId);
|
$request->validate([
|
||||||
|
'uuid' => 'required|uuid'
|
||||||
abort_if(empty($request->file), 422);
|
]);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$metadata = Upload::deleteFile($bundleId, $request->file);
|
$metadata = Upload::deleteFile($bundleId, $request->uuid);
|
||||||
return response()->json($metadata);
|
return response()->json($metadata);
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
document.addEventListener('alpine:init', () => {
|
document.addEventListener('alpine:init', () => {
|
||||||
Alpine.data('bundle', () => ({
|
Alpine.data('bundle', () => ({
|
||||||
bundles: null,
|
bundles: null,
|
||||||
|
active: null,
|
||||||
|
expired: null,
|
||||||
currentBundle: null,
|
currentBundle: null,
|
||||||
|
|
||||||
init: function() {
|
init: function() {
|
||||||
|
@ -15,25 +17,21 @@
|
||||||
this.bundles = JSON.parse(bundles)
|
this.bundles = JSON.parse(bundles)
|
||||||
|
|
||||||
if (this.bundles != null && Object.keys(this.bundles).length > 0) {
|
if (this.bundles != null && Object.keys(this.bundles).length > 0) {
|
||||||
this.bundles.active = []
|
this.active = []
|
||||||
this.bundles.expired = []
|
this.expired = []
|
||||||
|
|
||||||
this.bundles.forEach( (bundle) => {
|
this.bundles.forEach( (bundle) => {
|
||||||
if (bundle.title == null || bundle.title == '') {
|
if (bundle.title == null || bundle.title == '') {
|
||||||
bundle.title = 'untitled'
|
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())) {
|
if (bundle.expires_at != null && moment.unix(bundle.expires_at).isBefore(moment())) {
|
||||||
this.bundles.expired.push(bundle)
|
this.expired.push(bundle)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.bundles.active.push(bundle)
|
this.active.push(bundle)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log(this.bundles)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If bundle is empty, initializing it
|
// If bundle is empty, initializing it
|
||||||
|
@ -126,17 +124,17 @@
|
||||||
>
|
>
|
||||||
<option>-</option>
|
<option>-</option>
|
||||||
|
|
||||||
<template x-if="Object.keys(bundles.active).length > 0">
|
<template x-if="Object.keys(active).length > 0">
|
||||||
<optgroup label="{{ __('app.active') }}">
|
<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>
|
<option :value="bundle.bundle_id" x-text="bundle.title"></option>
|
||||||
</template>
|
</template>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template x-if="Object.keys(bundles.expired).length > 0">
|
<template x-if="Object.keys(expired).length > 0">
|
||||||
<optgroup label="{{ __('app.expired') }}">
|
<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>
|
<option :value="bundle.bundle_id" x-text="bundle.title"></option>
|
||||||
</template>
|
</template>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@extends('layout')
|
@extends('layout')
|
||||||
|
|
||||||
@section('page_title', __('app.upload'))
|
@section('page_title', __('app.upload-files-title'))
|
||||||
|
|
||||||
@push('scripts')
|
@push('scripts')
|
||||||
<script>
|
<script>
|
||||||
|
@ -201,10 +201,13 @@
|
||||||
dictResponseError: '@lang('app.server-answered')',
|
dictResponseError: '@lang('app.server-answered')',
|
||||||
})
|
})
|
||||||
|
|
||||||
this.dropzone.on("addedfile", (file) => {
|
this.dropzone.on('addedfile', (file) => {
|
||||||
console.log('added file')
|
console.log('added file')
|
||||||
|
|
||||||
|
file.uuid = this.uuid()
|
||||||
|
|
||||||
this.metadata.files.push({
|
this.metadata.files.push({
|
||||||
uuid: file.upload.uuid,
|
uuid: file.uuid,
|
||||||
original: file.name,
|
original: file.name,
|
||||||
filesize: file.size,
|
filesize: file.size,
|
||||||
fullpath: '',
|
fullpath: '',
|
||||||
|
@ -212,24 +215,28 @@
|
||||||
created_at: moment().unix(),
|
created_at: moment().unix(),
|
||||||
status: 'uploading'
|
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
|
let fileIndex = null
|
||||||
|
|
||||||
if (fileIndex = this.findFileIndex(file.upload.uuid)) {
|
if (fileIndex = this.findFileIndex(file.upload.uuid)) {
|
||||||
this.metadata.files[fileIndex].progress = Math.round(progress)
|
this.metadata.files[fileIndex].progress = Math.round(progress)
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
|
|
||||||
this.dropzone.on('error', (file, message) => {
|
this.dropzone.on('error', (file, message) => {
|
||||||
let fileIndex = this.findFileIndex(file.upload.uuid)
|
let fileIndex = this.findFileIndex(file.upload.uuid)
|
||||||
this.metadata.files[fileIndex].status = false
|
this.metadata.files[fileIndex].status = false
|
||||||
this.metadata.files[fileIndex].message = message
|
this.metadata.files[fileIndex].message = message
|
||||||
}),
|
})
|
||||||
|
|
||||||
this.dropzone.on("complete", (file) => {
|
this.dropzone.on('complete', (file) => {
|
||||||
let fileIndex = this.findFileIndex(file.upload.uuid)
|
let fileIndex = this.findFileIndex(file.uuid)
|
||||||
this.metadata.files[fileIndex].progress = 0
|
this.metadata.files[fileIndex].progress = 0
|
||||||
|
|
||||||
if (file.status == 'success') {
|
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) {
|
deleteFile: function(file) {
|
||||||
// File status is valid so it must be deleted from server
|
// File status is valid so it must be deleted from server
|
||||||
if (file.status == true) {
|
if (file.status == true) {
|
||||||
|
@ -267,7 +257,7 @@
|
||||||
url: '/upload/'+this.metadata.bundle_id+'/file',
|
url: '/upload/'+this.metadata.bundle_id+'/file',
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
data: {
|
data: {
|
||||||
file: lfile.uuid,
|
uuid: lfile.uuid,
|
||||||
auth: this.bundles[this.bundle].owner_token
|
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) {
|
syncData: function(metadata) {
|
||||||
if (Object.keys(metadata).length > 0) {
|
if (Object.keys(metadata).length > 0) {
|
||||||
this.metadata = metadata
|
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) {
|
showModal: function(text, callback) {
|
||||||
this.modal.text = text
|
this.modal.text = text
|
||||||
this.modal.callback = callback
|
this.modal.callback = callback
|
||||||
|
@ -339,11 +370,14 @@
|
||||||
|
|
||||||
countFilesOnServer: function() {
|
countFilesOnServer: function() {
|
||||||
count = 0
|
count = 0
|
||||||
this.metadata.files.forEach( (file) => {
|
|
||||||
if (file.status == true) {
|
if (this.metadata.hasOwnProperty('files') && Object.keys(this.metadata.files).length > 0) {
|
||||||
count ++
|
for (i in this.metadata.files) {
|
||||||
|
if (this.metadata.files[i].status == true) {
|
||||||
|
count ++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return count
|
return count
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -353,23 +387,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
return moment.unix(this.metadata.expires_at).isBefore(moment())
|
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>
|
||||||
</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 --}}
|
{{-- Buttons --}}
|
||||||
<div class="grid grid-cols-2 gap-10 mt-10 text-center">
|
<div class="grid grid-cols-2 gap-10 mt-10 text-center">
|
||||||
<div>
|
<div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue