Last active
January 8, 2017 20:17
-
-
Save haze/4af7a3be79abc0038dbce60a6719d92b to your computer and use it in GitHub Desktop.
1 class API for Genius ( needs Jsoup and Apache HTTP components )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package pw.haze.lyribot | |
import com.github.salomonbrys.kotson.fromJson | |
import com.google.gson.Gson | |
import com.google.gson.annotations.SerializedName | |
import org.apache.http.client.methods.HttpGet | |
import org.apache.http.client.methods.HttpUriRequest | |
import org.apache.http.impl.client.HttpClientBuilder | |
import org.jsoup.Jsoup | |
import java.io.BufferedReader | |
import java.io.InputStreamReader | |
import java.net.URLEncoder | |
/** | |
* @author Haze | |
* @time 11:35 (11:35 AM) | |
* @since 1/1/2017 | |
*/ | |
private val chromeUserAgent: String = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.28 Safari/537.36" | |
// f*** genius and f*** jsoup worst combination ever smfhtbqbh | |
fun <T> List<T>.skip(n: Int): List<T> = subList(n, size) | |
private fun scrapeLyrics(url: String): Array<String> = Jsoup.connect(url).userAgent(chromeUserAgent).get().getElementsByTag("lyrics").first().text().split("[").skip(1).map { s -> "[$s" }.toTypedArray() | |
class Genius(val id: String, val secret: String, val clientToken: String) { | |
// General Specifications | |
data class MetaObject(val status: Int) | |
data class Album(@SerializedName("api_path") val apiPath: String, | |
@SerializedName("cover_art_url") val coverArtURL: String, | |
val id: Long, | |
val name: String, | |
val url: String, | |
val artist: Artist) | |
data class MediaObject(val cinema: Boolean, | |
val provider: String, | |
val start: Int, | |
val type: String, | |
val url: String) | |
data class Song(val hot: Boolean, | |
@SerializedName("unreviewed_annotations") val unreviewedAnnotations: Int, | |
@SerializedName("pageviews") val pageViews: Int, | |
@SerializedName("annotation_count") val annotations: Int, | |
@SerializedName("api_path") val apiPath: String, | |
@SerializedName("featured_video") val featuredVideo: Boolean, | |
@SerializedName("full_title") val fullTitle: String, | |
@SerializedName("lyrics_owner_id") val lyricsOwnerID: Int, | |
@SerializedName("pyongs_count") val pyongs: Int, | |
@SerializedName("recording_location") val recordingLocation: String, | |
@SerializedName("release_date") val releaseDate: String, | |
@SerializedName("song_art_image_thumbnail_url") val songArtImageThumbURL: String, | |
@SerializedName("song_art_image_url") val songArtImageURL: String, | |
@SerializedName("primary_artist") val primaryArtist: Artist, | |
@SerializedName("writer_artists") val writers: Array<Artist>, | |
val url: String, | |
val id: Long, | |
val title: String, | |
val album: Album, | |
val media: Array<MediaObject>, | |
val concurrents: Int | |
) { | |
val lyrics: Array<String> | |
get() = scrapeLyrics(this.url) | |
} | |
data class Artist(@SerializedName("api_path") val apiPath: String, | |
@SerializedName("alternative_names") val alternativeNames: Array<String>, | |
@SerializedName("facebook_name") val facebookName: String, | |
@SerializedName("followers_count") val followers: Int, | |
@SerializedName("instagram_name") val instagramName: String, | |
@SerializedName("twitter_name") val twitterName: String, | |
@SerializedName("header_image_url") val headerImageURL: String, | |
val id: Long, | |
@SerializedName("image_url") val imageURL: String, | |
@SerializedName("is_meme_verified") val isMeme: Boolean, | |
@SerializedName("is_verified") val isVerified: Boolean, | |
val name: String, | |
val url: String, | |
val iq: Int) | |
// Search Specifications | |
// *NOTE* I've ignored the "highlights" tag as it appeared to return nothing from the example search query. | |
data class SearchIndex(@SerializedName("annotation_count") val annotations: Int, | |
@SerializedName("api_path") val apiPath: String, | |
@SerializedName("full_title") val fullTitle: String, | |
@SerializedName("header_image_thumbnail_url") val headerThumbImageURL: String, | |
@SerializedName("header_image_url") val headerImageURl: String, | |
@SerializedName("lyrics_owner_id") val ownerID: Int, | |
val id: Long, | |
val path: String, | |
@SerializedName("pyongs") val pyongs: Int, | |
@SerializedName("song_art_image_thumbnail_url") val songArtImageThumbURL: String, | |
val title: String, | |
val url: String, | |
@SerializedName("primary_artist") val primaryArtist: Artist) | |
data class SearchHit(val index: String, val type: String, val result: SearchIndex) | |
data class SearchResult(val hits: Array<SearchHit>) | |
data class SongResult(val song: Song) | |
// query meta wrappers | |
data class ArtistQuery(val meta: MetaObject, val response: Artist) | |
data class SearchQuery(val meta: MetaObject, val response: SearchResult) | |
data class SongQuery(val meta: MetaObject, val response: SongResult) | |
private val gson: Gson = Gson() | |
private val apiEndpoint: String = "http://api.genius.com/" | |
private val authString: String = "Bearer $clientToken" | |
private fun String.urlEncode(): String = URLEncoder.encode(this, "UTF-8") | |
private fun HttpUriRequest.addGeniusHeaders(): HttpUriRequest = apply { addHeader("Host", "api.genius.com"); addHeader("User-Agent", chromeUserAgent); addHeader("Accept", "application/json"); addHeader("Authorization", authString) } | |
fun search(query: String): SearchQuery = gson.fromJson<SearchQuery>(BufferedReader(InputStreamReader(HttpClientBuilder.create().build().execute(HttpGet("${this.apiEndpoint}search?q=${query.urlEncode()}").addGeniusHeaders()).entity.content))) | |
fun artist(id: Long): ArtistQuery = gson.fromJson<ArtistQuery>(BufferedReader(InputStreamReader(HttpClientBuilder.create().build().execute(HttpGet("${this.apiEndpoint}artists/$id").addGeniusHeaders()).entity.content))) | |
fun song(id: Long): SongQuery = gson.fromJson<SongQuery>(BufferedReader(InputStreamReader(HttpClientBuilder.create().build().execute(HttpGet("${this.apiEndpoint}songs/$id").addGeniusHeaders()).entity.content))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment