Skip to content

Commit

Permalink
Merge pull request #19 from Kkoile/fb_delete_mp3_files
Browse files Browse the repository at this point in the history
Fb delete mp3 files
  • Loading branch information
Kkoile authored Dec 19, 2018
2 parents 702b4b3 + 802f3a8 commit 8cbc42e
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 6 deletions.
2 changes: 1 addition & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"preferGlobal": true,
"name": "figure-speaker-frontend",
"version": "0.0.13",
"version": "0.0.14",
"description": "Speaker which reacts to NFC tags and streams music",
"author": "[email protected]",
"repository": "[email protected]:Kkoile/figure-speaker.git",
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
},
"upload": {
"button": "Hochladen"
},
"deleteFileInUse": {
"text": "Diese Datei wird noch von einer Figur benutzt. Möchtest du sie trotzdem löschen?"
}
},
"youtube": {
Expand Down Expand Up @@ -150,6 +153,9 @@
"delete": {
"button": "Löschen"
},
"cancel": {
"button": "Abbrechen"
},
"search": {
"button": "Suchen"
},
Expand Down
6 changes: 6 additions & 0 deletions frontend/src/lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@
},
"upload": {
"button": "Upload"
},
"deleteFileInUse": {
"text": "This File is in use by a Figure. Do you still want to delete it?"
}
},
"youtube": {
Expand Down Expand Up @@ -150,6 +153,9 @@
"delete": {
"button": "Delete"
},
"cancel": {
"button": "Cancel"
},
"search": {
"button": "Search"
},
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/lib/mp3/components/File.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
<template xmlns:v-on="http://www.w3.org/1999/xhtml">
<md-list-item>
<md-dialog :md-active.sync="$store.state.mp3.showFileIsInUseDialog">
<md-dialog-title>{{ $t("mp3.deleteFileInUse.text") }}</md-dialog-title>

<md-dialog-actions>
<md-button class="md-primary" v-on:click="cancelDeleteFile">{{ $t("common.cancel.button") }}</md-button>
<md-button class="md-primary" v-on:click="deleteFile">{{ $t("common.delete.button") }}</md-button>
</md-dialog-actions>
</md-dialog>

<div class="md-list-item-text">{{ item }}</div>
<md-button v-on:click="saveItem">{{ $t("common.save.button") }}</md-button>
<md-button v-on:click="checkAndDeleteFile">{{ $t("common.delete.button") }}</md-button>
</md-list-item>
</template>

Expand All @@ -12,6 +22,15 @@ export default {
methods: {
saveItem: function () {
this.$store.dispatch('mp3/saveItem', 'local:track:' + this.item);
},
checkAndDeleteFile: function () {
this.$store.dispatch('mp3/checkIfFileIsInUse', this.item);
},
cancelDeleteFile: function () {
this.$store.dispatch('mp3/cancelDeleteFile');
},
deleteFile: function () {
this.$store.dispatch('mp3/deleteFile', this.$store.state.mp3.itemToDelete);
}
}
};
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/lib/mp3/components/Mp3.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
v-bind:item="file"
v-bind:key="file" />
</md-list>

<md-progress-bar md-mode="indeterminate" v-if="$store.state.mp3.uploadStatus === 'PENDING'" />

<input class="invisible" type="file" visible="false" id="file" ref="file" v-on:change="handleFileUpload()"/>
<div class="upload" v-if="$store.state.mp3.files.length > 0">
<md-button v-on:click="openFileChoser()">{{ $t("mp3.openFileChoser.button") }}</md-button>
Expand Down
50 changes: 47 additions & 3 deletions frontend/src/lib/mp3/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,70 @@ import axios from 'axios';
const state = {
query: '',
uploadStatus: null,
files: []
files: [],
showFileIsInUseDialog: false,
itemToDelete: null
};

const mutations = {
resetData (state) {
state.query = '';
state.uploadStatus = null;
state.files = [];
state.showFileIsInUseDialog = false;
state.itemToDelete = null;
},
updateUploadStatus (state, sStatus) {
state.uploadStatus = sStatus;
},
setAvailableMp3Files (state, aFiles) {
state.files = aFiles;
},
showFileIsInUseDialog (state, sFilename) {
state.showFileIsInUseDialog = true;
state.itemToDelete = sFilename;
},
hideFileIsInUseDialog (state) {
state.showFileIsInUseDialog = false;
state.itemToDelete = null;
}
};

var getEncodedUri = function (sUri) {
return encodeURI(sUri).replace(/\(/g, '%28').replace(/\)/g, '%29');
};

const actions = {
saveItem ({dispatch}, sUri) {
var sEncodedUri = encodeURI(sUri).replace(/\(/g, '%28').replace(/\)/g, '%29');
dispatch('saveItem', sEncodedUri, { root: true });
dispatch('saveItem', getEncodedUri(sUri), { root: true });
},
checkIfFileIsInUse ({commit, dispatch}, sFilename) {
axios.get('/data/checkIfUriIsInUse', {params: {uri: getEncodedUri('local:track:' + sFilename)}})
.then(function (oData) {
if (oData.data) {
commit('showFileIsInUseDialog', sFilename);
} else {
dispatch('deleteFile', sFilename);
}
})
.catch(function (oError) {
alert(oError);
});
},
deleteFile ({commit, dispatch}, sFilename) {
axios.delete('/data/mp3/deleteFile', {params: {filename: getEncodedUri(sFilename)}})
.then(function () {
dispatch('loadAvailable');
})
.catch(function (oError) {
alert(oError);
})
.then(function () {
commit('hideFileIsInUseDialog');
});
},
cancelDeleteFile ({commit}) {
commit('hideFileIsInUseDialog');
},
loadAvailable ({commit}) {
axios.get('/data/mp3')
Expand All @@ -32,6 +75,7 @@ const actions = {
});
},
upload ({commit, dispatch}, oFile) {
commit('updateUploadStatus', 'PENDING');
var oFormData = new FormData();
oFormData.append('file', oFile);
axios.post('/data/mp3/upload',
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"preferGlobal": true,
"name": "figure-speaker",
"version": "0.0.13",
"version": "0.0.14",
"author": "Nils Hirsekorn <[email protected]>",
"description": "Speaker which reacts to NFC tags and streams music",
"repository": "[email protected]:Kkoile/figure-speaker.git",
Expand Down
24 changes: 24 additions & 0 deletions server/api/dataApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var FileUpload = require('express-fileupload');

var hostController = require('../lib/hostController');
var mp3Controller = require('../lib/mp3Controller');
var settingsController = require('../lib/settingsController');

var dataApi = express.Router();

Expand All @@ -19,6 +20,17 @@ dataApi.route('/:host/authToken').get(function (req, res, next) {
.catch(next);
});

dataApi.route('/checkIfUriIsInUse').get(function (req, res, next) {
if (!req.query.uri) {
return res.status(400).send('Uri to check has to be passed as url parameter');
}
settingsController.checkIfUriIsInUse(req.query.uri)
.then(function(oData) {
res.send(oData);
})
.catch(next);
});

dataApi.route('/mp3').get(function (req, res, next) {
mp3Controller.getAvailableFileNames()
.then(function(oData) {
Expand All @@ -27,6 +39,18 @@ dataApi.route('/mp3').get(function (req, res, next) {
.catch(next);
});

dataApi.route('/mp3/deleteFile').delete(function (req, res, next) {
if (!req.query.filename) {
return res.status(400).send('No filename to be removed passed as url parameter');
}
var sFilename = decodeURI(req.query.filename);
mp3Controller.deleteFile(sFilename)
.then(function() {
res.send(200);
})
.catch(next);
});

dataApi.use(FileUpload());
dataApi.route('/mp3/upload').post(function (req, res, next) {
if (!req.files || Object.keys(req.files).length == 0) {
Expand Down
14 changes: 14 additions & 0 deletions server/lib/mp3Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,18 @@ exports.upload = function (oFile) {
})
.then(mopidy.scanMp3Files.bind(mopidy))
.then(mopidy.restart.bind(mopidy));
};

exports.deleteFile = function (sFilename) {
return new Promise(function (resolve, reject) {
if (!sFilename) {
return reject(new ApplicationError(400, "No File provided"));
}
fs.unlink(constants.Data.PathToMp3Files + '/' + sFilename, function(oError) {
if (oError) {
return reject(oError);
}
resolve();
});
});
};
10 changes: 10 additions & 0 deletions server/lib/settingsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,4 +258,14 @@ exports.getCurrentVersion = function () {
return new Promise(function (resolve) {
resolve(packageJson.version);
}.bind(this));
};

exports.checkIfUriIsInUse = function(sUri) {
return new Promise(function(resolve) {
var oConfig = this.getConfigFile();
var bUriIsInUse = Object.keys(oConfig).some(function(sKey) {
return oConfig[sKey] && oConfig[sKey].uri === sUri;
});
resolve(bUriIsInUse);
}.bind(this));
};
2 changes: 1 addition & 1 deletion server/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"preferGlobal": true,
"name": "figure-speaker-server",
"version": "0.0.13",
"version": "0.0.14",
"author": "Nils Hirsekorn",
"description": "Speaker which reacts to NFC tags and streams music",
"repository": "[email protected]:Kkoile/figure-speaker.git",
Expand Down
22 changes: 22 additions & 0 deletions server/test/mp3Controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,4 +219,26 @@ describe('MP3 Controller', function () {
});
});
});

describe('deleteFile', function () {
it('should delete the file', function (done) {
var oFsStub = sandbox.stub(fs, 'unlink').withArgs(constants.Data.PathToMp3Files + '/' + 'DUMMY_FILE.mp3').callsFake(function(sArgument, cb) {
cb();
});
mp3Controller.deleteFile('DUMMY_FILE.mp3')
.then(function() {
assert(oFsStub.calledOnce);
done();
});
});

it('should throw an error if no file name is provided', function (done) {
var oFsStub = sandbox.stub(fs, 'unlink');
mp3Controller.deleteFile(null)
.catch(function(oError) {
assert(oFsStub.notCalled);
done();
});
});
});
});
60 changes: 60 additions & 0 deletions server/test/settingsController.js
Original file line number Diff line number Diff line change
Expand Up @@ -850,4 +850,64 @@ describe('Settings Controller', function () {

});
});

