diff --git a/package.json b/package.json index 58d29f2..e7fbf73 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "babel-eslint": "^10.1.0", "eslint": "^6.7.2", "eslint-plugin-vue": "^6.2.2", + "fs": "^0.0.1-security", + "jsmediatags": "^3.9.3", "vue-template-compiler": "^2.6.11" }, "eslintConfig": { diff --git a/scripts/weband-id3-to-json.js b/scripts/weband-id3-to-json.js new file mode 100644 index 0000000..82a8e6d --- /dev/null +++ b/scripts/weband-id3-to-json.js @@ -0,0 +1,98 @@ +const jsmediatags = require('jsmediatags'); +const fs = require('fs'); + +const INPUT = './public/audio/'; +const OUTPUT = 'src/data.json'; + + +const data = {"albums" : []}; +const promises = []; + +try { + if (fs.existsSync(INPUT)) { + //file exists + } + else { + console.log("\n============== Weband Error ====================\n\n"); + console.log("Audio files are missing. Please run first : \n\n$ ./scripts/weband-init.sh \n"); + console.log("\n================================================\n\n"); + process.exit(1); + } +} catch(err) { + console.log(err); + process.exit(1); +} + + +function is_dir(path) { + try { + var stat = fs.lstatSync(path); + return stat.isDirectory(); + } catch (e) { + // lstatSync throws an error if path doesn't exist + return false; + } +} + + + + +function id3ToJSON(path){ + fs.readdirSync(path).forEach(file => { + let isDir = is_dir(path + file); + if(isDir) + id3ToJSON(path + file + '/'); + else { + let filePath = path + file; + promises.push(new Promise((resolve, reject) => { + new jsmediatags.Reader(filePath) + .read({ + onSuccess: (tag) => { + var tags = tag.tags; + if(!data.artist) + data.artist = tags.artist; + let album = getAlbum(tags.album); + if(!album){ + album = {"title": tags.album, "tracks": [], "year": tags.year} + data.albums.push(album); + } + let track = {"title": tags.title, "file" : filePath.replace(INPUT,'audio/')}; + album.tracks.push(track); + resolve(tag); + }, + onError: (error) => { + console.log('Error'); + console.log(error); + reject(error); + } + }); + })); + } + }); +} + + +function getAlbum(albumTitle){ + for(let i = 0 ; i < data.albums.length; i++){ + if(data.albums[i].title === albumTitle) + return data.albums[i]; + } + return null; +} + +id3ToJSON(INPUT); + + +Promise.all(promises).then((values) => { + var jsonContent = JSON.stringify(data, null, 2); + console.log(jsonContent); + fs.writeFile(OUTPUT, jsonContent, 'utf8', function (err) { + if (err) { + console.log("An error occured while writing JSON Object to File."); + return console.log(err); + } + + console.log("JSON file has been saved : " + OUTPUT); + }); + +}); diff --git a/scripts/webbandd.sh b/scripts/webbandd.sh new file mode 100755 index 0000000..45eb099 --- /dev/null +++ b/scripts/webbandd.sh @@ -0,0 +1,85 @@ +#!/bin/bash +DIRECTORY=$(cd `dirname $0` && pwd) +IMAGES_DIRECTORY=$DIRECTORY'/../src/assets/images/' +AUDIOS_DIRECTORY=$DIRECTORY'/../public/audio/' + +ICONO_HEADER='icono_1.png' +ICONO_FOOTER='icono_2.png' + +display_usage(){ + echo "" + echo " webbandd script" + echo "" + echo " usage : webbandd.sh " + echo "" + echo " must contains :" + echo " - two image files : icono_1.png & icono_2.png" + echo " - one folder per album with mp3 and/or wav audio files" + echo "" +} + +error(){ + echo "" + echo " Weband ERROR :" + echo "" + echo " "$1 + echo "" +} + +# 1 argument required +if [ $# -ne 1 ] +then + display_usage + exit 1 +fi + + + + +# check_image(){ +# if [[ -e $1'.svg' || -e $1'.png' || -e $1'.jpg' ]] +# then +# return 0 +# else +# error $1' image file is missing !' +# exit -1 +# fi +# } + +check_image(){ + if [ -e $1 ] + then + return 0 + else + error $1' image file is missing !' + exit -1 + fi +} + +check_image $1'/'$ICONO_HEADER +echo " => "$1'/'$ICONO_HEADER" image exists - OK " +check_image $1'/'$ICONO_FOOTER +echo " => "$1'/'$ICONO_FOOTER" image exists - OK " + +#copy images (cover and contact) +cp $1'/'$ICONO_HEADER $IMAGES_DIRECTORY +cp $1'/'$ICONO_FOOTER $IMAGES_DIRECTORY + +if [ -d $AUDIOS_DIRECTORY ] +then + rm -rf $AUDIOS_DIRECTORY +fi + +mkdir $AUDIOS_DIRECTORY + + + +for d in `find $1/* -type d` +do + echo ' copying audio directory "'$d'"' + cp -r $d $AUDIOS_DIRECTORY +done + +echo " => audio files copy - OK " + +node $DIRECTORY'/weband-id3-to-json.js' diff --git a/src/App.vue b/src/App.vue index 55df315..e493104 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,28 +1,38 @@ diff --git a/src/assets/css/_variables.css b/src/assets/css/_variables.css new file mode 100644 index 0000000..8215168 --- /dev/null +++ b/src/assets/css/_variables.css @@ -0,0 +1,10 @@ +@font-face { + font-family: "work-sans"; + src: url('../fonts/work-sans/WorkSans-Regular.otf'); +} +:root{ + --font-family : 'work-sans'; + --pretty-margin: 0.5rem; + --main-color: black; + --secondary-color: black; +} diff --git a/src/assets/logo.png b/src/assets/logo.png deleted file mode 100644 index f3d2503..0000000 Binary files a/src/assets/logo.png and /dev/null differ diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue deleted file mode 100644 index 879051a..0000000 --- a/src/components/HelloWorld.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - diff --git a/src/components/Player.vue b/src/components/Player.vue new file mode 100644 index 0000000..a33f50d --- /dev/null +++ b/src/components/Player.vue @@ -0,0 +1,374 @@ + + + + + diff --git a/src/components/Weband.vue b/src/components/Weband.vue new file mode 100644 index 0000000..177dbea --- /dev/null +++ b/src/components/Weband.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/src/data.json.dist b/src/data.json.dist new file mode 100644 index 0000000..e9fc0ce --- /dev/null +++ b/src/data.json.dist @@ -0,0 +1,36 @@ +{ + "albums" : [ + { + "title" : "Album 1", + "date" : "2019", + "tracks" : [ + { + "file" : "audio/album_1/01.mp3", + "title" : "Track 1" + }, + { + "file" : "audio/album_1/02.mp3", + "title" : "Track 2" + }, + { + "file" : "audio/album_1/03.mp3", + "title" : "Track 3" + } + ] + }, + { + "title" : "Album 2", + "date" : "2020", + "tracks" : [ + { + "file" : "audio/album_2/04.mp3", + "title" : "Track X" + }, + { + "file" : "audio/album_2/05.mp3", + "title" : "Track Y" + } + ] + } + ] +} diff --git a/yarn.lock b/yarn.lock index d16c3dd..219713a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3729,6 +3729,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fs@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha1-invTcYa23d84E/I4WLV+yq9eQdQ= + fsevents@^1.2.7: version "1.2.13" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" @@ -4699,6 +4704,13 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= +jsmediatags@^3.9.3: + version "3.9.3" + resolved "https://registry.yarnpkg.com/jsmediatags/-/jsmediatags-3.9.3.tgz#309632d221d701bd385df65c9c6840cb399e11ff" + integrity sha512-h53yFnPYF1Y5jwr2ebcVzIIsvRpSalm0jhNiJDUztoPPHGpuHxi9YHUzdDgiw+ykiinXHd1s6HSIbudHw79zQw== + dependencies: + xhr2 "^0.1.4" + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -8190,6 +8202,11 @@ ws@^6.0.0, ws@^6.2.1: dependencies: async-limiter "~1.0.0" +xhr2@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" + integrity sha1-f4dliEdxbbUCYyOBL4GMras4el8= + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"