Warning, /multimedia/kid3/src/qml/script/EmbedLyrics.qml is written in an unsupported language. File is not indexed.

0001 /**
0002  * \file EmbedLyrics.qml
0003  * Fetch unsynchronised lyrics from web service.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 09 Mar 2015
0008  *
0009  * Copyright (C) 2015-2017  Urs Fleisch
0010  *
0011  * This program is free software; you can redistribute it and/or modify
0012  * it under the terms of the GNU Lesser General Public License as published by
0013  * the Free Software Foundation; version 3.
0014  *
0015  * This program is distributed in the hope that it will be useful,
0016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0018  * GNU Lesser General Public License for more details.
0019  *
0020  * You should have received a copy of the GNU Lesser General Public License
0021  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0022  */
0023 
0024 import Kid3 1.1
0025 
0026 Kid3Script {
0027   onRun: {
0028     function replaceHtmlEntities(str) {
0029       str = str.replace(/<br[ \/]*>/gmi, "\n")
0030       str = str.replace(/\s*<\/p>\s*<p>\s*/gmi, "\n")
0031       str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, "")
0032       str = str.replace(/&#\d+;/gm, function(s) {
0033         return String.fromCharCode(parseInt(s.substring(
0034           2, s.length - 1)))
0035       })
0036       return str
0037     }
0038 
0039     var lyricFetchers = {
0040       "makeitpersonal": {
0041         getUrl: function(artist, title) {
0042           return "https://makeitpersonal.co/lyrics?artist=%1&title=%2".
0043                    arg(artist).arg(title)
0044         },
0045         parseResponse: function(resp) {
0046           return (resp && resp.substring(0, 5) !== "Sorry") ? resp : ""
0047         }
0048       },
0049       "lyrics.wikia.com": {
0050         getUrl: function(artist, title) {
0051           return "https://lyrics.wikia.com/wiki/" + encodeURIComponent(artist) +
0052                    ":" + encodeURIComponent(title)
0053         },
0054         parseResponse: function(resp) {
0055           var begin = resp.indexOf("<div class='lyricbox'>")
0056           if (begin !== -1) {
0057             begin += 22
0058             var end = resp.indexOf("<!--", begin)
0059             var txt = resp.substring(begin, end)
0060             if (txt.substring(0, 2) === "&#") {
0061               txt = replaceHtmlEntities(txt)
0062               return txt
0063             }
0064           }
0065           return ""
0066         }
0067       },
0068       "www.letras.com": {
0069         getUrl: function(artist, title) {
0070           return "https://www.letras.com/" + encodeURIComponent(artist) +
0071                    "/" + encodeURIComponent(title)
0072         },
0073         parseResponse: function(resp) {
0074           var begin = resp.indexOf('<div class="cnt-letra">')
0075           if (begin !== -1) {
0076             begin += 23
0077             var end = resp.indexOf("</div>", begin)
0078             var txt = resp.substring(begin, end).trim()
0079             if (txt.substring(0, 3) === "<p>") {
0080               txt = replaceHtmlEntities(txt)
0081               return txt
0082             }
0083           }
0084           return ""
0085         }
0086       }
0087     }
0088     var usedFetchers = ["www.letras.com"]
0089     var currentFetcherIdx = 0
0090 
0091     function toNextFile() {
0092       if (!nextFile()) {
0093         if (isStandalone()) {
0094           // Save the changes if the script is started stand-alone, not from Kid3.
0095           app.saveDirectory()
0096         }
0097         Qt.quit()
0098       } else {
0099         currentFetcherIdx = 0
0100         setTimeout(doWork, 1)
0101       }
0102     }
0103 
0104     function toNextFetcher() {
0105       if (++currentFetcherIdx < usedFetchers.length) {
0106         setTimeout(doWork, 1)
0107       } else {
0108         toNextFile()
0109       }
0110     }
0111 
0112     function doWork() {
0113       if (app.selectionInfo.tag(Frame.Tag_2).tagFormat ||
0114           app.selectionInfo.tag(Frame.Tag_1).tagFormat) {
0115         var artist = app.getFrame(tagv2, "artist") || app.getFrame(tagv1, "artist")
0116         var title = app.getFrame(tagv2, "title") || app.getFrame(tagv1, "title")
0117         var doc = new XMLHttpRequest();
0118         var name = usedFetchers[currentFetcherIdx]
0119         var fetcher = lyricFetchers[name]
0120         doc.onreadystatechange = function() {
0121           if (doc.readyState === XMLHttpRequest.DONE) {
0122             if (doc.status === 200) {
0123               var txt = doc.responseText.trim()
0124               txt = fetcher.parseResponse(txt)
0125               if (txt) {
0126                 app.setFrame(tagv2, "lyrics", txt)
0127                 console.log("Set lyrics for %1 - %2 from %3".
0128                             arg(artist).arg(title).arg(name))
0129                 toNextFile()
0130               } else {
0131                 console.log("No lyrics for %1 - %2 from %3".
0132                             arg(artist).arg(title).arg(name))
0133                 toNextFetcher()
0134               }
0135             } else {
0136               console.log("Request failed for %1 - %2 from %3".
0137                           arg(artist).arg(title).arg(name))
0138               toNextFetcher()
0139             }
0140           }
0141         }
0142 
0143         doc.open("GET", fetcher.getUrl(artist, title))
0144         doc.send()
0145       } else {
0146         toNextFile()
0147       }
0148     }
0149 
0150     firstFile()
0151     doWork()
0152   }
0153 }