Created
October 25, 2012 15:36
-
-
Save bendoerr/3953421 to your computer and use it in GitHub Desktop.
Messy script to pull personal ratings for a particular genre from Netflix.
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
// Repository for Java Netflix Client. | |
@GrabResolver(name='BLC', root='http://nexus.blueleftistconstructor.com/content/repositories/releases') | |
// Java Netflix Client to abstract the raw http calls for us. | |
@Grab(group='com.lysergicjava.nfclient', module='netflix-java-client', version='2.1.2') | |
// The netflix-java-client uses SLF4J and complains if we don't have a facade around. | |
@Grab(group='org.slf4j', module='slf4j-simple', version='1.7.2') | |
// HttpClient since we want the stream for downloading the index file, and | |
// IO to write that stream to a file. | |
@Grab(group='commons-httpclient', module='commons-httpclient', version='3.1') | |
@Grab(group='commons-io', module='commons-io', version='2.4') | |
// StAX to Process the index. | |
@Grab(group='stax', module='stax-api', version='1.0.1') | |
@Grab(group='stax', module='stax', version='1.2.0') | |
import com.netflix.api.client.* | |
import com.netflix.api.client.dal.* | |
import com.netflix.api.client.oauth.* | |
import java.net.URLDecoder | |
import javax.xml.stream.* | |
import org.apache.commons.httpclient.HttpClient | |
import org.apache.commons.io.IOUtils | |
def key = args[0] | |
def secret = args[1] | |
def apiClient = new NetflixAPIClient(key, secret) | |
println "Starting" | |
// Lets save ourselves some bandwidth and cache the result | |
def indexFileName = "netflixIndex.xml" | |
def indexFileInStream = null; | |
if(!new File(indexFileName).exists()) { | |
println "Fetching Index to comb it for Anime" | |
def indexFileOutStream = new FileOutputStream(indexFileName) | |
// We want to stream this beast, so we can't use NetflixAPIClient directly. | |
def builder = new HttpMethodBuilder(apiClient) | |
def getIndexMethod = builder.buildConsumerSignedGetMethod(APIEndpoints.INDEX_URI, builder.getDefaultOAuthParameters()) | |
new HttpClient().executeMethod(getIndexMethod) | |
indexFileInStream = getIndexMethod.getResponseBodyAsStream() | |
IOUtils.copy(indexFileInStream, indexFileOutStream) | |
} else { | |
println "Found Index" | |
indexFileInStream = new FileInputStream(indexFileName) | |
} | |
// Step two filter the index for just anime. | |
// <category scheme="http://api.netflix.com/categories/genres" label="Anime & Animation" term="Anime & Animation"></category> | |
def animeTitleIds = [] | |
// Do some caching again | |
def animeTitlesFile = new File("netflixAnimeIds.txt") | |
if (!animeTitlesFile.exists()) { | |
println "Filtering Anime Out" | |
def xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(indexFileInStream) | |
def titleId = '' | |
def title = '' | |
def isAnime = false | |
while (xmlReader.hasNext()) { | |
if (xmlReader.startElement) { | |
switch (xmlReader.name.toString()){ | |
case 'title_index_item': | |
titleId = '' | |
isAnime = false | |
break | |
case 'id': | |
def id = xmlReader.elementText | |
if (id.startsWith('http')) | |
titleId = id | |
break | |
case 'title': | |
title = xmlReader.elementText | |
break | |
case 'category': | |
if (xmlReader.getAttributeValue(null, 'scheme') == 'http://api.netflix.com/categories/genres' && | |
xmlReader.getAttributeValue(null, 'term') == 'Anime & Animation') | |
isAnime = true | |
break | |
} | |
} | |
else if (xmlReader.endElement) { | |
if (xmlReader.name.toString() == 'title_index_item' && isAnime && titleId) | |
animeTitleIds.add(titleId) | |
} | |
xmlReader.next() | |
} | |
animeTitlesFile.setText('') | |
animeTitleIds.each { animeTitlesFile.append(it + "\n") } | |
} else { | |
println "Found Anime Ids" | |
animeTitleIds = animeTitlesFile.readLines() | |
} | |
def animeRatingsFile = new File("netflixAnimeRatings.xml") | |
if (!animeRatingsFile.exists()) { | |
def reqToken = apiClient.getNewRequestToken(); | |
println "Go Here and Do the Stuff: http://developer.netflix.com/walkthrough" | |
println "App Name: ${reqToken.getApplicationName()}" | |
println "OAuth Token: ${reqToken.getTokenText()}" | |
println "OAuth Secret: ${reqToken.getTokenSecret()}" | |
def userId = System.console().readLine('user > ') | |
def oauthToken = System.console().readLine('token > ') | |
def oauthSecret = System.console().readLine('secret > ') | |
def accessToken = new OAuthAccessToken() | |
accessToken.setTokenUserID(userId) | |
accessToken.setTokenText(oauthToken) | |
accessToken.setTokenSecret(oauthSecret) | |
def customer = new NetflixAPICustomer(accessToken); | |
animeRatingsFile.setText('') | |
// We can only do 500 title at a time | |
int chunk = 100 | |
(0..(animeTitleIds.size() / chunk)).each {gIdx -> | |
def offset = gIdx * chunk | |
def group = animeTitleIds[offset..(offset + (chunk - 1) < animeTitleIds.size() ? offset + (chunk - 1) : animeTitleIds.size() - 1)] | |
def titleRefs = group.join(',') | |
println "Fetching a group of ratings." | |
def response = apiClient.makeCustomerAuthorizedApiCall( | |
"${APIEndpoints.USER_URI}/${customer.getCustomerID()}/ratings/title", | |
customer, | |
['title_refs': titleRefs], | |
NetflixAPIClient.GET_METHOD_TYPE) | |
animeRatingsFile.append(response.getResponseBody()) | |
sleep(100) | |
} | |
} else { | |
println "Found Ratings File" | |
} | |
def ratingsInStream = new FileInputStream(animeRatingsFile) | |
println "Finding My Ratings" | |
def xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(ratingsInStream) | |
def title = null | |
def rating = null | |
def myAnimeRatings = [:] | |
while (xmlReader.hasNext()) { | |
if (xmlReader.startElement) { | |
switch (xmlReader.name.toString()){ | |
case 'ratings_item': | |
title = null | |
rating = null | |
break | |
case 'title': | |
title = xmlReader.getAttributeValue(null, 'regular') | |
break | |
case 'user_rating': | |
rating = xmlReader.elementText | |
break | |
} | |
} | |
else if (xmlReader.endElement) { | |
if (xmlReader.name.toString() == 'ratings_item' && title && rating) | |
myAnimeRatings.put(title, rating) | |
} | |
xmlReader.next() | |
} | |
myAnimeRatings.each {k,v-> | |
println "$k : $v" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment