Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
AURA
dashboard
Commits
772b16bd
Commit
772b16bd
authored
May 23, 2020
by
jackie / Andrea Ida Malkah Klaura
Browse files
move all file related actions to store
parent
2ac89e89
Changes
2
Hide whitespace changes
Inline
Side-by-side
src/components/filemanager/Files.vue
View file @
772b16bd
...
...
@@ -278,7 +278,6 @@
<
script
>
import
{
mapGetters
}
from
'
vuex
'
import
axios
from
'
axios
'
import
filesize
from
'
filesize
'
import
prettyDate
from
'
../../mixins/prettyDate
'
import
importLog
from
'
./ImportLog.vue
'
...
...
@@ -375,213 +374,69 @@ export default {
}
},
// Deletes a file with a specific ID calling the AuRa tank API and afterwards
// fetching a fresh list of files from it.
deleteFile
:
function
(
id
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
this
.
selectedShow
.
slug
+
'
/files/
'
+
id
// TODO: add mechanism to indicate the running delete request in the files table
axios
.
delete
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
},
}).
then
(()
=>
{
this
.
$log
.
debug
(
`Fetching files for show
${
this
.
selectedShow
.
slug
}
(ID:
${
id
}
)`
)
this
.
fetchFiles
(
this
.
selectedShow
.
slug
)
}).
catch
(
error
=>
{
// if there was a 409 Conflict response it means, that this file is
// still used in one or more playlists.
if
(
error
.
response
.
status
===
409
)
{
let
pls
=
error
.
response
.
data
.
detail
.
playlists
.
length
let
msg
=
'
Cannot delete file. Still used in
'
+
pls
+
'
playlists:
\n\n
'
for
(
let
pl
of
error
.
response
.
data
.
detail
.
playlists
)
{
msg
+=
'
ID:
'
+
pl
.
id
if
(
pl
.
description
)
{
msg
+=
'
(
'
+
pl
.
description
+
'
)
'
}
msg
+=
'
\n
'
}
msg
+=
'
\n
If you want to delete the file, remove it from those playlists first.
'
alert
(
msg
)
}
else
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
alert
(
'
Error: could not delete file. See console for details.
'
)
}
this
.
$store
.
dispatch
(
'
files/deleteFile
'
,
{
show
:
this
.
selectedShow
.
slug
,
file
:
id
,
})
},
// With this function we add a new file in the AuRa tank by calling its API.
// Depending on wheter we add a remote file which tank then imports by itself,
// or if we want to upload a local file, we source-uri has to look different.
// And for uploading a local file this is just the first step. Afterwards the
// actual upload has to be started with the startUpload function.
addFile
:
function
()
{
var
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
this
.
selectedShow
.
slug
+
'
/files
'
if
(
this
.
addNewFileURI
)
{
// TODO: add mechanism to indicate the running post request in the files table
axios
.
post
(
uri
,
{
'
source-uri
'
:
this
.
uploadSourceURI
},
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
}
}).
then
(()
=>
{
this
.
fetchFiles
(
this
.
selectedShow
.
slug
)
if
(
this
.
uploadInterval
===
null
)
{
this
.
uploadInterval
=
setInterval
(()
=>
{
this
.
fetchImports
(
this
.
selectedShow
.
slug
)
},
250
)
}
}).
catch
(
error
=>
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
alert
(
'
Error: could not add the new remote import. See console for details.
'
)
})
}
else
if
(
this
.
uploadSourceFile
)
{
// TODO: add mechanism to indicate the running post request in the files table
axios
.
post
(
uri
,
{
'
source-uri
'
:
encodeURI
(
encodeURI
(
'
upload://
'
+
this
.
uploadSourceFile
.
name
))
},
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
}
}).
then
(
response
=>
{
this
.
startUpload
(
response
.
data
.
id
)
addFile
()
{
this
.
$store
.
dispatch
(
'
files/addFile
'
,
{
show
:
this
.
selectedShow
.
slug
,
addNewFileURI
:
this
.
addNewFileURI
,
uploadSourceURI
:
this
.
uploadSourceURI
,
uploadSourceFile
:
this
.
uploadSourceFile
,
callback
:
()
=>
{
this
.
fetchFiles
(
this
.
selectedShow
.
slug
)
if
(
this
.
uploadInterval
===
null
)
{
this
.
uploadInterval
=
setInterval
(()
=>
{
this
.
fetchImports
(
this
.
selectedShow
.
slug
)
},
250
)
this
.
uploadInterval
=
setInterval
(()
=>
{
this
.
fetchImports
()
},
250
)
}
}).
catch
(
error
=>
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
alert
(
'
Error: could not add the new file upload. See console for details.
'
)
})
}
else
{
alert
(
'
Something is wrong. You have choosen to upload a file, but the corresponding file object does not exist.
'
)
}
},
// When a new file was added with the addFile function we can start an upload
// fetching the import endpoint of this file and then call the upload
// function, which atually puts the file onto the server.
startUpload
:
function
(
id
)
{
var
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
this
.
selectedShow
.
slug
+
'
/files/
'
+
id
+
'
/import
'
axios
.
get
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
},
params
:
{
'
wait-for
'
:
'
running
'
}
}).
then
(
this
.
upload
(
id
)
).
catch
(
error
=>
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
alert
(
'
Error: could not start the file upload. See console for details.
'
)
},
})
},
// Upload a file to the AuRa tank API - given it was created with the addFile
// and started with the startUpload methods.
upload
:
function
(
id
)
{
/*
* NOTE: there is no npm package for flow.js and importing it manually did not
* work so far. therefore this is commented out and we are using the simple
* upload method, until there is a nice npm package for flow.js or somone
* resolves this issue otherwise
var flow = new Flow({
target: process.env.VUE_APP_API_TANK + 'shows/' + this.selectedShow.slug + '/files/' + id + '/upload',
chunkSize: 100 * 1024,
prioritizeFirstAndLastChunk: true
})
flow.on('fileSuccess', function(file, message) {
this.$log.error(file, message)
})
flow.on('fileError', function(file, message) {
this.$log.error(file, message)
alert('Error: could not upload your file. See console for details.')
})
flow.addFile(this.uploadSourceFile)
flow.upload()
*/
var
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
this
.
selectedShow
.
slug
+
'
/files/
'
+
id
+
'
/upload
'
axios
.
put
(
uri
,
this
.
uploadSourceFile
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
,
'
Content-Type
'
:
'
application/octet-stream
'
}
}).
then
(()
=>
{
this
.
$log
.
info
(
'
Sucessfully uploaded file.
'
)
// now we start polling for the import progress
// the fetchImports function has to make sure to deactivate the interval
// again, when all running imports are done (in this first raw version;
// ideally we should refine this so that every single file gets updated independently)
//this.uploadInterval = setInterval(() => { this.fetchImports(this.selectedShow.slug) }, 100)
}).
catch
(
error
=>
{
if
(
error
.
response
.
status
===
500
&&
error
.
response
.
data
.
error
===
'
ffmpeg returned 1
'
)
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
// if we use a file format that is not supported by ffmpeg, we should find
// the second to last line should notify us about invalid data
let
ffmpegError
=
error
.
response
.
data
.
detail
[
error
.
response
.
data
.
detail
.
length
-
2
]
if
(
ffmpegError
.
line
===
'
pipe:: Invalid data found when processing input
'
)
{
// in this case we can make the error message in the files table more specific
alert
(
'
Error: import aborted. The audio data format of your file is not valid!
'
)
}
else
{
alert
(
'
Error: ffmpeg could not processs your file! See console for details.
'
)
fetchImports
()
{
this
.
$store
.
dispatch
(
'
files/fetchImports
'
,
{
show
:
this
.
selectedShow
.
slug
,
callback
:
(
response
)
=>
{
// if all imports are done, we will receive an empty result set and stop
// polling the server again. then we can also refetch all file statuses.
if
(
response
.
data
.
results
.
length
===
0
)
{
clearInterval
(
this
.
uploadInterval
)
this
.
uploadInterval
=
null
this
.
fetchFiles
()
}
}
else
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
alert
(
'
Error: could not finish the file upload/import. See console for details.
'
)
}
})
},
// This function fetches all running imports for a given show. It should
// be called periodically to reflect the upload/import progress. When no
// more active imports are available the corresponding updateInterval
// should be cleared again.
fetchImports
:
function
(
slug
){
var
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
slug
+
'
/imports
'
axios
.
get
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
this
.
$store
.
state
.
auth
.
user
.
access_token
}
}).
then
(
response
=>
{
// if all imports are done, we will receive an empty result set and stop
// polling the server again. then we can also refetch all file statuses.
if
(
response
.
data
.
results
.
length
===
0
)
{
clearInterval
(
this
.
uploadInterval
)
this
.
uploadInterval
=
null
this
.
fetchShow
(
slug
)
}
// if there are still imports going on, we just updated the respective
// progress information for the import we just fetched and rerender
// the filesTable
else
{
for
(
var
i
in
response
.
data
.
results
)
{
var
f
=
this
.
getFileById
(
response
.
data
.
results
[
i
].
id
)
if
(
f
)
{
f
.
source
.
import
.
progress
=
{
// if there are still imports going on, we just update the respective
// progress information for the import we just fetched and rerender
// the filesTable
else
{
for
(
let
i
in
response
.
data
.
results
)
{
this
.
$store
.
commit
(
'
files/updateProgress
'
,
{
id
:
response
.
data
.
results
[
i
].
id
,
progress
:
response
.
data
.
results
[
i
].
progress
.
progress
,
step
:
response
.
data
.
results
[
i
].
progress
.
step
}
}
)
let
p
=
'
[import]
'
p
+=
'
id:
'
+
response
.
data
.
results
[
i
].
id
p
+=
'
, progress:
'
+
response
.
data
.
results
[
i
].
progress
.
progress
p
+=
'
, step:
'
+
response
.
data
.
results
[
i
].
progress
.
step
this
.
$log
.
debug
(
p
)
this
.
$refs
.
filesTable
.
refresh
()
}
this
.
$refs
.
filesTable
.
refresh
()
}
},
callbackCancel
:
()
=>
{
// also in case of an error we have to cancel the uploadInterval,
// otherwise we'll continuosly get alerts if the error is persistent
clearInterval
(
this
.
uploadInterval
)
this
.
uploadInterval
=
null
}
}).
catch
(
error
=>
{
// also in case of an error we have to cancel the uploadInterval,
// otherwise we'll continuosly get alerts if the error is persistent
clearInterval
(
this
.
uploadInterval
)
if
(
error
.
response
)
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
}
else
{
this
.
$log
.
error
(
error
)
}
alert
(
'
Error: could not fetch current imports. See console for details.
'
)
})
},
// Fetch all files for a given show from the AuRa tank API
fetchFiles
:
function
(
slug
)
{
this
.
$store
.
dispatch
(
'
files/fetchFiles
'
,
{
slug
:
slug
})
fetchFiles
()
{
this
.
$store
.
dispatch
(
'
files/fetchFiles
'
,
{
slug
:
this
.
selectedShow
.
slug
})
},
},
...
...
src/store/modules/files.js
View file @
772b16bd
...
...
@@ -36,8 +36,24 @@ const mutations = {
let
file
=
state
.
files
.
find
(
f
=>
f
.
id
===
data
.
id
)
file
.
metadata
=
data
.
metadata
},
deleteFile
(
state
,
id
)
{
let
i
=
state
.
files
.
findIndex
(
f
=>
f
.
id
===
id
)
if
(
i
>=
0
)
{
state
.
files
.
splice
(
i
,
1
)
}
},
setLog
(
state
,
log
)
{
state
.
log
=
log
},
updateProgress
(
state
,
data
)
{
let
file
=
state
.
files
.
find
(
f
=>
f
.
id
==
data
.
id
)
if
(
file
)
{
file
.
source
.
import
.
progress
=
{
progress
:
data
.
progress
,
step
:
data
.
step
}
}
},
}
const
actions
=
{
...
...
@@ -78,6 +94,23 @@ const actions = {
})
},
// This function fetches all running imports for a given show. It should
// be called periodically to reflect the upload/import progress. When no
// more active imports are available the corresponding updateInterval
// should be cleared again.
fetchImports
(
ctx
,
data
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/imports
'
axios
.
get
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
ctx
.
rootState
.
auth
.
user
.
access_token
}
}).
then
(
response
=>
{
if
(
data
&&
typeof
(
data
.
callback
)
===
'
function
'
)
{
data
.
callback
(
response
)
}
}).
catch
(
error
=>
{
handleApiError
(
this
,
error
,
'
could not fetch current imports
'
)
if
(
data
&&
typeof
(
data
.
callbackCancel
)
===
'
function
'
)
{
data
.
callbackCancel
()
}
})
},
updateFile
(
ctx
,
data
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/files/
'
+
data
.
file
// TODO: add mechanism to indicate the running patch request in the files table
...
...
@@ -91,6 +124,137 @@ const actions = {
handleApiError
(
this
,
error
,
'
could not update file
'
)
if
(
data
&&
typeof
(
data
.
callbackCancel
)
===
'
function
'
)
{
data
.
callbackCancel
()
}
})
},
// With this function we add a new file in the AuRa tank by calling its API.
// Depending on wheter we add a remote file which tank then imports by itself,
// or if we want to upload a local file, the source-uri has to look different.
// And for uploading a local file this is just the first step. Afterwards the
// actual upload has to be started with the startUpload function.
addFile
(
ctx
,
data
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/files
'
let
payload
=
{}
if
(
data
.
addNewFileURI
)
{
payload
[
'
source-uri
'
]
=
data
.
uploadSourceURI
}
else
{
payload
[
'
source-uri
'
]
=
encodeURI
(
encodeURI
(
'
upload://
'
+
data
.
uploadSourceFile
.
name
))
}
axios
.
post
(
uri
,
payload
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
ctx
.
rootState
.
auth
.
user
.
access_token
}
}).
then
(
response
=>
{
if
(
!
data
.
addNewFileURI
)
{
ctx
.
dispatch
(
'
startUpload
'
,
{
show
:
data
.
show
,
file
:
response
.
data
.
id
})
}
if
(
data
&&
typeof
(
data
.
callback
)
===
'
function
'
)
{
data
.
callback
()
}
}).
catch
(
error
=>
{
let
msg
=
'
could not add the new remote import
'
if
(
!
data
.
addNewFileURI
)
{
msg
=
'
could not add the new file upload
'
}
handleApiError
(
this
,
error
,
msg
)
if
(
data
&&
typeof
(
data
.
callbackCancel
)
===
'
function
'
)
{
data
.
callbackCancel
()
}
})
},
// When a new file was added with the addFile dispatch we can start an upload
// fetching the import endpoint of this file and then call the upload
// function, which atually puts the file onto the server.
startUpload
(
ctx
,
data
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/files/
'
+
data
.
file
+
'
/import
'
axios
.
get
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
ctx
.
rootState
.
auth
.
user
.
access_token
},
params
:
{
'
wait-for
'
:
'
running
'
}
}).
then
(
ctx
.
dispatch
(
'
upload
'
,
data
)
).
catch
(
error
=>
{
handleApiError
(
this
,
error
,
'
could not start the file upload
'
)
})
},
// Upload a file to the AuRa tank API - given it was created with the addFile
// and started with the startUpload dispatch.
upload
(
ctx
,
data
)
{
/*
* NOTE: there is no npm package for flow.js and importing it manually did not
* work so far. therefore this is commented out and we are using the simple
* upload method, until there is a nice npm package for flow.js or somone
* resolves this issue otherwise
let flow = new Flow({
target: process.env.VUE_APP_API_TANK + 'shows/' + data.show + '/files/' + data.file + '/upload',
chunkSize: 100 * 1024,
prioritizeFirstAndLastChunk: true
})
flow.on('fileSuccess', function(file, message) {
this.$log.error(file, message)
})
flow.on('fileError', function(file, message) {
this.$log.error(file, message)
alert('Error: could not upload your file. See console for details.')
})
flow.addFile(this.uploadSourceFile)
flow.upload()
*/
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/files/
'
+
data
.
file
+
'
/upload
'
axios
.
put
(
uri
,
data
.
uploadSourceFile
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
ctx
.
rootState
.
auth
.
user
.
access_token
,
'
Content-Type
'
:
'
application/octet-stream
'
}
}).
then
(()
=>
{
this
.
$log
.
info
(
'
Sucessfully uploaded file:
'
+
data
.
uploadSourceFile
.
name
)
}).
catch
(
error
=>
{
if
(
error
.
response
.
status
===
500
&&
error
.
response
.
data
.
error
===
'
ffmpeg returned 1
'
)
{
this
.
$log
.
error
(
error
.
response
.
status
+
'
'
+
error
.
response
.
statusText
)
this
.
$log
.
error
(
error
.
response
)
// if we use a file format that is not supported by ffmpeg, we should find
// the second to last line should notify us about invalid data
let
ffmpegError
=
error
.
response
.
data
.
detail
[
error
.
response
.
data
.
detail
.
length
-
2
]
if
(
ffmpegError
.
line
===
'
pipe:: Invalid data found when processing input
'
)
{
// in this case we can make the error message in the files table more specific
alert
(
'
Error: import aborted. The audio data format of your file is not valid!
'
)
}
else
{
alert
(
'
Error: ffmpeg could not process your file! See console for details.
'
)
}
}
else
{
handleApiError
(
this
,
error
,
'
could not finish the file upload/import
'
)
}
})
},
// Deletes a file with a specific ID calling the AuRa tank API
deleteFile
(
ctx
,
data
)
{
let
uri
=
process
.
env
.
VUE_APP_API_TANK
+
'
shows/
'
+
data
.
show
+
'
/files/
'
+
data
.
file
// TODO: add mechanism to indicate the running delete request in the files table
axios
.
delete
(
uri
,
{
withCredentials
:
true
,
headers
:
{
'
Authorization
'
:
'
Bearer
'
+
ctx
.
rootState
.
auth
.
user
.
access_token
},
}).
then
(()
=>
{
ctx
.
commit
(
'
deleteFile
'
,
data
.
file
)
if
(
data
&&
typeof
(
data
.
callback
)
===
'
function
'
)
{
data
.
callback
()
}
}).
catch
(
error
=>
{
// if there was a 409 Conflict response it means, that this file is
// still used in one or more playlists.
if
(
error
.
response
&&
error
.
response
.
status
===
409
)
{
let
pls
=
error
.
response
.
data
.
detail
.
playlists
.
length
let
msg
=
'
Cannot delete file. Still used in
'
+
pls
+
'
playlists:
\n\n
'
for
(
let
pl
of
error
.
response
.
data
.
detail
.
playlists
)
{
msg
+=
'
ID:
'
+
pl
.
id
if
(
pl
.
description
)
{
msg
+=
'
(
'
+
pl
.
description
+
'
)
'
}
msg
+=
'
\n
'
}
msg
+=
'
\n
If you want to delete the file, remove it from those playlists first.
'
alert
(
msg
)
}
else
{
handleApiError
(
this
,
error
,
'
could not delete file
'
)
if
(
data
&&
typeof
(
data
.
callbackCancel
)
===
'
function
'
)
{
data
.
callbackCancel
()
}
}
})
},
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment