Permalink
Browse files

Initial commit: working shows api

  • Loading branch information...
mattijs committed Nov 26, 2011
0 parents commit 9c99da1937cde2ab30c89795dbbae532c3a17fd1
Showing with 257 additions and 0 deletions.
  1. +40 −0 README.md
  2. +18 −0 examples/shows.coffee
  3. +92 −0 src/trakt/client.coffee
  4. +5 −0 src/trakt/index.coffee
  5. +44 −0 src/trakt/user.coffee
  6. +58 −0 trakt.coffee
@@ -0,0 +1,40 @@
+# node-trakt
+
+node-trakt (as the name suggests) is a node module for accessing the
+http://trakt.tv API.
+
+The source for node-trakt is written in CoffeeScript. The module can be
+used with node.js through the CoffeeScript module or by using the
+compiled source.
+
+This is still alpha state software: it might be and likely is broken and
+far from complete.
+
+## (Un)license
+
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/>
+
+
@@ -0,0 +1,18 @@
+{Client} = require '../src/trakt'
+UserExtension = require '../src/trakt/user'
+
+# Configuration
+apikey = 'YOUR API KEY GOES HERE'
+username = 'YOUR USERNAME GOES HERE'
+
+# Create a client
+client = new Client apikey
+
+# Load the user api
+ext = new UserExtension
+client.extend "user", ext
+
+# Retreive shows for a username
+client.user.shows { username: username }, (data) ->
+ console.log "Received data"
+ console.log data
@@ -0,0 +1,92 @@
+http = require 'http'
+
+class Client
+
+ constructor: (@apikey, @format = 'json') ->
+ @apiBase = 'api.trakt.tv'
+ @authHash = null
+ @extensions = {}
+
+ extend: (name, extension) ->
+ throw new Error("Extension must be an instance of ClientExtension") unless extension instanceof ClientExtension
+
+ # Register the extension and give it a reference to us (Client)
+ @extensions[name] = extension
+ extension.setClient @
+
+ # Create extension as property
+ @[name] = {} unless @hasOwnProperty(name) and Object is @name.constructor
+
+ # Copy all exported methods and correct scope to the extending object
+ for methodName, method of do extension.exports
+ @[name][methodName] = (() ->
+ return () -> method.apply extension, arguments
+ )()
+
+ return @
+
+ authenticate: (username, password) ->
+
+ post: (endpoint, data = {}, callback) ->
+ console.log "Posting to #{endpoint}"
+
+ get: (endpoint, callback) ->
+ console.log "Getting #{endpoint}"
+ options =
+ host: @apiBase
+ port: 80
+ path: endpoint
+ method: 'GET'
+
+ request = http.request options, (response) =>
+ response.setEncoding 'utf8'
+ data = ''
+ response.on 'data', (chunk) ->
+ data += chunk
+ response.on 'end', () ->
+ callback JSON.parse data
+ do request.end
+
+
+
+class ClientExtension
+
+ # Set the API Client
+ setClient: (@client) ->
+
+ # List of methods this extension offers
+ exports: () ->
+ return {}
+
+ # Construct an endpoint replacing parameter placeholders with values
+ #
+ # @param {string} name The endpoint name to construct
+ # @param {object} parameters Map of parameters to insert into the endpoint
+ # @return {string}
+ endpoint: (name, parameters = {}) ->
+ throw new Error("Endpoint #{name} not found") if not endpoint = @endpoints[name]
+
+ # Replace all parameters in the endpoint
+ regex = new RegExp "\:[A-Za-z0-9_\-]*", 'g'
+ endpoint = endpoint.replace regex, (match) =>
+ key = match.substr 1
+ throw new Error "Parameter #{key} not found in list" unless parameters.hasOwnProperty key
+
+ return parameters[key]
+
+ return endpoint
+
+ # Merge the contents of two objects
+ merge: (obj1, obj2) ->
+ for param of obj2
+ if obj2[param].constructor is Object
+ obj1[param] = @merge obj1[param], obj2[param]
+ else if not obj1.hasOwnProperty param
+ obj1[param] = obj2[param]
+
+ return obj1
+
+
+module.exports =
+ Client: Client
+ ClientExtension: ClientExtension
@@ -0,0 +1,5 @@
+client = require './client'
+
+module.exports =
+ Client: client.Client
+ ClientExtension: client.ClientExtension
@@ -0,0 +1,44 @@
+{ClientExtension} = require './client'
+
+class UserExtension extends ClientExtension
+
+ endpoints:
+ 'calendar': '/user/calendar/shows.:format/:apikey/:username'
+ 'friends': '/user/friends'
+ 'shows': '/user/library/shows/:data.:format/:apikey/:username'
+ 'movies': '/user/library/movies/:data.format/:apikey/:username'
+ 'lists': '/user/lists.:format/:apikey/:username'
+ 'list': '/user/list.:format/:apikey/:username/:slug'
+
+ # Fetch shows for a Trakt user. Authentication is needed to retrieve
+ # private show data.
+ shows: (parameters = {}, callback) ->
+ parameters = @merge parameters, {
+ data: 'all',
+ apikey: @client.apikey,
+ format: @client.format
+ }
+ throw new Error "Username not given" unless parameters.username
+
+ endpoint = @endpoint 'shows', parameters
+
+ @client.get endpoint, callback
+
+ lists: (parameters = {}, callback) ->
+ parameters = @merge parameters, {
+ apikey: @client.apikey,
+ format: @client.format
+ }
+ throw new Error "Username not given" unless parameters.username
+
+ endpoint = @endpoint 'lists', parameters
+
+ @client.get endpoint, callback
+
+ exports: () ->
+ return {
+ shows: @shows
+ lists: @lists
+ }
+
+module.exports = UserExtension
@@ -0,0 +1,58 @@
+class Trakt
+
+ endpoints:
+ 'userShowsCalendar': '/user/calendar/shows.:format/:apikey/:username'
+ 'userFriends': '/user/friends'
+ 'userShows': '/user/library/shows/:data.:format/:apikey/:username'
+ 'userMovies': '/user/library/movies/:data.format/:apikey/:username'
+ 'userList': '/user/list.:format/:apikey/:username/:slug'
+
+ constructor: (@apiKey, @username = null, @format = "json") ->
+ @protocol = 'http'
+ @apiBase = 'api.trakt.tv'
+
+ userShows: (parameters = {}, callback) ->
+ parameters = @mergeObjects parameters, { data: 'all', format: @format, apikey: @apiKey }
+
+ endpoint = @endpoint 'userShows', parameters
+ @get endpoint, callback
+
+ userList: (parameters = {}, callback) ->
+ parameters = @mergeObjects parameters, { format: @format, apikey: @apiKey }
+
+ endpoint = @endpoint 'userList', parameters
+ @get endpoint, callback
+
+ mergeObjects: (obj1, obj2) ->
+ for param of obj2
+ if obj2[param].constructor is Object
+ obj1[param] = @mergeObjects obj1[param], obj2[param]
+ else if undefined is obj1[param]
+ obj1[param] = obj2[param]
+
+ return obj1
+
+ endpoint: (name, parameters = {}) ->
+ throw new Error("Endpoint #{name} not found") if not endpoint = @endpoints[name]
+
+ # Replace all parameters in the endpoint
+ regex = new RegExp "\:[A-Za-z0-9_\-]*", 'g'
+ endpoint = endpoint.replace regex, (match) =>
+ key = match.substr 1
+ throw new Error "Parameter #{key} not found in list" unless parameters.hasOwnProperty key
+
+ return parameters[key]
+
+ return endpoint
+
+ get: (endpoint, callback) ->
+ $.ajax {
+ url: "#{@protocol}://#{@apiBase}#{endpoint}",
+ type: "GET",
+ dataType: "jsonp",
+ success: (data) -> callback null, data
+ error: (jqXHR, textStatus, errorThrown) -> callback errorThrown
+ }
+
+# Export for usage
+window.Trakt = Trakt

0 comments on commit 9c99da1

Please sign in to comment.