FileManager.vue 44.4 KB
Newer Older
1001
          alert('Error: could not save metadata info to file. See console for details.')
1002
1003
        })
      }
1004
    },
1005
1006
1007

    // Deletes a file with a specific, calling the AuRa tank API and afterwards
    // fetching a fresh list of files from it.
1008
1009
    deleteFile: function (id) {
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + this.shows[this.currentShow].slug + '/files/' + id
1010
      // TODO: add mechanism to indicate the running delete request in the files table
1011
1012
1013
1014
      axios.delete(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token },
      }).then(
1015
        this.fetchFiles(this.shows[this.currentShow].slug)
1016
      ).catch(error => {
1017
1018
1019
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not delete file. See console for details.')
1020
1021
      })
    },
1022
1023
1024
1025
1026
1027

    // 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.
1028
    addFile: function () {
1029
1030
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + this.shows[this.currentShow].slug + '/files'
      if (this.addNewFileURI) {
1031
1032
1033
1034
        // 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.$parent.user.access_token }
1035
        }).then(() => {
1036
          this.fetchFiles(this.shows[this.currentShow].slug)
1037
1038
1039
1040
          if (this.uploadInterval === null) {
            this.uploadInterval = setInterval(() => { this.fetchImports(this.shows[this.currentShow].slug) }, 250)
          }
        }).catch(error => {
1041
1042
1043
          console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
          console.log(error.response)
          alert('Error: could not add the new remote import. See console for details.')
1044
        })
1045
      } else if (this.uploadSourceFile) {
1046
        // TODO: add mechanism to indicate the running post request in the files table
1047
1048
1049
1050
1051
        axios.post(uri, { 'source-uri': encodeURI('upload://' + this.uploadSourceFile.name) }, {
          withCredentials: true,
          headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token }
        }).then(response => {
          this.startUpload(response.data.id)
1052
          this.fetchFiles(this.shows[this.currentShow].slug)
1053
1054
1055
          if (this.uploadInterval === null) {
            this.uploadInterval = setInterval(() => { this.fetchImports(this.shows[this.currentShow].slug) }, 250)
          }
1056
        }).catch(error => {
1057
1058
1059
          console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
          console.log(error.response)
          alert('Error: could not add the new file upload. See console for details.')
1060
1061
        })
      } else {
1062
        alert('Something is wrong. You have choosen to upload a file, but the corresponding file object does not exist.')
1063
1064
      }
    },
1065
1066
1067
1068

    // 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.
1069
1070
1071
1072
1073
1074
1075
1076
1077
    startUpload: function (id) {
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + this.shows[this.currentShow].slug + '/files/' + id + '/import'
      axios.get(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token },
        params: {'wait-for': 'running'}
      }).then(
        this.upload(id)
      ).catch(error => {
1078
1079
1080
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not start the file upload. See console for details.')
1081
1082
      })
    },
1083
1084
1085

    // Upload a file to the AuRa tank API - given it was created with the addFile
    // and started with the startUpload methods.
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
    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.shows[this.currentShow].slug + '/files/' + id + '/upload',
        chunkSize: 100 * 1024,
        prioritizeFirstAndLastChunk: true
      })
      flow.on('fileSuccess', function(file, message) {
        console.log(file, message)
      })
      flow.on('fileError', function(file, message) {
        console.log(file, message)
1102
        alert('Error: could not upload your file. See console for details.')
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
      })
      flow.addFile(this.uploadSourceFile)
      flow.upload()
      */
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + this.shows[this.currentShow].slug + '/files/' + id + '/upload'
      axios.put(uri, this.uploadSourceFile, {
        withCredentials: true,
        headers: {
          'Authorization': 'Bearer ' + this.$parent.user.access_token,
          'Content-Type': 'application/octet-stream'
        }
1114
1115
1116
1117
1118
1119
1120
      }).then(() => {
        console.log('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.shows[this.currentShow].slug) }, 100)
1121
      }).catch(error => {
1122
1123
1124
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not start the file upload. See console for details.')
1125
      })
1126
    },
