UNPKG

3.36 kBtext/coffeescriptView Raw
1querystring = require 'querystring'
2request = require 'request'
3compress = require 'compress'
4
5# This is the entry point.
6#
7# Takes an optional format parameter, defaulting to 'json'. If 'xml' consumer is expected to take care of parsing
8#
9# client = discogs("xml")
10exports = module.exports = (format) ->
11 gunzip = new compress.Gunzip()
12 gunzip.init()
13
14 # Return a proper url with optional format
15 getUrl = (url) ->
16 sep = if "?" in url then "&" else "?"
17 url = "http://api.discogs.com/#{url}" if url.substr(0, 7) isnt 'http://'
18
19 url += "#{sep}f=#{format}" if format
20 url
21
22 # Make a request
23 discogsRequest = (url, next) ->
24 request
25 uri: getUrl url
26 headers: {'accept-encoding': 'gzip'}
27 encoding: 'binary'
28 (error, res, body) =>
29 if not error and 200 <= res.statusCode < 400
30 if body
31 body = gunzip.inflate(body) if 'gzip' in res.headers['content-type']
32 body = JSON.parse(body) if 'json' in res.headers['content-type'] or not format
33
34 next null, body
35 else
36 next error
37
38 responseHandler = (type, next) ->
39 (err, res) ->
40 return next(err, res) if err or res not instanceof Object or type not of res?.resp
41 next(null, res.resp[type])
42
43 # API
44
45 # Use this if you have a discogs url
46 get: (url, next) ->
47 discogsRequest url, next
48
49 # Get a release
50 master: (id, next) ->
51 discogsRequest 'master/' + id,
52 responseHandler('master', next)
53
54 # Get a release
55 release: (id, next) ->
56 discogsRequest 'release/' + id,
57 responseHandler('release', next)
58
59 # Get an artist
60 artist: (name, next) ->
61 discogsRequest 'artist/' + name,
62 responseHandler('artist', next)
63
64 # Get a label
65 label: (name, next) ->
66 discogsRequest 'label/' + name,
67 responseHandler('label', next)
68
69 # Search for something
70 # Valid types:
71 # `all`, `artists`, `labels`, `releases`, `needsvote`, `catno`, `forsale`
72 search: (query, type, next) ->
73 if type instanceof Function
74 next = type
75 type = 'all'
76 discogsRequest 'search?' + querystring.stringify(type: type, q: query),
77 responseHandler('search', next)
78
79 # Do a search and try to find the master or main release in all results.
80 # Uses 2 or 3 requests per lookup, to find the best result.
81 lookup: (query, next) ->
82 @search query, "releases", (err, res) =>
83 return next err if err
84
85 results = res?.searchresults?.results
86 return next() unless results
87
88 masters = (result for result in results when result.type is "master")
89 # Did we find masters already?
90 results = masters if masters.length
91
92 matches = (result for result in results when result.title is query)
93 # Take only the best results
94 results = matches if matches.length
95
96 release = results[0]
97 id = release.uri.split("/").pop()
98
99 @[release.type] id, (err, res) =>
100 if "master_id" of res
101 # Did we find a master now?
102 @master res.master_id, (err, master) =>
103 if "main_release" of master
104 @release master.main_release, next
105 else
106 next null, master
107 else if "main_release" of res
108 # Or maybe a main release?
109 @release res.main_release, next
110 else
111 # This is the best we can do
112 next null, res