Release 4.1.3 4.1.3
authorRemixDev <DeezloaderRemix@gmail.com>
Sat, 25 Aug 2018 20:36:06 +0000 (22:36 +0200)
committerRemixDev <DeezloaderRemix@gmail.com>
Sat, 25 Aug 2018 20:36:06 +0000 (22:36 +0200)
13 files changed:
README.md
app/app.js
app/deezer-api.js
app/default.json
app/package.json
app/public/index.html
app/public/js/main.js
compileLinux.sh
compileMacOS.sh
compileWindows.bat [deleted file]
compileWindows32.bat [new file with mode: 0644]
compileWindows64.bat [new file with mode: 0644]
package.json

index 1038d6079693066641d76f06dcf1c03d8289e637..3e7cb9effc33bb0546a5270bb5cfcd615d9845de 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
 # Deezloader Remix
-### Latest Version: 4.1.2
+### Latest Version: 4.1.3
 Deezloader Remix is an improved version of Deezloader based on the Reborn branch.<br/>
 With this app you can download songs, playlists and albums directly from Deezers Server in a single and well packaged app.
 
index 522dd2b1a2bd525b3f31c9c8dedbf90205bd70d6..50c61c55ca752cc44598b940b08387bbfea720f0 100644 (file)
@@ -126,7 +126,7 @@ io.sockets.on('connection', function (socket) {
                Deezer.init(username, password, function (err) {
                        if(err){
                                socket.emit("login", {error: err.message});
-                               logger.error("Failed to login, "+err.stack);
+                               logger.error("Failed to login, "+err);
                        }else{
                                if(autologin){
                                        let data = username + "\n" + password;
@@ -139,7 +139,7 @@ io.sockets.on('connection', function (socket) {
                                        });
                                }
                                logger.info("Logging in");
-                               socket.emit("login", {username: Deezer.userName, picture: Deezer.userPicture});
+                               socket.emit("login", {username: Deezer.userName, picture: Deezer.userPicture, email: username});
                                logger.info("Logged in successfully");
                        }
                });
@@ -224,7 +224,7 @@ io.sockets.on('connection', function (socket) {
 
        function socketDownloadTrack(data){
                if(parseInt(data.id)>0){
-                       Deezer.getTrack(data.id, data.settings.maxBitrate, function (track, err) {
+                       Deezer.getTrack(data.id, data.settings.maxBitrate, data.settings.fallbackBitrate, function (track, err) {
                                if (err) {
                                        logger.error(err)
                                        return;
@@ -288,22 +288,17 @@ io.sockets.on('connection', function (socket) {
                                id: playlist["id"],
                                type: "playlist",
                                cover: playlist["picture_small"],
-                               tracks: playlist.tracks.data
                        };
                        _playlist.settings = data.settings || {};
-                       if (_playlist.size>400){
-                               Deezer.getPlaylistTracks(data.id, function (playlist, err) {
-                                       if (err){
-                                               logger.error(err)
-                                               return;
-                                       }
-                                       _playlist.size = playlist.data.length
-                                       _playlist.tracks = playlist.data
-                                       addToQueue(JSON.parse(JSON.stringify(_playlist)));
-                               })
-                       }else{
+                       Deezer.getAdvancedPlaylistTracks(data.id, function (playlist, err) {
+                               if (err){
+                                       logger.error(err)
+                                       return;
+                               }
+                               _playlist.size = playlist.data.length
+                               _playlist.tracks = playlist.data
                                addToQueue(JSON.parse(JSON.stringify(_playlist)));
-                       }
+                       })
                });
        }
        socket.on("downloadplaylist", data=>{socketDownloadPlaylist(data)});
@@ -325,11 +320,18 @@ io.sockets.on('connection', function (socket) {
                                queueId: queueId,
                                id: album["id"],
                                type: "album",
-                               tracks: album.tracks.data
                        };
                        data.settings.albumInfo = slimDownAlbumInfo(album)
                        _album.settings = data.settings || {};
-                       addToQueue(JSON.parse(JSON.stringify(_album)));
+                       Deezer.getAdvancedAlbumTracks(data.id, function (playlist, err) {
+                               if (err){
+                                       logger.error(err)
+                                       return;
+                               }
+                               _album.size = playlist.data.length
+                               _album.tracks = playlist.data
+                               addToQueue(JSON.parse(JSON.stringify(_album)));
+                       })
                });
        }
        socket.on("downloadalbum", data=>{socketDownloadAlbum(data)});
@@ -417,12 +419,12 @@ io.sockets.on('connection', function (socket) {
                                });
                                break;
                        case "album":
-                               downloading.playlistContent = downloading.tracks.map((t) => {
+                               downloading.playlistContent = downloading.tracks.map((t,i) => {
                                        if (t.FALLBACK){
                                                if (t.FALLBACK.SNG_ID)
-                                                       return {id: t.id, fallback: t.FALLBACK.SNG_ID, name: t.title, artist: t.artist.name, queueId: downloading.queueId}
+                                                       return {id: t.SNG_ID, fallback: t.FALLBACK.SNG_ID, name: (t.VERSION ? t.SNG_TITLE + " "+t.VERSION : t.SNG_TITLE), artist: t.ART_NAME, index: i+"", queueId: downloading.queueId}
                                        }else{
-                                               return {id: t.id, name: t.title, artist: t.artist.name, queueId: downloading.queueId}
+                                               return {id: t.SNG_ID, name: (t.VERSION ? t.SNG_TITLE+" "+t.VERSION : t.SNG_TITLE), artist: t.ART_NAME, index: i+"", queueId: downloading.queueId}
                                        }
                                })
                                downloading.settings.albName = downloading.name;
@@ -436,10 +438,10 @@ io.sockets.on('connection', function (socket) {
                                                filePath += antiDot(fixName(downloading.settings.artName)) + path.sep;
                                        }
                                        if (downloading.settings.createAlbumFolder) {
-                                               filePath += antiDot(fixName(settingsRegexAlbum(downloading.settings.foldername,downloading.settings.artName,downloading.settings.albName,downloading.settings.albumInfo.release_date.slice(0, 4),downloading.settings.albumInfo.record_type,downloading.settings.albumInfo.label))) + path.sep;
+                                               filePath += antiDot(fixName(settingsRegexAlbum(downloading.settings.foldername,downloading.settings.artName,downloading.settings.albName,downloading.settings.albumInfo.release_date.slice(0, 4),downloading.settings.albumInfo.record_type,downloading.settings.albumInfo.explicit_lyrics,downloading.settings.albumInfo.label))) + path.sep;
                                        }
                                } else if (downloading.settings.artName) {
-                                       filePath += antiDot(fixName(settingsRegexAlbum(downloading.settings.foldername,downloading.settings.artName,downloading.settings.albName,downloading.settings.albumInfo.release_date.slice(0, 4),downloading.settings.albumInfo.record_type,downloading.settings.albumInfo.label))) + path.sep;
+                                       filePath += antiDot(fixName(settingsRegexAlbum(downloading.settings.foldername,downloading.settings.artName,downloading.settings.albName,downloading.settings.albumInfo.release_date.slice(0, 4),downloading.settings.albumInfo.record_type,downloading.settings.albumInfo.explicit_lyrics,downloading.settings.albumInfo.label))) + path.sep;
                                }
                                downloading.finished = new Promise((resolve,reject)=>{
                                        downloading.playlistContent.every(function (t) {
@@ -456,7 +458,7 @@ io.sockets.on('connection', function (socket) {
                                                                        if (track.searched) downloading.searchedLog += `${t.artist} - ${t.name}\r\n`
                                                                } else {
                                                                        downloading.failed++;
-                                                                       downloading.errorLog += `${t.id} | ${t.artist} - ${t.name}\r\n`;
+                                                                       downloading.errorLog += `${t.id} | ${t.artist} - ${t.name} | ${err}\r\n`;
                                                                }
                                                                socket.emit("downloadProgress", {
                                                                        queueId: downloading.queueId,
@@ -517,9 +519,9 @@ io.sockets.on('connection', function (socket) {
                                downloading.playlistContent = downloading.tracks.map((t,i) => {
                                        if (t.FALLBACK){
                                                if (t.FALLBACK.SNG_ID)
-                                                       return {id: t.id, fallback: t.FALLBACK.SNG_ID, name: t.title, artist: t.artist.name, index: i, queueId: downloading.queueId}
+                                                       return {id: t.SNG_ID, fallback: t.FALLBACK.SNG_ID, name: (t.VERSION ? t.SNG_TITLE + " "+t.VERSION : t.SNG_TITLE), artist: t.ART_NAME, index: i+"", queueId: downloading.queueId}
                                        }else{
-                                               return {id: t.id, name: t.title, artist: t.artist.name, index: i+"", queueId: downloading.queueId}
+                                               return {id: t.SNG_ID, name: (t.VERSION ? t.SNG_TITLE+" "+t.VERSION : t.SNG_TITLE), artist: t.ART_NAME, index: i+"", queueId: downloading.queueId}
                                        }
                                })
                                downloading.settings.plName = downloading.name;
@@ -545,7 +547,7 @@ io.sockets.on('connection', function (socket) {
                                                                        if (track.searched) downloading.searchedLog += `${t.artist} - ${t.name}\r\n`
                                                                } else {
                                                                        downloading.failed++;
-                                                                       downloading.errorLog += `${t.id} | ${t.artist} - ${t.name}\r\n`
+                                                                       downloading.errorLog += `${t.id} | ${t.artist} - ${t.name} | ${err}\r\n`;
                                                                }
                                                                socket.emit("downloadProgress", {
                                                                        queueId: downloading.queueId,
@@ -590,7 +592,7 @@ io.sockets.on('connection', function (socket) {
                                                let imgPath = filePath + antiDot(fixName(settingsRegexCover(downloading.settings.coverImageTemplate,downloading.artist,downloading.name)))+(downloading.settings.PNGcovers ? ".png" : ".jpg");
                                                if (downloading.cover){
                                                        downloading.cover = downloading.cover.replace("56x56",`${downloading.settings.artworkSize}x${downloading.settings.artworkSize}`)
-                                                       request.get(downloading.cover, {encoding: 'binary'}, function(error,response,body){
+                                                       request.get(downloading.cover, {strictSSL: false,encoding: 'binary'}, function(error,response,body){
                                                                if(error){
                                                                        logger.error(error.stack);
                                                                        return;
@@ -684,7 +686,7 @@ io.sockets.on('connection', function (socket) {
                                                                                if (track.searched) downloading.searchedLog += `${t.artist} - ${t.name}\r\n`
                                                                        } else {
                                                                                downloading.failed++;
-                                                                               downloading.errorLog += `${t.id} | ${t.artist} - ${t.name}\r\n`
+                                                                               downloading.errorLog += `${t.id} | ${t.artist} - ${t.name} | ${err}\r\n`;
                                                                        }
                                                                        socket.emit("downloadProgress", {
                                                                                queueId: downloading.queueId,
@@ -728,7 +730,7 @@ io.sockets.on('connection', function (socket) {
                                                        if (!fs.existsSync(filePath)) fs.mkdirSync(filePath);
                                                        let imgPath = filePath + antiDot(fixName(settingsRegexCover(downloading.settings.coverImageTemplate,downloading.artist,downloading.name)))+(downloading.settings.PNGcovers ? ".png" : ".jpg");
                                                        if (downloading.cover){
-                                                               request.get(downloading.cover, {encoding: 'binary'}, function(error,response,body){
+                                                               request.get(downloading.cover, {strictSSL: false,encoding: 'binary'}, function(error,response,body){
                                                                        if(error){
                                                                                logger.error(error.stack);
                                                                                return;
@@ -892,7 +894,13 @@ io.sockets.on('connection', function (socket) {
                if (["track", "playlist", "album", "artist"].indexOf(data.type) == -1) data.type = "track";
 
                // Remove "feat."  "ft." and "&" (causes only problems)
-               data.text = data.text.replace(/ feat[\.]? /g, " ").replace(/ ft[\.]? /g, " ").replace(/\(feat[\.]? /g, " ").replace(/\(ft[\.]? /g, " ").replace(/\&/g, "");
+               data.text = data.text
+                       .replace(/ feat[\.]? /g, " ")
+                       .replace(/ ft[\.]? /g, " ")
+                       .replace(/\(feat[\.]? /g, " ")
+                       .replace(/\(ft[\.]? /g, " ")
+                       .replace(/\&/g, "")
+                       .replace(/–/g, "-");
 
                Deezer.search(encodeURIComponent(data.text), data.type, function (searchObject, err) {
                        try {
@@ -1058,13 +1066,13 @@ io.sockets.on('connection', function (socket) {
 
        function downloadTrack(t, settings, altmetadata, callback) {
                if (!socket.downloadQueue[t.queueId]) {
-                       logger.error("Not in queue");
+                       logger.error(`Failed to download ${t.artist} - ${t.name}: Not in queue`);
                        callback(new Error("Not in queue"));
                        return;
                }
                if (t.id == 0){
-                       logger.error("Failed to download track: Wrong ID");
-                       callback(new Error("Failed to download track: Wrong ID"));
+                       logger.error(`Failed to download ${t.artist} - ${t.name}: Wrong ID`);
+                       callback(new Error("Wrong ID"));
                        return;
                }
                settings = settings || {};
@@ -1078,22 +1086,27 @@ io.sockets.on('connection', function (socket) {
                                                        if(!t.searched){
                                                                logger.warn("Failed to download track, searching for alternative");
                                                                Deezer.track2ID(t.artist, t.name, null, data=>{
-                                                                       t.searched = true;
-                                                                       t.id = data.id;
-                                                                       t.artist = data.artist;
-                                                                       t.name = data.name;
-                                                                       downloadTrack(t, settings, null, callback);
+                                                                       if (t.id != 0){
+                                                                               t.searched = true;
+                                                                               t.id = data.id;
+                                                                               t.artist = data.artist;
+                                                                               t.name = data.name;
+                                                                               downloadTrack(t, settings, null, callback);
+                                                                       }else{
+                                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: Searched alternative; Not found`);
+                                                                               callback(new Error("Searched alternative; Not found"));
+                                                                       }
                                                                });
                                                        }else{
-                                                               logger.error("Failed to download track: "+ err);
-                                                               callback(err, `${t.id} | ${t.artist} - ${t.name}`);
+                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: ${err}`);
+                                                               callback(err);
                                                        }
                                                        return;
                                                }
                                                resolve(trackInfo);
                                        });
                                }else{
-                                       Deezer.getTrack(t.id, settings.maxBitrate, function (trackInfo, err) {
+                                       Deezer.getTrack(t.id, settings.maxBitrate, settings.fallbackBitrate, function (trackInfo, err) {
                                                if (err) {
                                                        if(t.fallback){
                                                                logger.warn("Failed to download track, falling on alternative");
@@ -1103,15 +1116,20 @@ io.sockets.on('connection', function (socket) {
                                                        }else if(!t.searched){
                                                                logger.warn("Failed to download track, searching for alternative");
                                                                Deezer.track2ID(t.artist, t.name, null, data=>{
-                                                                       t.searched = true;
-                                                                       t.id = data.id;
-                                                                       t.artist = data.artist;
-                                                                       t.name = data.name;
-                                                                       downloadTrack(t, settings, null, callback);
+                                                                       if (t.id != 0){
+                                                                               t.searched = true;
+                                                                               t.id = data.id;
+                                                                               t.artist = data.artist;
+                                                                               t.name = data.name;
+                                                                               downloadTrack(t, settings, null, callback);
+                                                                       }else{
+                                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: Searched alternative; Not found`);
+                                                                               callback(new Error("Searched alternative; Not found"));
+                                                                       }
                                                                });
                                                        }else{
-                                                               logger.error("Failed to download track: "+ err);
-                                                               callback(err, `${t.id} | ${t.artist} - ${t.name}`);
+                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: ${err}`);
+                                                               callback(err);
                                                        }
                                                        return;
                                                }
@@ -1143,15 +1161,20 @@ io.sockets.on('connection', function (socket) {
                                                                        }else if(!t.searched){
                                                                                logger.warn("Failed to download track, searching for alternative");
                                                                                Deezer.track2ID(t.artist, t.name, null, data=>{
-                                                                                       t.searched = true;
-                                                                                       t.id = data.id;
-                                                                                       t.artist = data.artist;
-                                                                                       t.name = data.name;
-                                                                                       downloadTrack(t, settings, null, callback);
+                                                                                       if (t.id != 0){
+                                                                                               t.searched = true;
+                                                                                               t.id = data.id;
+                                                                                               t.artist = data.artist;
+                                                                                               t.name = data.name;
+                                                                                               downloadTrack(t, settings, null, callback);
+                                                                                       }else{
+                                                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: Searched alternative album; Not found`);
+                                                                                               callback(new Error("Searched alternative album; Not found"));
+                                                                                       }
                                                                                });
                                                                        }else{
-                                                                               logger.error("Failed to download track: "+ err);
-                                                                               callback(new Error("Album does not exists."));
+                                                                               logger.error(`Failed to download ${t.artist} - ${t.name}: ${err}`);
+                                                                               callback(err);
                                                                        }
                                                                        return;
                                                                }
@@ -1167,7 +1190,6 @@ io.sockets.on('connection', function (socket) {
                        }else{
                                resolve({artist:{}})
                        }
-
                });
                temp.then(albumres=>{
                let ajson = albumres;
@@ -1228,15 +1250,15 @@ io.sockets.on('connection', function (socket) {
 
                        if (settings.createAlbumFolder) {
                                if(settings.artName){
-                                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,settings.artName,settings.albName,metadata.year,metadata.rtype,metadata.publisher))) + path.sep;
+                                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,settings.artName,settings.albName,metadata.year,metadata.rtype,metadata.albumExplicit,metadata.publisher))) + path.sep;
                                }else{
-                                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,metadata.albumArtist,metadata.album,metadata.year,metadata.rtype,metadata.publisher))) + path.sep;
+                                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,metadata.albumArtist,metadata.album,metadata.year,metadata.rtype,metadata.albumExplicit,metadata.publisher))) + path.sep;
                                }
                        }
                } else if (settings.plName) {
                        filepath += antiDot(fixName(settings.plName)) + path.sep;
                } else if (settings.artName) {
-                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,settings.artName,settings.albName,metadata.year,metadata.rtype,metadata.publisher))) + path.sep;
+                       filepath += antiDot(fixName(settingsRegexAlbum(settings.foldername,settings.artName,settings.albName,metadata.year,metadata.rtype,metadata.albumExplicit,metadata.publisher))) + path.sep;
                }
                let coverpath = filepath;
                if (metadata.discTotal > 1 && (settings.artName || settings.createAlbumFolder) && settings.createCDFolder){
@@ -1261,7 +1283,7 @@ io.sockets.on('connection', function (socket) {
                }
                let playlistData = [0,""]
                if (settings.createM3UFile && (settings.plName || settings.albName)) {
-                       if (settings.numplaylistbyalbum && t.index){
+                       if (t.index){
                                playlistData = [parseInt(t.index), writePath];
                        }else{
                                playlistData = [metadata.trackNumber-1, writePath];
@@ -1280,20 +1302,19 @@ io.sockets.on('connection', function (socket) {
                                let imgPath;
                                //If its not from an album but a playlist.
                                if(!(settings.albName || settings.createAlbumFolder)){
-                                       imgPath = coverArtFolder + (metadata.barcode ? fixName(metadata.barcode) : fixName(`${metadata.albumArtist - metadata.album}`))+(settings.PNGcovers ? ".png" : ".jpg");
+                                       imgPath = coverArtFolder + (metadata.barcode ? fixName(metadata.barcode) : fixName(`${metadata.albumArtist} - ${metadata.album}`))+(settings.PNGcovers ? ".png" : ".jpg");
                                }else{
                                        if (settings.saveArtwork)
-                                               imgPath = coverpath + antiDot(fixName(settingsRegexCover(settings.coverImageTemplate,settings.artName,settings.albName)))+(settings.PNGcovers ? ".png" : ".jpg");
+                                               imgPath = coverpath + fixName(settingsRegexCover(settings.coverImageTemplate,settings.artName,settings.albName))+(settings.PNGcovers ? ".png" : ".jpg");
                                        else
-                                               imgPath = coverArtFolder + fixName(metadata.barcode)+(settings.PNGcovers ? ".png" : ".jpg");
+                                               imgPath = coverArtFolder + fixName(metadata.barcode ? fixName(metadata.barcode) : fixName(`${metadata.albumArtist} - ${metadata.album}`))+(settings.PNGcovers ? ".png" : ".jpg");
                                }
-
                                if(fs.existsSync(imgPath)){
                                        metadata.imagePath = (imgPath).replace(/\\/g, "/");
                                        logger.info("Starting the download process CODE:1");
                                        resolve();
                                }else{
-                                       request.get(metadata.image, {encoding: 'binary'}, function(error,response,body){
+                                       request.get(metadata.image, {strictSSL: false,encoding: 'binary'}, function(error,response,body){
                                                if(error){
                                                        logger.error(error.stack);
                                                        metadata.image = undefined;
@@ -1328,11 +1349,12 @@ io.sockets.on('connection', function (socket) {
                                        if(fs.existsSync(imgPath)){
                                                resolve();
                                        }else{
-                                               request.get(metadata.artistImage, {encoding: 'binary'}, function(error,response,body){
+                                               request.get(metadata.artistImage, {strictSSL: false,encoding: 'binary'}, function(error,response,body){
                                                        if(error){
                                                                logger.error(error.stack);
                                                                return;
                                                        }
+                                                       if (body.indexOf("unauthorized")>-1) return resolve();
                                                        fs.outputFile(imgPath,body,'binary',function(err){
                                                                if(err){
                                                                        logger.error(err.stack);
@@ -1378,11 +1400,11 @@ io.sockets.on('connection', function (socket) {
                                                t.id = data.id;
                                                t.artist = data.artist;
                                                t.name = data.name;
-                                               downloadTrack(t, settings, null, callback);
+                                               downloadTrack(t, settings, metadata, callback);
                                        });
                                }else{
-                                       logger.error("Failed to download: " + metadata.artist + " - " + metadata.title);
-                                       callback(err, `${t.id} | ${t.artist} - ${t.name}`)
+                                       logger.error(`Failed to download ${t.artist} - ${t.name}: ${err}`);
+                                       callback(err)
                                }
                                return;
                        }
@@ -1406,7 +1428,7 @@ io.sockets.on('connection', function (socket) {
                                                flacComments.push('ITUNESADVISORY=' + metadata.explicit);
                                        if (settings.tags.isrc)
                                                flacComments.push('ISRC=' + metadata.ISRC);
-                                       if (settings.tags.artist)
+                                       if (settings.tags.artist && metadata.artists)
                                                metadata.artists.forEach(x=>{
                                                        flacComments.push('ARTIST=' + x);
                                                });
@@ -1475,7 +1497,7 @@ io.sockets.on('connection', function (socket) {
                                        }
                                        let mdbVorbisPicture;
                                        let mdbVorbisComment;
-                                       processor.on('preprocess', (mdb) => {
+                                       processor.on('preprocess', function(mdb){
                                                // Remove existing VORBIS_COMMENT and PICTURE blocks, if any.
                                                if (mflac.Processor.MDB_TYPE_VORBIS_COMMENT === mdb.type) {
                                                        mdb.remove();
@@ -1483,24 +1505,18 @@ io.sockets.on('connection', function (socket) {
                                                        mdb.remove();
                                                }
                                                if (mdb.isLast) {
-                                                       res = settings.artworkSize;
+                                                       mdbVorbisComment = mflac.data.MetaDataBlockVorbisComment.create(false, vendor, flacComments);
+                                                       processor.push(mdbVorbisComment.publish());
                                                        if(cover){
-                                                               mdbVorbisPicture = mflac.data.MetaDataBlockPicture.create(true, 3, `image/${(settings.PNGcovers) ? "png" : "jpeg"}`, '', res, res, 24, 0, cover);
+                                                               mdbVorbisPicture = mflac.data.MetaDataBlockPicture.create(false, 3, `image/${(settings.PNGcovers ? "png" : "jpeg")}`, '', settings.artworkSize, settings.artworkSize, 24, 0, cover);
+                                                               processor.push(mdbVorbisPicture.publish());
                                                        }
-                                                       mdbVorbisComment = mflac.data.MetaDataBlockVorbisComment.create(false, vendor, flacComments);
-                                                       mdb.isLast = false;
                                                }
                                        });
                                        processor.on('postprocess', (mdb) => {
                                                if (mflac.Processor.MDB_TYPE_VORBIS_COMMENT === mdb.type && null !== mdb.vendor) {
                                                        vendor = mdb.vendor;
                                                }
-                                               if (mdbVorbisPicture && mdbVorbisComment) {
-                                                       processor.push(mdbVorbisComment.publish());
-                                                       processor.push(mdbVorbisPicture.publish());
-                                               }else if(mdbVorbisComment){
-                                                       processor.push(mdbVorbisComment.publish());
-                                               }
                                        });
                                        reader.on('end', () => {
                                                fs.remove(tempPath);
@@ -1539,7 +1555,7 @@ io.sockets.on('connection', function (socket) {
                                                        description: ''
                                                });
                                        }
-                                       if(metadata.unsynchronisedLyrics && settings.tags.cover)
+                                       if(metadata.unsynchronisedLyrics && settings.tags.unsynchronisedLyrics)
                                                writer.setFrame('USLT', metadata.unsynchronisedLyrics);
                                        if(metadata.publisher && settings.tags.publisher)
                                                writer.setFrame('TPUB', metadata.publisher);
@@ -1568,7 +1584,6 @@ io.sockets.on('connection', function (socket) {
                                        fs.remove(tempPath);
                                }
                        }
-                       t.trackSocket = null;
                        callback(null, {playlistData: playlistData, searched: t.searched});
                })
        })
@@ -1662,7 +1677,8 @@ function settingsRegex(metadata, filename, playlist) {
        } else {
                filename = filename.replace(/%number%/g, '');
        }
-       return filename;
+       filename = filename.replace(/%explicit%/g, (metadata.explicit ? (filename.indexOf(/[^%]explicit/g)>-1 ? "" : "(Explicit Version)") : ""));
+       return filename.trim();
 }
 
 /**
@@ -1671,7 +1687,7 @@ function settingsRegex(metadata, filename, playlist) {
  * @param foldername
  * @returns {XML|string|*}
  */
-function settingsRegexAlbum(foldername, artist, album, year, rtype, publisher) {
+function settingsRegexAlbum(foldername, artist, album, year, rtype, explicit, publisher) {
        foldername = foldername.replace(/%album%/g, album);
        foldername = foldername.replace(/%artist%/g, artist);
        foldername = foldername.replace(/%year%/g, year);
@@ -1681,7 +1697,8 @@ function settingsRegexAlbum(foldername, artist, album, year, rtype, publisher) {
                foldername = foldername.replace(/%type%/g, "");
        }
        foldername = foldername.replace(/%label%/g, publisher);
-       return foldername;
+       foldername = foldername.replace(/%explicit%/g, (explicit ? (foldername.indexOf(/[^%]explicit/g)>-1 ? "" : "(Explicit)") : ""));
+       return foldername.trim();
 }
 
 function settingsRegexCover(foldername, artist, name) {
@@ -1770,6 +1787,7 @@ function slimDownAlbumInfo(ajsonOld){
        ajson.record_type = ajsonOld.record_type
        ajson.label = ajsonOld.label
        ajson.genres = ajsonOld.genres
+       ajson.explicit_lyrics = ajsonOld.explicit_lyrics
        ajson.release_date = ajsonOld.release_date
        ajson.tracks = {
                data: ajsonOld.tracks.data.map(x=>{
@@ -1796,6 +1814,12 @@ function swichReleaseType(id){
 function parseMetadata(track, ajson, totalDiskNumber, settings, position, altmetadata){
        let metadata;
        if (track["VERSION"]) track["SNG_TITLE"] += " " + track["VERSION"];
+       if (settings.removeAlbumVersion){
+               if(track["SNG_TITLE"].indexOf("Album Version")>-1){
+                       track["SNG_TITLE"] = track["SNG_TITLE"].replace(/\(Album Version\)/g,"")
+                       track["SNG_TITLE"].trim()
+               }
+       }
        if(altmetadata){
                metadata = altmetadata;
                if(track["LYRICS_TEXT"] && !metadata.unsynchronisedLyrics){
@@ -1825,6 +1849,9 @@ function parseMetadata(track, ajson, totalDiskNumber, settings, position, altmet
                if (!metadata.rtype){
                        metadata.rtype = swichReleaseType(track["TYPE"])
                }
+               if (ajson.explicit_lyrics){
+                       metadata.albumExplicit = ajson.explicit_lyrics;
+               }
                if(track["SNG_CONTRIBUTORS"]){
                        if(track["SNG_CONTRIBUTORS"].composer){
                                metadata.composer = [];
@@ -1946,10 +1973,29 @@ function parseMetadata(track, ajson, totalDiskNumber, settings, position, altmet
                }
                if (ajson.release_date) {
                        metadata.year = ajson.release_date.slice(0, 4);
-                       metadata.date = ajson.release_date;
+                       metadata.date = {
+                               day: ajson.release_date.slice(5,7),
+                               month:  ajson.release_date.slice(8,10),
+                               year: (settings.dateFormatYear == "2" ? ajson.release_date.slice(2, 4) : ajson.release_date.slice(0, 4))
+                       }
                } else if(track["PHYSICAL_RELEASE_DATE"]){
                        metadata.year = track["PHYSICAL_RELEASE_DATE"].slice(0, 4);
-                       metadata.date = track["PHYSICAL_RELEASE_DATE"];
+                       metadata.date = {
+                               day: track["PHYSICAL_RELEASE_DATE"].slice(5,7),
+                               month:  track["PHYSICAL_RELEASE_DATE"].slice(8,10),
+                               year: (settings.dateFormatYear == "2" ? track["PHYSICAL_RELEASE_DATE"].slice(2, 4) : track["PHYSICAL_RELEASE_DATE"].slice(0, 4))
+                       }
+               }
+               if (metadata.date){
+                       let date
+                       switch (settings.dateFormat){
+                               case "0": date = `${metadata.date.year}-${metadata.date.month}-${metadata.date.day}`; break;
+                               case "1": date = `${metadata.date.day}-${metadata.date.month}-${metadata.date.year}`; break;
+                               case "2": date = `${metadata.date.month}-${metadata.date.day}-${metadata.date.year}`; break;
+                               case "3": date = `${metadata.date.year}-${metadata.date.day}-${metadata.date.month}`; break;
+                               default: date = `${metadata.date.day}-${metadata.date.month}-${metadata.date.year}`; break;
+                       }
+                       metadata.date = date;
                }
                if(settings.plName && !(settings.createArtistFolder || settings.createAlbumFolder) && !settings.numplaylistbyalbum){
                        metadata.trackNumber = (position+1).toString();
index 54f796ab528e38128953d4fcdc219c214a19ff21..acf2e7a79e1a8dc2b51c3f71c623a6ebb7fb6d65 100644 (file)
@@ -24,6 +24,7 @@ Deezer.prototype.init = function(username, password, callback) {
        var self = this;
        request.post({
                url: self.apiUrl,
+               strictSSL: false,
                qs: {
                        api_version: "1.0",
                        api_token: "null",
@@ -42,6 +43,7 @@ Deezer.prototype.init = function(username, password, callback) {
                request.post({
                        url: "https://www.deezer.com/ajax/action.php",
                        headers: this.httpHeaders,
+                       strictSSL: false,
                        form: {
                                type:'login',
                                mail:username,
@@ -51,10 +53,11 @@ Deezer.prototype.init = function(username, password, callback) {
                        jar: true
                }, function(err, res, body) {
                        if(err || res.statusCode != 200) {
-                               callback(new Error("Unable to load deezer.com"));
+                               callback(new Error(`Unable to load deezer.com: ${res ? (res.statusCode != 200 ? res.statusCode : "") : ""} ${err ? err.message : ""}`));
                        }else if(body.indexOf("success") > -1){
                                request.post({
                                        url: self.apiUrl,
+                                       strictSSL: false,
                                        qs: {
                                                api_version: "1.0",
                                                api_token: "null",
@@ -72,7 +75,7 @@ Deezer.prototype.init = function(username, password, callback) {
                                                self.userPicture = `https:\/\/e-cdns-images.dzcdn.net\/images\/user\/${user.USER_PICTURE}\/250x250-000000-80-0-0.jpg`;
                                                callback(null, null);
                                        } else {
-                                               callback(new Error("Unable to load deezer.com "+err));
+                                               callback(new Error(`Unable to load deezer.com: ${res ? (res.statusCode != 200 ? res.statusCode : "") : ""} ${err ? err.message : ""}`));
                                        }
                                });
                        }else{
@@ -102,6 +105,7 @@ Deezer.prototype.getAAlbum = function(id, callback) {
                request.post({
                        url: self.apiUrl,
                        headers: self.httpHeaders,
+                       strictSSL: false,
                        qs: {
                                api_version: "1.0",
                                input: "3",
@@ -142,22 +146,67 @@ Deezer.prototype.getArtist = function(id, callback) {
 }
 
 Deezer.prototype.getPlaylistTracks = function(id, callback) {
-       getJSON("https://api.deezer.com/playlist/" + id + "/tracks?limit=-1", function(res, err){
+       getJSON(`https://api.deezer.com/playlist/${id}/tracks?limit=-1`, function(res, err){
                callback(res, err);
        });
 }
 
-Deezer.prototype.getAlbumSize = function(id, callback) {
-       getJSON("https://api.deezer.com/album/" + id + "/tracks?limit=1", function(res, err){
+Deezer.prototype.getAlbumTracks = function(id, callback) {
+       getJSON(`https://api.deezer.com/album/${id}/tracks?limit=-1`, function(res, err){
                callback(res, err);
        });
+}
 
+Deezer.prototype.getAdvancedPlaylistTracks = function(id, callback) {
+       var self = this;
+       self.getToken().then(data=>{
+               request.post({
+                       url: self.apiUrl,
+                       headers: self.httpHeaders,
+                       strictSSL: false,
+                       qs: {
+                               api_version: "1.0",
+                               input: "3",
+                               api_token: data,
+                               method: "playlist.getSongs"
+                       },
+                       body: {playlist_id:id, nb:-1},
+                       jar: true,
+                       json: true
+               }, (function (err, res, body) {
+                       if(!err && res.statusCode == 200 && typeof body.results != 'undefined'){
+                               callback(body.results);
+                       } else {
+                               callback(null, new Error("Unable to get Album" + id));
+                       }
+               }).bind(self));
+       })
 }
 
-Deezer.prototype.getAlbumTracks = function(id, callback) {
-       getJSON("https://api.deezer.com/album/" + id + "/tracks?limit=-1", function(res, err){
-               callback(res, err);
-       });
+Deezer.prototype.getAdvancedAlbumTracks = function(id, callback) {
+       var self = this;
+       self.getToken().then(data=>{
+               request.post({
+                       url: self.apiUrl,
+                       headers: self.httpHeaders,
+                       strictSSL: false,
+                       qs: {
+                               api_version: "1.0",
+                               input: "3",
+                               api_token: data,
+                               method: "song.getListByAlbum"
+                       },
+                       body: {alb_id:id,nb:-1},
+                       jar: true,
+                       json: true
+               }, (function (err, res, body) {
+                       if(!err && res.statusCode == 200 && typeof body.results != 'undefined'){
+                               callback(body.results);
+                       } else {
+                               callback(null, new Error("Unable to get Album" + id));
+                       }
+               }).bind(self));
+       })
 }
 
 Deezer.prototype.getArtistAlbums = function(id, callback) {
@@ -202,6 +251,7 @@ Deezer.prototype.getLocalTrack = function(id, callback) {
                request.post({
                        url: self.apiUrl,
                        headers: self.httpHeaders,
+                       strictSSL: false,
                        qs: {
                                api_version: "1.0",
                                input: "3",
@@ -224,13 +274,14 @@ Deezer.prototype.getLocalTrack = function(id, callback) {
        })
 }
 
-Deezer.prototype.getTrack = function(id, maxBitrate, callback) {
+Deezer.prototype.getTrack = function(id, maxBitrate, fallbackBitrate, callback) {
        var scopedid = id;
        var self = this;
        self.getToken().then(data=>{
                request.post({
                        url: self.apiUrl,
                        headers: self.httpHeaders,
+                       strictSSL: false,
                        qs: {
                                api_version: "1.0",
                                input: "3",
@@ -258,16 +309,20 @@ Deezer.prototype.getTrack = function(id, maxBitrate, callback) {
                                        case "9":
                                                format = 9;
                                                if (json["FILESIZE_FLAC"]>0) break;
+                                               if (!fallbackBitrate) return callback(null, new Error("Song not found at desired bitrate."))
                                        case "3":
                                                format = 3;
                                                if (json["FILESIZE_MP3_320"]>0) break;
+                                               if (!fallbackBitrate) return callback(null, new Error("Song not found at desired bitrate."))
                                        case "5":
                                                format = 5;
                                                if (json["FILESIZE_MP3_256"]>0) break;
+                                               if (!fallbackBitrate) return callback(null, new Error("Song not found at desired bitrate."))
                                        case "1":
                                                format = 1;
                                                if (json["FILESIZE_MP3_128"]>0) break;
-                                       case "8":
+                                               if (!fallbackBitrate) return callback(null, new Error("Song not found at desired bitrate."))
+                                       default:
                                                format = 8;
                                }
                                json.format = format;
@@ -289,7 +344,7 @@ Deezer.prototype.search = function(text, type, callback) {
                type += "?";
        }
 
-       request.get({url: "https://api.deezer.com/search/" + type + "q=" + text, headers: this.httpHeaders, jar: true}, function(err, res, body) {
+       request.get({url: "https://api.deezer.com/search/" + type + "q=" + text, strictSSL: false, headers: this.httpHeaders, jar: true}, function(err, res, body) {
                if(!err && res.statusCode == 200) {
                        var json = JSON.parse(body);
                        if(json.error) {
@@ -309,7 +364,7 @@ Deezer.prototype.track2ID = function(artist, track, album, callback, trim=false)
        track = track.replace(/–/g,"-").replace(/’/g, "'");
        if (album) album = album.replace(/–/g,"-").replace(/’/g, "'");
        if (album){
-               request.get({url: 'https://api.deezer.com/search/?q=track:"'+encodeURIComponent(track)+'" artist:"'+encodeURIComponent(artist)+'" album:"'+encodeURIComponent(album)+'"&limit=1&strict=on', headers: this.httpHeaders, jar: true}, function(err, res, body) {
+               request.get({url: 'https://api.deezer.com/search/?q=track:"'+encodeURIComponent(track)+'" artist:"'+encodeURIComponent(artist)+'" album:"'+encodeURIComponent(album)+'"&limit=1&strict=on', strictSSL: false, headers: this.httpHeaders, jar: true}, function(err, res, body) {
                        if(!err && res.statusCode == 200) {
                                var json = JSON.parse(body);
                                if(json.error) {
@@ -347,7 +402,7 @@ Deezer.prototype.track2ID = function(artist, track, album, callback, trim=false)
                        }
                });
        }else{
-               request.get({url: 'https://api.deezer.com/search/?q=track:"'+encodeURIComponent(track)+'" artist:"'+encodeURIComponent(artist)+'"&limit=1&strict=on', headers: this.httpHeaders, jar: true}, function(err, res, body) {
+               request.get({url: 'https://api.deezer.com/search/?q=track:"'+encodeURIComponent(track)+'" artist:"'+encodeURIComponent(artist)+'"&limit=1&strict=on', strictSSL: false, headers: this.httpHeaders, jar: true}, function(err, res, body) {
                        if(!err && res.statusCode == 200) {
                                var json = JSON.parse(body);
                                if(json.error) {
@@ -392,7 +447,7 @@ Deezer.prototype.track2ID = function(artist, track, album, callback, trim=false)
 Deezer.prototype.hasTrackAlternative = function(id, callback) {
        var scopedid = id;
        var self = this;
-       request.get({url: "https://www.deezer.com/track/"+id, headers: this.httpHeaders, jar: true}, (function(err, res, body) {
+       request.get({url: "https://www.deezer.com/track/"+id,strictSSL: false, headers: this.httpHeaders, jar: true}, (function(err, res, body) {
                var regex = new RegExp(/<script>window\.__DZR_APP_STATE__ = (.*)<\/script>/g);
                var rexec = regex.exec(body);
                var _data;
@@ -431,7 +486,7 @@ Deezer.prototype.decryptTrack = function(writePath, track, queueId, callback) {
        if (self.delStream.indexOf(queueId) == -1){
                if (typeof self.reqStream[queueId] != "object") self.reqStream[queueId] = [];
                self.reqStream[queueId].push(
-                       request.get({url: track.downloadUrl, headers: self.httpHeaders, encoding: 'binary'}, function(err, res, body) {
+                       request.get({url: track.downloadUrl,strictSSL: false, headers: self.httpHeaders, encoding: 'binary'}, function(err, res, body) {
                                if(!err && res.statusCode == 200) {
                                        var decryptedSource = decryptDownload(new Buffer(body, 'binary'), track);
                                        fs.outputFile(writePath,decryptedSource,function(err){
@@ -532,6 +587,7 @@ Deezer.prototype.getToken = async function(){
        const res = await request.get({
                url: this.apiUrl,
                headers: this.httpHeaders,
+               strictSSL: false,
                qs: {
                        api_version: "1.0",
                        api_token: "null",
@@ -545,7 +601,7 @@ Deezer.prototype.getToken = async function(){
 }
 
 function getJSON(url, callback){
-       request.get({url: url, headers: this.httpHeaders, jar: true, json: true}, function(err, res, body) {
+       request.get({url: url, headers: this.httpHeaders, strictSSL: false, jar: true, json: true}, function(err, res, body) {
                if(err || res.statusCode != 200 || !body) {
                        callback(null, new Error("Unable to initialize Deezer API"));
                } else {
index 0f45da0d7f7c7ba29571639b997fae2dc2327187..9a16866e6e13c2631205c77654f305762c979db8 100644 (file)
                "multitagSeparator": ";",
                "maxBitrate": "3",
                "PNGcovers": false,
+               "removeAlbumVersion": false,
+               "dateFormat": "0",
+               "dateFormatYear": "4",
+               "fallbackBitrate": true,
                "tags": {
                        "title": true,
                        "artist": true,
index 5edfca2320ef81ed46bd2c0b4a9f8f2b01cf6bb8..3baa13a602a53249ece7b344ebe8003caf55093e 100644 (file)
@@ -1,7 +1,7 @@
 {
        "name": "deezloader-rmx",
        "productName": "Deezloader Remix",
-       "version": "4.1.2",
+       "version": "4.1.3",
        "description": "Download music from Deezer",
        "main": "main.js",
        "author": "RemixDevs",
index 9283371be46a54b1c388055df52b01f1c0649645..3a3e55a20646cea795c42cc6db43802b2d80c4af 100644 (file)
@@ -16,7 +16,7 @@
   <meta charset="utf-8"/>
 </head>
 <body>
-<span id="appVersionFallback" hidden>4.1.2</span>
+<span id="appVersionFallback" hidden>4.1.3</span>
 
 <div id="title-bar" class="deezloader-black">
        <div class="resize-padding" style="width: 100%; height: 3px;"></div>
                                <i class="material-icons prefix">label</i>
                                <input type="text" id="modal_settings_input_trackNameTemplate"/>
                                <label for="modal_settings_input_trackNameTemplate">Track names <i class="material-icons valignicon tiny tooltipped" data-position="right" data-delay="50"
-          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album% and %label%">info_outline</i></label>
+          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album%, %explicit% and %label%">info_outline</i></label>
                        </div>
                        <div class="input-field col s12 m6">
                                <i class="material-icons prefix">label</i>
                                <input type="text" id="modal_settings_input_playlistTrackNameTemplate"/>
                                <label for="modal_settings_input_playlistTrackNameTemplate">Playlist track names <i class="material-icons valignicon tiny tooltipped" data-position="right" data-delay="50"
-          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album% and %label%">info_outline</i></label>
+          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album%, %explicit% and %label%">info_outline</i></label>
                        </div>
                </div>
     <div class="row">
                                <i class="material-icons prefix">label</i>
                                <input type="text" id="modal_settings_input_albumTrackNameTemplate"/>
                                <label for="modal_settings_input_albumTrackNameTemplate">Album track names <i class="material-icons valignicon tiny tooltipped" data-position="right" data-delay="50"
-          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album% and %label%">info_outline</i></label>
+          data-tooltip="Supported variables are: %number%, %year%, %artist%, %title%, %album%, %explicit% and %label%">info_outline</i></label>
                        </div>
                        <div class="input-field col s12 m6">
                                <i class="material-icons prefix">label</i>
                                <input type="text" id="modal_settings_input_albumNameTemplate"/>
                                <label for="modal_settings_input_albumNameTemplate">Album names <i class="material-icons valignicon tiny tooltipped" data-position="right" data-delay="50"
-          data-tooltip="Supported variables are: %year%, %artist%, %type%, %album% and %label%">info_outline</i></label>
+          data-tooltip="Supported variables are: %year%, %artist%, %type%, %album%, %explicit% and %label%">info_outline</i></label>
                        </div>
                </div>
     <div class="row">
                                <i class="material-icons prefix">label</i>
                                <select name="multitagSeparator" id="modal_settings_select_multitagSeparator">
                                        <option value="null">Null Character</option>
-                                       <option value=", ">,</option>
+          <option value=",">,</option>
+          <option value=", ">, with space</option>
                                        <option value="/">/</option>
+          <option value=" / ">/ with space</option>
                                        <option value=";">;</option>
+          <option value="; ">; with space</option>
                                </select>
                                <label for="modal_settings_select_multitagSeparator">Multitag Separator</label>
                        </div>
                </div>
+    <div class="row">
+                       <div class="input-field col s12 m6">
+                               <i class="material-icons prefix">label</i>
+                               <select name="dateFormat" id="modal_settings_select_dateFormat">
+          <option value="0">YMD</option>
+                                       <option value="1">DMY</option>
+                                       <option value="2">MDY</option>
+          <option value="3">YDM</option>
+                               </select>
+                               <label for="modal_settings_select_dateFormat">Date Format</label>
+                       </div>
+      <div class="input-field col s12 m6">
+                               <i class="material-icons prefix">label</i>
+                               <select name="dateFormatYear" id="modal_settings_select_dateFormatYear">
+          <option value="2">2</option>
+                                       <option value="4">4</option>
+                               </select>
+                               <label for="modal_settings_select_dateFormatYear">Number of digits for the year (only in date tag)</label>
+                       </div>
+               </div>
                <div class="row">
                        <div class="input-field col s12">
                                <i class="material-icons prefix">label</i>
         <label>
                                <input type="checkbox" id="modal_settings_cbox_PNGcovers" class="filled-in"/>
                                <span>Download images as PNGs</span>
+        </label>
+                       </p>
+      <p class="col s12 m4">
+        <label>
+                               <input type="checkbox" id="modal_settings_cbox_removeAlbumVersion" class="filled-in"/>
+                               <span>Remove "(Album Version)" from track title</span>
+        </label>
+                       </p>
+      <p class="col s12 m4">
+        <label>
+                               <input type="checkbox" id="modal_settings_cbox_fallbackBitrate" class="filled-in"/>
+                               <span>Fallback to lower bitrates</span>
         </label>
                        </p>
                </div>
           <div class="collapsible-header waves-effect"><i class="material-icons">group</i>Contacts</div>
           <div class="collapsible-body">
             <p>
-              If you want to talk about the app and help you can do that in this <a href="https://t.me/joinchat/BJf2dUoyFbTi9HLUp0SWkw">Telegram Group</a>!
+              If you want to talk about the app and help you can do that in this <a href="https://t.me/joinchat/BJf2dUoyFbSZFV-kQIe_LQ">Telegram Group</a>!
             </p>
           </div>
         </li>
                                        <div class="collapsible-header waves-effect"><i class="material-icons">history</i>Changelog</div>
                                        <div class="collapsible-body">
                                                <p>
-                         <b>Version 4.1.2</b><br/>
-                         - Fixed Login Problem (for real this time)<br/>
-                         - Fixed Login after refresh<br/>
-                         - Regionlock free download<br/>
-                         - Added support for download of User Uploaded tracks<br/>
-                         - Now you can select which tags your songs has<br/>
-                         - Fixed selecting problem<br/>
-                         - Tracks without preview will display a disabled play button<br/>
-                         - Previews inside modal will stop with modal close<br/>
-                         - New %label% field for tracks and albums<br/>
-                         - Added option to create folder for CDs<br/>
-                         - Added rename option for cover file<br/>
-                         - Added option to download Artist artwork<br/>
-                         - Added option do log downloaded alternative tracks<br/>
-                         - Fixed some minor bugs
-                         <br/>
+              <b>Version 4.1.3</b><br/>
+              - Playlist and Album tracks now have fallback support<br/>
+              - M3U files now works correctly<br/>
+              - Fixed problems with tags<br/>
+              - Added option %explicit% for Track and Album names (Will add "(Explicit)" in that position if it's explicit)<br/>
+              - Added option to remove "(Album Version)" from track title<br/>
+              - Added options to select which format should the date tag have<br/>
+              - Added option to not fallback if desired bitrate is not aviable<br/>
+              - Logging enhancements<br/>
+              - Other minor bug-fixing<br/>
+              <br/>
+                         <b>Version 4.1.2</b><br/>
+                         - Fixed Login Problem (for real this time)<br/>
+                         - Fixed Login after refresh<br/>
+                         - Regionlock free download<br/>
+                         - Added support for download of User Uploaded tracks<br/>
+                         - Now you can select which tags your songs has<br/>
+                         - Fixed selecting problem<br/>
+                         - Tracks without preview will display a disabled play button<br/>
+                         - Previews inside modal will stop with modal close<br/>
+                         - New %label% field for tracks and albums<br/>
+                         - Added option to create folder for CDs<br/>
+                         - Added rename option for cover file<br/>
+                         - Added option to download Artist artwork<br/>
+                         - Added option do log downloaded alternative tracks<br/>
+                         - Fixed some minor bugs
+                         <br/>
               <b>Version 4.1.1</b><br/>
               - Fixed Login Problem (again)<br/>
               - Added Dark Mode<br/>
                                <li>
                                        <div class="collapsible-header waves-effect"><i class="material-icons">build</i>Contributors</div>
                                        <div class="collapsible-body">
-                                               <p>Thanks to the following contributors for fixing bugs and improving this application. <br> <br>
+                                               <p>Thanks to the following contributors for fixing bugs and improving this application.<br>
+              <br>
                                                        <a href="https://www.reddit.com/user/Blind-Mute">Blind-Mute</a> <br>
                                                        <a href="https://gitlab.com/Persei08">Persei08</a> <br>
                                                        <a href="https://github.com/Uukrull">Uukrull</a> <br>
index dd4477e7dcc84ba5310222a5dd05df831b3ad145..22f30d0202f239a7f386d7ac8ba99c39fea18615 100644 (file)
@@ -24,7 +24,6 @@ $('#modal_login_btn_login').click(function () {
        var username = $('#modal_login_input_username').val();
        var password = $('#modal_login_input_password').val();
        var autologin = $('#modal_login_input_autologin').prop("checked");
-       Username = username;
        //Send to the software
        socket.emit('login', username, password,autologin);
 });
@@ -34,7 +33,6 @@ socket.on("autologin",function(username,password){
        $('#modal_login_btn_login').attr("disabled", true);
        $('#modal_login_btn_login').html("Logging in...");
        $('#modal_login_input_username').val(username);
-       Username = username;
        $('#modal_login_input_password').val(password);
        M.updateTextFields();
        socket.emit('login', username, password,false);
@@ -46,7 +44,7 @@ socket.on("login", function (data) {
                $("#modal_settings_picture").attr("src",data.picture);
                $("#side_user").text(data.username);
                $("#side_avatar").attr("src",data.picture);
-               $("#side_email").text(Username);
+               $("#side_email").text(data.email);
                $('#initializing').addClass('animated fadeOut').on('webkitAnimationEnd', function () {
                        $(this).css('display', 'none');
                        $(this).removeClass('animated fadeOut');
@@ -226,6 +224,10 @@ $('#modal_settings_btn_saveSettings').click(function () {
                multitagSeparator: $('#modal_settings_select_multitagSeparator').val(),
                maxBitrate: $('#modal_settings_select_maxBitrate').val(),
                PNGcovers: $('#modal_settings_cbox_PNGcovers').is(':checked'),
+               removeAlbumVersion : $('#modal_settings_cbox_removeAlbumVersion').is(':checked'),
+               dateFormat: $('#modal_settings_select_dateFormat').val(),
+               dateFormatYear: $('#modal_settings_select_dateFormatYear').val(),
+               fallbackBitrate : $('#modal_settings_cbox_fallbackBitrate').is(':checked'),
                tags: {
                        title: $('#modal_tags_title').is(':checked'),
                        artist: $('#modal_tags_artist').is(':checked'),
@@ -318,6 +320,11 @@ function fillSettingsModal(settings) {
        $('#modal_settings_select_multitagSeparator').val(settings.multitagSeparator).formSelect();
        $('#modal_settings_select_maxBitrate').val(settings.maxBitrate).formSelect();
        $('#modal_settings_cbox_PNGcovers').prop('checked', settings.PNGcovers);
+       $('#modal_settings_cbox_removeAlbumVersion').prop('checked', settings.removeAlbumVersion);
+       $('#modal_settings_select_dateFormat').val(settings.dateFormat).formSelect();
+       $('#modal_settings_select_dateFormatYear').val(settings.dateFormatYear).formSelect();
+       $('#modal_settings_cbox_fallbackBitrate').prop('checked', settings.fallbackBitrate);
+
        $('#modal_tags_title').prop('checked', settings.tags.title);
        $('#modal_tags_artist').prop('checked', settings.tags.artist);
        $('#modal_tags_album').prop('checked', settings.tags.album);
@@ -735,7 +742,7 @@ socket.on("getChartsTrackListByCountry", function (data) {
                                `<tr>
                                <td>${(i + 1)}</td>
                                <td><a href="#" class="circle ${(currentChartTrack.preview ? `single-cover" preview="${currentChartTrack.preview}"><i class="material-icons preview_controls white-text">play_arrow</i>` : '">')}<img style="width:56px" src="${(currentChartTrack.album.cover_small ? currentChartTrack.album.cover_small : "img/noCover.jpg")}" class="circle" /></a></td>
-                               <td>${currentChartTrack.title}</td>
+                               <td>${(currentChartTrack.explicit_lyrics ? '<i class="material-icons valignicon tiny materialize-red-text tooltipped" data-tooltip="Explicit">error_outline</i> ' : '')}${currentChartTrack.title}</td>
                                <td>${currentChartTrack.artist.name}</td>
                                <td>${currentChartTrack.album.title}</td>
                                <td>${convertDuration(currentChartTrack.duration)}</td>
@@ -775,10 +782,8 @@ $('#tab_url_form_url').submit(function (ev) {
 
        ev.preventDefault();
        var urls = $("#song_url").val().split(";");
-       console.log(urls);
        for(var i = 0; i < urls.length; i++){
                var url = urls[i];
-               console.log(url);
                if (url.length == 0) {
                        message('Blank URL Field', 'You need to insert an URL to download it!');
                        return false;
@@ -804,7 +809,6 @@ $('#tab_url_form_url').submit(function (ev) {
 //############################################TAB_DOWNLOADS###########################################\\
 function addToQueue(url) {
        var type = getTypeFromLink(url), id = getIDFromLink(url);
-       console.log(type, id)
        if (type == 'spotifyplaylist'){
                [user, id] = getPlayUserFromURI(url)
                userSettings.currentSpotifyUser = user;
index d31cca40ac93b967825b22ed89cca3bfa791e112..e285a9448aa86d9822ae44efddc4ca3be2fa1a44 100644 (file)
@@ -1,3 +1,3 @@
 echo Starting to compile.
 echo The software will be compiled to /dist folder
-npm install && npm run dist -l
\ No newline at end of file
+npm install && npm run dist:linux
\ No newline at end of file
index 56a601f2f4321e53b5d59e527a18d05302c5ca68..30406450a8c09a54a6f0ba99c24de83160bb5de1 100644 (file)
@@ -1,3 +1,3 @@
 echo Starting to compile.
 echo The software will be compiled to /dist folder
-npm install && npm run dist -m
\ No newline at end of file
+npm install && npm run dist:macOS
\ No newline at end of file
diff --git a/compileWindows.bat b/compileWindows.bat
deleted file mode 100644 (file)
index 7895daf..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-@echo off
-@echo Starting to compile.
-@echo The software will be compiled to /dist folder
-
-:: Starting to compile
-npm install && npm run dist -w
-pause
diff --git a/compileWindows32.bat b/compileWindows32.bat
new file mode 100644 (file)
index 0000000..9e9ecb9
--- /dev/null
@@ -0,0 +1,7 @@
+@echo off
+@echo Starting to compile.
+@echo The software will be compiled to /dist folder
+
+:: Starting to compile
+npm install && npm run dist:win32
+pause
diff --git a/compileWindows64.bat b/compileWindows64.bat
new file mode 100644 (file)
index 0000000..0ccec91
--- /dev/null
@@ -0,0 +1,7 @@
+@echo off
+@echo Starting to compile.
+@echo The software will be compiled to /dist folder
+
+:: Starting to compile
+npm install && npm run dist:win64
+pause
index 34c2f94d2cc3567f312a772228b76915770bc096..51b9a940a5fbe1f8ef52942b16fb774205838b27 100644 (file)
                "electron-builder": "latest"
        },
        "scripts": {
-               "dist": "electron-builder",
+               "dist:win32": "electron-builder -w --ia32 --config.nsis.artifactName=\"${productName} ${version} Setup-x32.${ext}\" --config.portable.artifactName=\"${productName} ${version} x32.${ext}\"",
+               "dist:win64": "electron-builder -w --x64",
+               "dist:linux": "electron-builder -l",
+               "dist:macOS": "electron-builder -m",
                "pack": "electron-builder --dir",
                "start": "cross-env NODE_ENV=development electron ./app",
                "postinstall": "electron-builder install-app-deps"
                },
                "win": {
                        "target": [
-                               {
-                                       "target": "nsis",
-                                       "arch": [
-                                               "x64",
-                                               "ia32"
-                                       ]
-                               },
-                               {
-                                       "target": "portable",
-                                       "arch": [
-                                               "x64",
-                                               "ia32"
-                                       ]
-                               }
+                               "nsis",
+                               "portable"
                        ]
                },
                "nsis": {
-                       "artifactName": "${productName} ${version} Setup.${ext}",
+                       "artifactName": "${productName} ${version} Setup.${ext}",
                        "oneClick": false,
                        "license": "LICENSE",
                        "allowToChangeInstallationDirectory": true,
@@ -63,7 +54,7 @@
                        "deleteAppDataOnUninstall": true
                },
                "portable": {
-                       "artifactName": "${productName} ${version} - Portable.${ext}",
+                       "artifactName": "${productName} ${version}.${ext}",
                        "requestExecutionLevel": "user"
                }
        }