-
{{$t("Library")}}
+ {{$t("Library")}}
+
+ mdi-shuffle
+
+
@@ -76,7 +80,18 @@ export default {
}
},
methods: {
-
+ async shuffle() {
+ let res = await this.$axios.get('/shuffle');
+ if (res && res.data) {
+ this.$root.queue.source = {
+ text: this.$t('Shuffle'),
+ source: 'playlist',
+ data: 0
+ };
+ this.$root.replaceQueue(res.data);
+ this.$root.playIndex(0);
+ }
+ }
},
mounted() {
//Make mutable
diff --git a/app/client/src/views/Settings.vue b/app/client/src/views/Settings.vue
index 85b5a00..492daba 100644
--- a/app/client/src/views/Settings.vue
+++ b/app/client/src/views/Settings.vue
@@ -79,6 +79,18 @@
{{$t("Create folders for albums")}}
+
+
+
+
+
+
+ {{$t("Download album cover")}}
+
+
+
+
+
@@ -324,8 +336,10 @@ export default {
{code: 'es', name: 'Spanish'},
{code: 'tr', name: 'Turkish'},
{code: 'uk', name: 'Ukrainian'},
- {code: 'vi', name: 'Vietnamese'}
+ {code: 'vi', name: 'Vietnamese'},
+ {code: 'uwu', name: 'Furry'}
],
+ artResolutions: [256, 512, 600, 800, 1000, 1200, 1400, 1600, 1800],
colorPicker: false,
primaryColorIndex: 0,
primaries: ['#F44336', '#E91E63', '#9C27B0', '#673AB7', '#3F51B5', '#2196F3', '#03A9F4',
diff --git a/app/package.json b/app/package.json
index ae8980c..59880e4 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,7 +1,7 @@
{
"name": "freezer",
"private": true,
- "version": "1.1.11",
+ "version": "1.1.12",
"description": "",
"main": "background.js",
"scripts": {
diff --git a/app/src/deezer.js b/app/src/deezer.js
index 8c98d95..1e5e657 100644
--- a/app/src/deezer.js
+++ b/app/src/deezer.js
@@ -66,7 +66,7 @@ class DeezerAPI {
//Invalid CSRF
if (data.data.error && data.data.error.VALID_TOKEN_REQUIRED) {
- await this.callApi('deezer.getUserData');
+ await this.authorize();
return await this.callApi(method, args, gatewayInput);
}
@@ -127,7 +127,7 @@ class DeezerAPI {
//Invalid CSRF
if (data.error && data.error.VALID_TOKEN_REQUIRED) {
- await this.callApi('deezer.getUserData');
+ await this.authorize();
return await this.callApi(method, args, gatewayInput);
}
diff --git a/app/src/definitions.js b/app/src/definitions.js
index e73ca18..3b76d4a 100644
--- a/app/src/definitions.js
+++ b/app/src/definitions.js
@@ -122,14 +122,13 @@ class DeezerImage {
this.hash = hash;
this.type = type;
//Create full and thumb, to standardize size and because functions aren't preserved
- this.full = this.url(1400);
- this.thumb = this.url(256);
+ this.full = DeezerImage.url(this.hash, this.type, 1400);
+ this.thumb = DeezerImage.url(this.hash, this.type, 256);
}
-
- url(size = 256) {
- if (!this.hash)
- return `https://e-cdns-images.dzcdn.net/images/${this.type}/${size}x${size}-000000-80-0-0.jpg`;
- return `https://e-cdns-images.dzcdn.net/images/${this.type}/${this.hash}/${size}x${size}-000000-80-0-0.jpg`;
+ static url(hash, type, size = 256) {
+ if (!hash)
+ return `https://e-cdns-images.dzcdn.net/images/${type}/${size}x${size}-000000-80-0-0.jpg`;
+ return `https://e-cdns-images.dzcdn.net/images/${type}/${hash}/${size}x${size}-000000-80-0-0.jpg`;
}
}
diff --git a/app/src/downloads.js b/app/src/downloads.js
index 198fae7..99f72f2 100644
--- a/app/src/downloads.js
+++ b/app/src/downloads.js
@@ -9,7 +9,7 @@ const decryptor = require('nodeezcryptor');
const sanitize = require('sanitize-filename');
const ID3Writer = require('browser-id3-writer');
const Metaflac = require('metaflac-js2');
-const { Track, Lyrics } = require('./definitions');
+const { Track, Lyrics, DeezerImage } = require('./definitions');
const { throwDeprecation } = require('process');
let deezer;
@@ -206,6 +206,7 @@ class DownloadThread {
this.settings = settings;
this.stopped = true;
this.isUserUploaded = download.track.id.toString().startsWith('-');
+ this.coverPath = null;
}
//Callback wrapper
@@ -328,9 +329,11 @@ class DownloadThread {
await fs.promises.unlink(`${tmp}.DEC`);
await fs.promises.unlink(tmp);
+ let cover = null;
+
if (!this.isUserUploaded) {
- //Tag
- await this.tagTrack(outPath);
+ //Tag, returns cover to prevent double downlaoding
+ cover = await this.tagTrack(outPath);
//Lyrics
if (this.settings.downloadLyrics) {
@@ -346,6 +349,25 @@ class DownloadThread {
}
}
}
+
+ //Cover
+ if (this.coverPath) {
+ if (!fs.existsSync(this.coverPath)) {
+ //Create empty file to "lock"
+ fs.closeSync(fs.openSync(this.coverPath, 'w'));
+
+ if (!cover) {
+ try {
+ cover = await this.downloadCover(DeezerImage.url(this.track.albumArt.hash, 'cover', this.settings.coverResolution));
+ } catch (e) {}
+ }
+ if (!cover) {
+ logger.warn("Error downloading album art!");
+ } else {
+ await fs.promises.writeFile(this.coverPath, cover);
+ }
+ }
+ }
this.download.state = 3;
@@ -355,7 +377,7 @@ class DownloadThread {
async tagTrack(path) {
let cover;
try {
- cover = await this.downloadCover(this.track.albumArt.full);
+ cover = await this.downloadCover(this.track.albumArt.hash, 'cover', this.settings.coverResolution);
} catch (e) {}
//Genre tag
@@ -392,7 +414,8 @@ class DownloadThread {
//Write
await fs.promises.writeFile(path, Buffer.from(writer.arrayBuffer));
- return;
+
+ return cover;
}
//Tag FLAC
@@ -496,7 +519,12 @@ class DownloadThread {
}
//Generate folders
if (this.settings.createArtistFolder) folder = path.join(folder, sanitize(this.track.artists[0].name));
- if (this.settings.createAlbumFolder) folder = path.join(folder, sanitize(this.track.album.title));
+ if (this.settings.createAlbumFolder) {
+ folder = path.join(folder, sanitize(this.track.album.title));
+ if (this.settings.downloadCover) {
+ this.coverPath = path.join(folder, "cover.jpg");
+ }
+ }
//Extension
if (quality.toString() == '9') {
diff --git a/app/src/server.js b/app/src/server.js
index 0fb7643..14096e6 100644
--- a/app/src/server.js
+++ b/app/src/server.js
@@ -204,6 +204,15 @@ app.get('/profile', async (req, res) => {
res.send(profile);
});
+//Get shuffled library
+app.get('/shuffle', async (req, res) => {
+ let data = await deezer.callApi('tracklist.getShuffledCollection', {
+ nb: 50,
+ start: 0
+ });
+ res.send(data.results.data.map((t) => new Track(t)));
+});
+
//Get list of `type` from library
app.get('/library/:type', async (req, res) => {
let type = req.params.type;
diff --git a/app/src/settings.js b/app/src/settings.js
index 0cbf30f..2cbd835 100644
--- a/app/src/settings.js
+++ b/app/src/settings.js
@@ -23,6 +23,8 @@ class Settings {
this.createArtistFolder = true;
this.downloadFilename = '%0trackNumber%. %artists% - %title%';
this.downloadDialog = true;
+ this.downloadCover = true;
+ this.coverResolution = 1400;
this.logListen = false;
this.lastFM = null;
diff --git a/package.json b/package.json
index 9c18bf2..443a836 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "freezer",
"private": true,
- "version": "1.1.11",
+ "version": "1.1.12",
"description": "",
"scripts": {
"pack": "electron-builder --dir",