describe('checkIfUriIsInUse', function () {
it('should get figures file and check if one uri is equal to the given URI', function (done) {

var oGetConfigStub = sandbox.stub(settingsController, 'getConfigFile').returns({
'SOME_ID': {
uri: 'DUMMY_URI'
},
'OTHER_ID': {
uri: 'DUMMY_URI_2'
}
});

settingsController.checkIfUriIsInUse('DUMMY_URI')
.then(function (bIsInUse) {
assert(bIsInUse === true);
assert(oGetConfigStub.calledOnce);
done();
});

});
it('should return true if an uri is used by two figures', function (done) {

var oGetConfigStub = sandbox.stub(settingsController, 'getConfigFile').returns({
'SOME_ID': {
uri: 'DUMMY_URI'
},
'OTHER_ID': {
uri: 'DUMMY_URI'
}
});

settingsController.checkIfUriIsInUse('DUMMY_URI')
.then(function (bIsInUse) {
assert(bIsInUse === true);
assert(oGetConfigStub.calledOnce);
done();
});

});
it('should return false if an uri is not used', function (done) {

var oGetConfigStub = sandbox.stub(settingsController, 'getConfigFile').returns({
'SOME_ID': {
uri: 'DUMMY_URI'
},
'OTHER_ID': {
uri: 'DUMMY_URI_2'
}
});

settingsController.checkIfUriIsInUse('DUMMY_URI_3')
.then(function (bIsInUse) {
assert(bIsInUse === false);
assert(oGetConfigStub.calledOnce);
done();
});

});
});
});

0 comments on commit 8cbc42e

Please sign in to comment.