diff --git a/README.md b/README.md index db2fde9..3fe9861 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,16 @@ -# RapGenius-JS [![Build Status](https://travis-ci.org/kenshiro-o/RapGenius-JS.png?branch=master)](https://travis-ci.org/kenshiro-o/RapGenius-JS) +# Genius-JS [![Build Status](https://travis-ci.org/kenshiro-o/RapGenius-JS.png?branch=master)](https://travis-ci.org/kenshiro-o/RapGenius-JS) - rapgenius-js is a simple client that enables you to query RapGenius(www.rapgenius.com) and retrieve -information about rap and rock artists and songs. + Genius-js is a simple client that enables you to query Genius(www.genius.com) and retrieve +information about rap and rock artists and songs. This project has been forked from kenshiro-o's RapGenius-JS and altered to support all areas of Genius rather than just Rap and Rock genius. ## Rationale - This project was created because RapGenius does currently not support a Node.js API. + This project was created because Genius does currently not support a Node.js API. ## Installation ```bash -$ npm install rapgenius-js +$ npm install genius-js ``` ## Usage @@ -54,36 +54,26 @@ $ npm install rapgenius-js ### Search for an artist: ```js -var rapgeniusClient = require("rapgenius-js"); +var geniusClient = require("genius-js"); -rapgeniusClient.searchArtist("GZA", "rap", function(err, artist){ +rapgeniusClient.searchArtist("GZA", function(err, artist){ if(err){ console.log("Error: " + err); }else{ - console.log("Rap artist found [name=%s, link=%s, popular-songs=%d]", + console.log("Artist found [name=%s, link=%s, popular-songs=%d]", artist.name, artist.link, artist.popularSongs.length); } }); -//Example for a rock artist -rapgeniusClient.searchArtist("Bruce Springsteen", "rock", function(err, artist){ - if(err){ - console.log("Error: " + err); - }else{ - console.log("Rap artist found [name=%s, link=%s, popular-songs=%d]", - artist.name, artist.link, artist.popularSongs.length); - - } -}); ``` ### Search for a song: ```js -var rapgeniusClient = require("rapgenius-js"); +var geniusClient = require("genius-js"); -rapgeniusClient.searchSong("Liquid Swords", "rap", function(err, songs){ +geniusClient.searchSong("Liquid Swords", "GZA", function(err, songs){ if(err){ console.log("Error: " + err); }else{ @@ -96,7 +86,7 @@ rapgeniusClient.searchSong("Liquid Swords", "rap", function(err, songs){ ### Search for the lyrics of a song along with their meaning: ```js -var rapgeniusClient = require("rapgenius-js"); +var geniusClient = require("genius-js"); var lyricsSearchCb = function(err, lyricsAndExplanations){ if(err){ @@ -122,12 +112,12 @@ var searchCallback = function(err, songs){ }else{ if(songs.length > 0){ //We have some songs - rapgeniusClient.searchLyricsAndExplanations(songs[0].link, "rap", lyricsSearchCb); + geniusClient.searchLyricsAndExplanations(songs[0].link, lyricsSearchCb); } } }; -rapgeniusClient.searchSong("Liquid Swords", "rap", searchCallback); +geniusClient.searchSong("Liquid Swords", "GZA", searchCallback); ``` diff --git a/examples/artistSearch.js b/examples/artistSearch.js index 9dc2cb2..0b40085 100644 --- a/examples/artistSearch.js +++ b/examples/artistSearch.js @@ -1,21 +1,11 @@ -var rapgeniusClient = require("../src/geniusClient.js"); +var geniusClient = require("../src/geniusClient.js"); -rapgeniusClient.searchArtist("GZA", "rap", function(err, artist){ +geniusClient.searchArtist("GZA", function(err, artist){ if(err){ console.log("Error: " + err); }else{ - console.log("Rap artist found [name=%s, link=%s, popular-songs=%d]", + console.log("Artist found [name=%s, link=%s, popular-songs=%d]", artist.name, artist.link, artist.popularSongs.length); } -}); - -//Example for a rock artist -rapgeniusClient.searchArtist("Bruce Springsteen", "rock", function(err, artist){ - if(err){ - console.log("Error: " + err); - }else{ - console.log("Rap artist found [name=%s, link=%s, popular-songs=%d]", - artist.name, artist.link, artist.popularSongs.length); - } }); \ No newline at end of file diff --git a/examples/lyricsSearch.js b/examples/lyricsSearch.js index 125dab4..05b9659 100644 --- a/examples/lyricsSearch.js +++ b/examples/lyricsSearch.js @@ -1,4 +1,4 @@ -var rapgeniusClient = require("../src/geniusClient"); +var geniusClient = require("../src/geniusClient"); var lyricsSearchCb = function(err, lyricsAndExplanations){ if(err){ @@ -24,9 +24,9 @@ var searchCallback = function(err, songs){ }else{ if(songs.length > 0){ //We have some songs - rapgeniusClient.searchLyricsAndExplanations(songs[0].link, "rap", lyricsSearchCb); + geniusClient.searchLyricsAndExplanations(songs[0].link, lyricsSearchCb); } } }; -rapgeniusClient.searchSong("Liquid Swords", "rap", searchCallback); \ No newline at end of file +geniusClient.searchSong("Liquid Swords", "GZA", searchCallback); \ No newline at end of file diff --git a/examples/songSearch.js b/examples/songSearch.js index e65d297..cac5e15 100644 --- a/examples/songSearch.js +++ b/examples/songSearch.js @@ -1,6 +1,6 @@ -var rapgeniusClient = require("../src/geniusClient"); +var geniusClient = require("../src/geniusClient"); -rapgeniusClient.searchSong("Liquid Swords", "rap", function(err, songs){ +geniusClient.searchSong("Liquid Swords", "GZA", function(err, songs){ if(err){ console.log("Error: " + err); }else{ diff --git a/genius_api_lyrics.js b/genius_api_lyrics.js new file mode 100644 index 0000000..6dd4512 --- /dev/null +++ b/genius_api_lyrics.js @@ -0,0 +1,34 @@ +var geniusClient = require("genius-js"); + +var lyricsSearchCb = function(err, lyricsAndExplanations){ + if(err){ + console.log("Error: " + err); + }else{ + //Printing lyrics with section names + var lyrics = lyricsAndExplanations.lyrics; + var explanations = lyricsAndExplanations.explanations; + console.log("Found lyrics for song [title=%s, main-artist=%s, featuring-artists=%s, producing-artists=%s]", + lyrics.songTitle, lyrics.mainArtist, lyrics.featuringArtists, lyrics.producingArtists); + //console.log("**** LYRICS *****\n%s", lyrics.getFullLyrics(true)); + + //Now we can embed the explanations within the verses + lyrics.addExplanations(explanations); + var firstVerses = lyrics.sections[0].verses[0]; + console.log(firstVerses.content.split('\n')[0]); + //console.log("\nVerses:\n %s \n\n *** This means ***\n%s", firstVerses.content, firstVerses.explanation); + } +}; + +var searchCallback = function(err, songs){ + if(err){ + console.log("Error: " + err); + }else{ + if(songs.length > 0){ + //We have some songs + console.log("SONG ID: " + songs[0].songId) + geniusClient.searchLyricsAndExplanations(songs[0].link, "r-b", lyricsSearchCb); + } + } +}; +geniusClient.searchSong("Beat It", "r-b", searchCallback); +geniusClient.searchSong("Beat It", "rock", searchCallback); \ No newline at end of file diff --git a/package.json b/package.json index 970bb46..b296d3a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { - "name": "rapgenius-js", + "name": "genius-js", "description": "A client that queries the RapGenius (www.rapgenius.com) website", + "genius-js": "https://github.com/yuichitlo/Genius-JS/tarball/master", "version": "0.1.2", "keywords": ["rap", "rock", "rapgenius", "client", "lyrics", "music"], - "author": "kenshiro-o", + "author": "kenshiro-o, yuichitlo", "main": "src/geniusClient", "repository": { "type": "git", - "url": "git://github.com/kenshiro-o/RapGenius-JS.git" + "url": "git://github.com/yuichitlo/Genius-JS.git" }, "dependencies": { "superagent": "0.12.x", diff --git a/src/constants/Constants.js b/src/constants/Constants.js index eaac937..db8f5aa 100644 --- a/src/constants/Constants.js +++ b/src/constants/Constants.js @@ -1,4 +1,10 @@ var Type2URLs = { + "urls": { + "artist_url":"http://genius.com/artists/", + "base_url":"http://genius.com", + "search_url":"http://genius.com/search", + "annotations_url": "http://genius.com/annotations/for_song_page" + }, "rock": { "artist_url":"http://rock.rapgenius.com/artists/", "base_url":"http://rock.rapgenius.com", @@ -10,8 +16,13 @@ var Type2URLs = { "base_url":"http://rapgenius.com", "search_url":"http://rapgenius.com/search", "annotations_url": "http://rapgenius.com/annotations/for_song_page" + }, + "r-b": { + "artist_url":"http://r-b.genius.com/artists/", + "base_url": "http://r-b.genius.com", + "search_url": "http://r-b.genius.com/search", + "annotations_url": "http://r-b.genius.com/annotations/for_song_page" } - }; module.exports.Type2URLs = Type2URLs; @@ -23,3 +34,7 @@ module.exports.ROCK_RAP_GENIUS_ARTIST_URL = "http://rock.rapgenius.com/artists/" module.exports.RAP_GENIUS_URL = "http://rapgenius.com"; module.exports.RAP_GENIUS_URL_SEARCH_URL = "http://rapgenius.com/search"; module.exports.RAP_GENIUS_ARTIST_URL = "http://rapgenius.com/artists/"; + +module.exports.RB_RAP_GENIUS_URL = "http://r-b.genius.com"; +module.exports.RB_RAP_GENIUS_URL_SEARCH_URL = "http://r-b.genius.com/search"; +module.exports.RB_RAP_GENIUS_ARTIST_URL = "http://r-b.genius.com/artists/"; diff --git a/src/constants/Constants.js~ b/src/constants/Constants.js~ new file mode 100644 index 0000000..eaac937 --- /dev/null +++ b/src/constants/Constants.js~ @@ -0,0 +1,25 @@ +var Type2URLs = { + "rock": { + "artist_url":"http://rock.rapgenius.com/artists/", + "base_url":"http://rock.rapgenius.com", + "search_url":"http://rock.rapgenius.com/search", + "annotations_url": "http://rock.rapgenius.com/annotations/for_song_page" + }, + "rap": { + "artist_url":"http://rapgenius.com/artists/", + "base_url":"http://rapgenius.com", + "search_url":"http://rapgenius.com/search", + "annotations_url": "http://rapgenius.com/annotations/for_song_page" + } + +}; + +module.exports.Type2URLs = Type2URLs; + +module.exports.ROCK_RAP_GENIUS_URL = "http://rock.rapgenius.com"; +module.exports.ROCK_RAP_GENIUS_URL_SEARCH_URL = "http://rock.rapgenius.com/search"; +module.exports.ROCK_RAP_GENIUS_ARTIST_URL = "http://rock.rapgenius.com/artists/"; + +module.exports.RAP_GENIUS_URL = "http://rapgenius.com"; +module.exports.RAP_GENIUS_URL_SEARCH_URL = "http://rapgenius.com/search"; +module.exports.RAP_GENIUS_ARTIST_URL = "http://rapgenius.com/artists/"; diff --git a/src/geniusClient.js b/src/geniusClient.js index a6c1046..eddfe54 100644 --- a/src/geniusClient.js +++ b/src/geniusClient.js @@ -1,32 +1,32 @@ var superAgent = require("superagent"), - RapSongParser = require("./parsers/SongsParser"), - RapArtistParser = require("./parsers/ArtistParser"), - RapLyricsParser = require("./parsers/LyricsParser") + SongParser = require("./parsers/SongsParser"), + ArtistParser = require("./parsers/ArtistParser"), + LyricsParser = require("./parsers/LyricsParser") Constants = require("./constants/Constants"); -var RAP_GENIUS_URL = "http://rapgenius.com"; -var RAP_GENIUS_ARTIST_URL = "http://rapgenius.com/artists/"; -var RAP_GENIUS_SONG_EXPLANATION_URL = RAP_GENIUS_URL + "/annotations/for_song_page"; +var GENIUS_URL = "http://genius.com"; +var GENIUS_ARTIST_URL = "http://genius.com/artists/"; +var GENIUS_SONG_EXPLANATION_URL = GENIUS_URL + "/annotations/for_song_page"; -function searchSong(query, type, callback) { +function searchSong(query, artist, callback) { //TODO perform input validation - type = type.toLowerCase(); - var type2Urls = Constants.Type2URLs[ type]; - if (!type2Urls){ - process.nextTick(function(){ - callback("Unrecognized type in song search [type=" + type + "]"); - }); - return; - } - - superAgent.get(type2Urls.search_url) - .query({q: query}) + // type = type.toLowerCase(); + // var type2Urls = Constants.Type2URLs[ type]; + // if (!type2Urls){ + // process.nextTick(function(){ + // callback("Unrecognized type in song search [type=" + type + "]"); + // }); + // return; + // } + + superAgent.get("http://genius.com/search") + .query({q: query + artist}) .set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") .end(function (res) { if (res.ok) { - var result = RapSongParser.parseSongHTML(res.text, type); + var result = SongParser.parseSongHTML(res.text); if (result instanceof Error) { return callback(result); } else { @@ -39,23 +39,23 @@ function searchSong(query, type, callback) { }); } -function searchArtist(artist, type, callback) { +function searchArtist(artist, callback) { //TODO perform input validation - type = type.toLowerCase(); - var type2Urls = Constants.Type2URLs[ type]; - if (!type2Urls){ - process.nextTick(function(){ - callback("Unrecognized type in artist search [type=" + type + "]"); - }); - return; - } - - superAgent.get(type2Urls.artist_url + artist) + // type = type.toLowerCase(); + // var type2Urls = Constants.Type2URLs[ type]; + // if (!type2Urls){ + // process.nextTick(function(){ + // callback("Unrecognized type in artist search [type=" + type + "]"); + // }); + // return; + // } + + superAgent.get("http://genius.com/artists/" + artist) .set("Accept", "text/html") .end(function (res) { debugger; if (res.ok) { - var result = RapArtistParser.parseArtistHTML(res.text, type); + var result = ArtistParser.parseArtistHTML(res.text); if (result instanceof Error) { return callback(result); } else { @@ -69,23 +69,23 @@ function searchArtist(artist, type, callback) { } -function searchSongLyrics(link, type, callback){ +function searchSongLyrics(link, callback){ //Check whether the URL is fully defined or relative - type = type.toLowerCase(); - var type2Urls = Constants.Type2URLs[ type]; - if (!type2Urls){ - process.nextTick(function(){ - callback("Unrecognized type in song lyrics search [type=" + type + "]"); - }); - return; - } - - var url = /^http/.test(link) ? link : type2Urls.base_url + link; + // type = type.toLowerCase(); + // var type2Urls = Constants.Type2URLs[ type]; + // if (!type2Urls){ + // process.nextTick(function(){ + // callback("Unrecognized type in song lyrics search [type=" + type + "]"); + // }); + // return; + // } + + var url = /^http/.test(link) ? link : "http://genius.com" + link; superAgent.get(url) .set("Accept", "text/html") .end(function(res){ if(res.ok){ - var result = RapLyricsParser.parseLyricsHTML(res.text, type); + var result = LyricsParser.parseLyricsHTML(res.text); if(result instanceof Error){ return callback(result); }else{ @@ -98,24 +98,24 @@ function searchSongLyrics(link, type, callback){ }); } -function searchLyricsExplanation(songId, type, callback){ +function searchLyricsExplanation(songId, callback){ //Check whether the URL is fully defined or relative - type = type.toLowerCase(); - var type2Urls = Constants.Type2URLs[ type]; - if (!type2Urls){ - process.nextTick(function(){ - callback("Unrecognized type in song lyrics search [type=" + type + "]"); - }); - return; - } + // type = type.toLowerCase(); + // var type2Urls = Constants.Type2URLs[ type]; + // if (!type2Urls){ + // process.nextTick(function(){ + // callback("Unrecognized type in song lyrics search [type=" + type + "]"); + // }); + // return; + // } - superAgent.get(type2Urls.annotations_url) + superAgent.get("http://genius.com/annotations/for_song_page") .set("Accept", "text/html") .query({song_id: songId}) .end(function(res){ if(res.ok){ - var explanations = RapLyricsParser.parseLyricsExplanationJSON(JSON.parse(res.text)); + var explanations = LyricsParser.parseLyricsExplanationJSON(JSON.parse(res.text)); if(explanations instanceof Error){ return callback(explanations); }else{ @@ -128,14 +128,15 @@ function searchLyricsExplanation(songId, type, callback){ }); } -function searchLyricsAndExplanations(link, type, callback){ +function searchLyricsAndExplanations(link, callback){ var lyrics = null; - var lyricsCallback = function(err, rapLyrics){ + var lyricsCallback = function(err, cur_lyrics){ if(err){ return callback(err); }else{ - lyrics = rapLyrics; - searchLyricsExplanation(lyrics.songId, type, explanationsCallback); + lyrics = cur_lyrics; + console.log("SongID: " + lyrics.songId) + searchLyricsExplanation(lyrics.songId, explanationsCallback); } }; @@ -147,7 +148,7 @@ function searchLyricsAndExplanations(link, type, callback){ } }; - searchSongLyrics(link, type, lyricsCallback); + searchSongLyrics(link, lyricsCallback); } module.exports.searchSong = searchSong; diff --git a/src/model/Artist.js b/src/model/Artist.js index 5c6978d..606c1e5 100644 --- a/src/model/Artist.js +++ b/src/model/Artist.js @@ -12,12 +12,12 @@ Artist.prototype = { songs: null }; -Artist.prototype.addPopularSong = function (rapSong) { - this.popularSongs.push(rapSong); +Artist.prototype.addPopularSong = function (song) { + this.popularSongs.push(song); }; -Artist.prototype.addSong = function (rapSong) { - this.songs.push(rapSong); +Artist.prototype.addSong = function (song) { + this.songs.push(song); }; diff --git a/src/parsers/ArtistParser.js b/src/parsers/ArtistParser.js index 9fca8a4..6150a5d 100644 --- a/src/parsers/ArtistParser.js +++ b/src/parsers/ArtistParser.js @@ -5,9 +5,9 @@ var cheerio = require("cheerio"), StringUtils = require("../util/StringUtils"); -function parseArtistHTML(html, type) { +function parseArtistHTML(html) { try { - var urls = CONSTANTS.Type2URLs[type]; + var urls = CONSTANTS.Type2URLs["urls"]; var $ = cheerio.load(html); var artistElem = $(".canonical_name", "#main"); @@ -28,7 +28,7 @@ function parseArtistHTML(html, type) { }); var artistLink = urls.artist_url + artistName.replace(" ", "-"); - var rapArtist = new Artist(artistName, artistLink); + var cur_artist = new Artist(artistName, artistLink); var songs = $(".song_list", "#main"); songs.each(function (index, song) { @@ -40,18 +40,18 @@ function parseArtistHTML(html, type) { if (index === 0) { //This element represents the favourite songs of the artist - rapArtist.addPopularSong(rapSong); + cur_artist.addPopularSong(rapSong); } - rapArtist.addSong(rapSong); + cur_artist.addSong(rapSong); }); }); - return rapArtist; + return cur_artist; } catch (e) { console.log("An error occured while trying to parse the artist: [html=" + html + "], error: " + e); - return new Error("Unable to parse artist details results from RapGenius"); + return new Error("Unable to parse artist details results from Genius"); } } diff --git a/src/parsers/LyricsParser.js b/src/parsers/LyricsParser.js index 9bd8b8c..0e59b75 100644 --- a/src/parsers/LyricsParser.js +++ b/src/parsers/LyricsParser.js @@ -2,7 +2,7 @@ var cheerio = require("cheerio"), Lyrics = require("../model/Lyrics"), StringUtils = require("../util/StringUtils"); -function parseLyricsHTML(html, type) { +function parseLyricsHTML(html) { try { var $ = cheerio.load(html); @@ -32,7 +32,7 @@ function parseLyricsHTML(html, type) { if (lyricsContainer.length <= 0) { return new Error("Unable to parse lyrics: lyrics_container does not exist!"); } - var rapLyrics = null; + var cur_lyrics = null; var currentSection = new Lyrics.Section("[Empty Section]"); @@ -41,11 +41,11 @@ function parseLyricsHTML(html, type) { //The lyrics class holds the paragraphs that contain the lyrics var lyricsElems = $(container).find(".lyrics"); var songId = parseInt($(lyricsElems.first()).attr("data-id")); - rapLyrics = new Lyrics.Lyrics(songId, 10); - rapLyrics.songTitle = songTitle; - rapLyrics.mainArtist = mainArtist; - rapLyrics.featuringArtists = ftList; - rapLyrics.producingArtists = prodList; + cur_lyrics = new Lyrics.Lyrics(songId, 10); + cur_lyrics.songTitle = songTitle; + cur_lyrics.mainArtist = mainArtist; + cur_lyrics.featuringArtists = ftList; + cur_lyrics.producingArtists = prodList; var currentVerses = null; @@ -58,7 +58,7 @@ function parseLyricsHTML(html, type) { //check if parsed content is a section if (/^\[.*\]$/.test(parsed)) { currentSection = new Lyrics.Section(parsed); - rapLyrics.addSection(currentSection); + cur_lyrics.addSection(currentSection); } else { //Not a section name, therefore this must be text //However we only want to add non empty strings @@ -98,10 +98,10 @@ function parseLyricsHTML(html, type) { lyricsElems.find("p").each(parserFunc); }); - if (rapLyrics.sections.length === 0){ - rapLyrics.addSection(currentSection); + if (cur_lyrics.sections.length === 0){ + cur_lyrics.addSection(currentSection); } - return rapLyrics; + return cur_lyrics; } catch (e) { console.log("An error occurred while trying to parse the lyrics: [html=" + html + "], :\n" + e); return new Error("Unable to parse lyrics from RapGenius"); diff --git a/src/parsers/SongsParser.js b/src/parsers/SongsParser.js index 75c3e25..7fc51c3 100644 --- a/src/parsers/SongsParser.js +++ b/src/parsers/SongsParser.js @@ -4,15 +4,15 @@ var cheerio = require("cheerio"), StringUtils = require("../util/StringUtils"); -function parseSongHTML(html, type) { +function parseSongHTML(html) { //TODO Check we are dealing with proper HTML //or something that looks like HTML, otherwise throw an error try { - var urls = CONSTANTS.Type2URLs[type]; + var urls = CONSTANTS.Type2URLs["urls"]; var $ = cheerio.load(html); var songs = $(".song_link", "#main"); - var rapSongArray = new Array(songs.length); + var songArray = new Array(songs.length); songs.each(function (index, song) { var link = $(this).attr("href"); @@ -29,13 +29,13 @@ function parseSongHTML(html, type) { var artists = StringUtils.trim(songAndArtists.substring(0, indexOfHyphen)); var songName = StringUtils.trim(songAndArtists.substring(indexOfHyphen + 1, songAndArtists.length)); - rapSongArray[index] = new Song(songName, artists, link); + songArray[index] = new Song(songName, artists, link); }); - return rapSongArray; + return songArray; } catch (e) { console.log("An error occured while trying to parse the songs: [html=" + html + "]"); - return new Error("Unable to parse song search results from RapGenius"); + return new Error("Unable to parse song search results from Genius"); } }