const http = require("http"); var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; var { DOMParser} = require("xmldom"); const serverurl = 'https://vtuner.com/setupapp/guide/asp/'; const statics = [ {prefix: "/setupapp/denon/asp/BrowseXML/loginXML.asp",response:"123456789abcdef0"}, {prefix: "/setupapp/denon/asp/browsexm2/loginXML.asp",response:"-1"+ "DirGenre"+ "http://denon.vtuner.com/setupapp/BrowseStations/StartPage.asp?sBrowseType=Format"+ "DirLocation"+ "http://denon.vtuner.com/setupapp/BrowseStations/StartPage.asp?sBrowseType=Location"+ "DirLanguage"+ "http://denon.vtuner.com/setupapp/BrowseStations/StartPage.asp?sBrowseType=Language"+ "DirNederland"+ "http://denon.vtuner.com/setupapp/BrowseStations/BrowsePremiumStations.asp?sCategory=Netherlands&sBrowseType=Location"+ "DirNederlands"+ "http://denon.vtuner.com/setupapp/BrowseStations/StartPage.asp?sCategory=dut&sBrowseType=Language&sNiceLang=Dutchi"+ ""}, {prefix: "/setupapp/BrowseStations/StartPage.asp", responsefunc:(url, res1) => { BrowseGenres(url, res1);}}, {prefix: "/setupapp/BrowseStations/BrowsePremiumStations.asp", responsefunc:(url, res1) => { BrowseStations(url, res1);}}, {prefix: "/setupapp/BrowseStations/dynampls.asp", responsefunc:(url, res1) => {GetStation(url, res1);}} ]; const server = http.createServer((req, res) => { let url = new URL("http://localhost"+req.url); console.log("received "+url.pathname + " and query "+url.search); var match = statics.filter((element) => {console.log(element); console.log(element.prefix); return (url.pathname.indexOf(element.prefix) === 0);} ); console.log("match "+match); console.log("match "+match.length); if (match.length > 0) { console.log("match found"); if (match[0].response !== undefined) { console.log("Const response"); res.end(match[0].response); } else { console.log( "function response"); match[0].responsefunc(url, res); } } }); server.listen(3000, "localhost", () => { console.log("Listening for request"); }); function getWebpage(url, callback) { var webpage; let httpreq =new XMLHttpRequest(); httpreq.open("GET", url, false); httpreq.responseType = "document"; httpreq.send(); return httpreq.responseText; } function fixHtmlErrors(text) { text = text.replace(//g, ''); text = text.replace(//g, ''); text = text.replace(//g, ''); text = text.replace(//g, ''); return text; } function getGenre(queryparams) { const vtunerurl=serverurl + "BrowseStations/StartPage.asp"+ queryparams; let response = getWebpage(vtunerurl); var result = []; response = fixHtmlErrors(response); const doc = new DOMParser().parseFromString(response,'text/html'); const links = doc.getElementsByTagName('td'); for (let i = 0; i < links.length; i++) { if (links[i].getAttribute('class') !== 'links') { continue; } const anchors = links[i].getElementsByTagName('a'); for (let j=0; j { const nameA = a.name.toUpperCase(); // ignore upper and lowercase const nameB = b.name.toUpperCase(); // ignore upper and lowercase if (nameA < nameB) { return -1; } if (nameA > nameB) { return 1; } // names must be equal return 0; }); const pagelinks = doc.getElementsByTagName('a'); for (let i=0; i< pagelinks.length; i++) { if (pagelinks[i].getAttribute('class') !== 'paging') { continue; } result.push({link: pagelinks.getAttribute('href'), name: "page "+link.firstChild.data, type: 'Dir'}); } return result; } function getStationList(vtunerurl) { let response = getWebpage(vtunerurl); var result = []; response = fixHtmlErrors(response); const doc = new DOMParser().parseFromString(response,'text/html'); const table = doc.getElementById('table2'); if (table === undefined || table == null) { console.log("Cannot find table2 in page "+vtunerurl); console.log(response); exit; } console.log("isolated table"); const links = table.getElementsByTagName('td'); console.log("selected "+links.length+" table cells"); for (let i = 0; i < links.length; i++) { if (links[i].getAttribute('class') !== 'links') { console.log('table cell #'+i+" is not class 'links', skipping"); continue; } const anchors = links[i].childNodes; console.log("table cell #"+i+" of class links has "+anchors.length+" anchors inside"); for (let j=0; j= 0) { continue; } result.push({link: hrefAttr, name: name, type: 'Station'}); console.log(result[result.length-1]); } } const pagelinks = doc.getElementsByTagName('a'); for (let i=0; i< pagelinks.length; i++) { var link = pagelinks[i]; if (link.getAttribute('class') !== 'paging') { continue; } console.log(link.attributes); result.push({link:link.getAttribute('HREF'), name: "page "+link.firstChild.firstChild.data, type: 'Dir'}); } return result; } function getStationRedirect(vtunerurl) { let response = getWebpage(vtunerurl); response = fixHtmlErrors(response); const doc = new DOMParser().parseFromString(response,'text/html'); const audioElements = doc.getElementsByTagName('audio'); console.log("selected "+audioElements.length+" audio elements"); for (let i = 0; i < audioElements.length; i++) { var srcAttr = link.getAttribute('src'); if (srcAttr == undefined || srcAttr == '' ) continue; console.log(srcAttr); return(srcAttr); } const scripts = doc.getElementsByTagName('script'); console.log("selected "+scripts.length+" script elements"); for (let i=0; i" + listentry.name+ ""+ ""+listentry.link+""; } else if (listentry.type == 'Station') { listentry.link = listentry.link.replace('../', serverurl); response += 'Station'+ "" + i+ ""+ "" + listentry.name+ ""+ ""+listentry.link+""; } return response; } function BrowseGenres(url, res2) { let list = getGenre(url.search); const header = "-1"; var body = ""; const footer = ""; for (let i=0; i< list.length; i++) { var entry = EntryToItem(i, list[i]); console.log(entry); body += entry; } res2.end(header + body + footer); } function BrowseStations(url, res) { //example: /setupapp/BrowseStations/BrowsePremiumStations.asp and query ?sCategory=Alternative&sBrowseType=Format&sNiceLOFO=Alternative&fver=1.754333&dlang=dut&startitems=1&enditems=10 if (url.pathname.indexOf('/setupapp/') != 0) { console.log ('unexpected base'); }; var pathname = url.pathname.replace('/setupapp/', '/'); var search= url.search.replace(/&mac=[\w\d]*&/, '&'); console.log('search '+url.search+' w/o mac: '+ search); let list = getStationList(serverurl + pathname + search); const header = "-1"; var body = ""; const footer = ""; for (let i=0; i< list.length; i++) { var entry = EntryToItem(i, list[i]); console.log(entry); body += entry; } res.end(header + body + footer); } function GetStation(url, res) { //example: /setupapp/BrowseStations/dynampls.asp?id=45518&k=c104fb13bec928a3e3cd0905e363be8097586d4657ba8ff55e852d0ddb815f7f if (url.pathname.indexOf('/setupapp/') != 0) { console.log ('unexpected base'); }; var pathname = url.pathname.replace('/setupapp/', '/'); let redirect = getStationRedirect(serverurl + pathname + url.search); var pathname = url.pathname.replace('/setupapp/', '/'); res.writeHead(302, { "location":redirect} ); res.end(); }