const Cheerio = require('cheerio'); const { promises: fs } = require('fs'); const debug = require('debug')('vk-music-dl'); const vm = require('vm'); const Request = require('request-promise'); const Promise = require('bluebird'); const _ = require('lodash'); const leven = require('leven'); require('dotenv').config(); async function getSpotifyPlaylist(){ const spotifyPlaylistPageContent = await fs.readFile('./test.html'); const $ = Cheerio.load(spotifyPlaylistPageContent); let playlist; $('script').each(function(i, elem){ const content = $(this).html(); if(/Spotify.Entity/.test(content)){ playlist = vm.runInNewContext(content); } }); return playlist; } async function searchOnVkMusic(query){ return await Request({ uri: 'https://api.vk.com/method/audio.search', qs: { v: '5.71', access_token: process.env.ACCESS_TOKEN, q: query, //sort: '2', count: 200, }, headers: { 'User-Agent': 'KateMobileAndroid/48.2 lite-433 (Android 8.1.0; SDK 27; arm64-v8a; Google Pixel 2 XL; en)', }, json: true }); } function matchScore(spotifyMetas, vkmusicMetas){ const originalArtistNames = _.map(spotifyMetas.artists, 'name').join(', ').toLowerCase(); const originalTitle = spotifyMetas.name.toLowerCase(); const originalDuration = Math.round(spotifyMetas.duration_ms/1000); const matchArtistScore = 1 - (leven(originalArtistNames, vkmusicMetas.artist.toLowerCase()) / Math.max(originalArtistNames.length, vkmusicMetas.artist.length)); const matchTitleScore = 1 - (leven(originalTitle, vkmusicMetas.title.toLowerCase()) / Math.max(originalTitle.length, vkmusicMetas.title.length)); const matchDurationScore = 1 - (Math.abs(originalDuration - vkmusicMetas.duration) / originalDuration); debug('matchArtistScore=%f matchTitleScore=%f matchDurationScore=%f', matchArtistScore, matchTitleScore, matchDurationScore); return matchArtistScore + matchTitleScore + matchDurationScore; } async function main(i = 0){ const playlist = await getSpotifyPlaylist(); await Promise.map([playlist.tracks.items[i]], async ({track}) => { const artistNames = _.map(track.artists, 'name').join(', '); debug('%s - %s', track.name, artistNames); const { response } = await searchOnVkMusic(`${artistNames} ${track.name}`); debug('response=%O', response); const bestMatch = _.chain(response.items).map((item) => { item.score = matchScore(track, item); return item; }).sortBy('score').last().value(); debug(bestMatch); }); // best match for Love Is a Bitch id:456240390 //const results = await searchOnVkMusic('Two Feet Love Is a Bitch'); //debug(await searchOnVkMusic('The Neighbourhood Daddy Issues')); } main(parseInt(process.argv[2]));