1127
1128
1129

    // This switches the UI elements to reflect another show and fetches all
    // relevent data from the tank API.
1130
1131
1132
1133
    switchShow: function (index) {
      // set the current show and its ID to whatever we want to switch to now
      this.currentShow = index
      this.currentShowID = this.shows[this.currentShow].id
1134
      this.fetchShow(this.shows[this.currentShow].slug)
1135
    },
1136
1137
1138

    // This function is used to visually switch between the files and playlists
    // editing mode.
1139
1140
1141
1142
    switchMode: function (mode) {
      if (this.mode !== mode) {
        this.mode = mode
        for (var b in this.button) {
1143
1144
          if (b === mode) { this.button[b] = 'info' }
          else { this.button[b] = 'outline-info' }
1145
1146
1147
        }
      }
    },
1148
1149
1150
1151
1152

    // 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.
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
    fetchImports: function (slug){
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + slug + '/imports'
      axios.get(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token }
      }).then(response => {
        // if all imports are done, we will receive an empty result set and stop
        // polling the server again. now we can also refetch all file statuses.
        if (response.data.results === null) {
          clearInterval(this.uploadInterval)
          this.uploadInterval = null
          this.fetchShow(slug)
        } else {
          for (var i in response.data.results) {
            var f = this.getFileById(response.data.results[i].id)
            if (f) {
              f.source.import.progress = {
                progress: response.data.results[i].progress.progress,
                step: response.data.results[i].progress.step
              }
            }
            var 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
            console.log(p)
            this.$refs.filesTable.refresh()
          }
        }
      }).catch(error => {
1183
1184
1185
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not fetch current imports. See console for details.')
1186
1187
      })
    },
1188
1189

    // Just a wrapper to fetch both, files and playlists information.
1190
1191
1192
1193
    fetchShow: function (slug) {
      this.fetchFiles(slug)
      this.fetchPlaylists(slug)
    },
1194
1195

    // Fetch all files for a given show from the AuRa tank API
1196
    fetchFiles: function (slug) {
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
      this.loaded.files = false
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + slug + '/files'
      axios.get(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token }
      }).then(response => {
        // we don't have to check separately, if there are files, because tank
        // always provides an empty array if there are no files (or even if there is no corresponding show)
        this.files = response.data.results
        this.loaded.files = true
      }).catch(error => {
1208
1209
1210
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not fetch files from tank. See console for details.')
1211
      })
1212
    },
1213
1214

    // Fetch all playlists for a given show from the AuRa tank API
1215
1216
1217
    fetchPlaylists: function (slug) {
      this.loaded.playlists = false
      var uri = process.env.VUE_APP_API_TANK + 'shows/' + slug + '/playlists'
1218
1219
1220
1221
1222
1223
1224
1225
1226
      axios.get(uri, {
        withCredentials: true,
        headers: { 'Authorization': 'Bearer ' + this.$parent.user.access_token }
      }).then(response => {
        // we don't have to check separately, if there are playlists, because tank
        // always provides an empty array if there are no playlists (or even if there is no corresponding show)
        this.playlists = response.data.results
        this.loaded.playlists = true
      }).catch(error => {
1227
1228
1229
        console.log('Error: ' + error.response.status + ' ' + error.response.statusText)
        console.log(error.response)
        alert('Error: could not fetch playlists from tank. See console for details.')
1230
      })
1231
1232
1233
    }
  }
}
1234
1235
1236
</script>

<style>
1237
1238
1239
1240
1241
div.filelistbox {
  border: 1px solid #e9ecef;
  border-radius: 0.3rem;
  padding: 1rem 2rem;
}
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
.stateNew {
  color: red;
  font-weight: bold;
}
.stateRunning {
  color: darkgreen;
}
.stateUndefined {
  color: orange;
  font-weight: bold;
}
1253
1254
1255
1256
1257
1258
.upDownArrows {
  font-size: 1.15rem;
}
.modalPlaylistRows {
  padding: 0.2rem 0;
}
1259
</style>