Skip to content

Commit f2bba75

Browse files
unknownunknown
unknown
authored and
unknown
committed
0.2.0
1 parent c1727f5 commit f2bba75

File tree

6 files changed

+67
-40
lines changed

6 files changed

+67
-40
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
node_modules/
1+
node_modules/
2+
*.log

HISTORY.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
0.2.0 / 2014-06-19
2+
==================
3+
* Implemented/fixed broken `image` function from `0.1.1`
4+
* Added rate limiting header info to the callback params
5+
16
0.1.1 / 2014-06-18
27
==================
38
* Added `HISTORY.md`

README.md

+21-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
[![NPM version](https://badge.fury.io/js/disconnect.svg)](http://badge.fury.io/js/disconnect)
2-
[![Dependency Status](https://david-dm.org/bartve/disconnect.png)](https://david-dm.org/bartve/disconnect)
3-
41
## About
52

63
`disconnect` is a [Node.js](http://www.nodejs.org) client library that connects with the [Discogs.com API v2.0](http://www.discogs.com/developers/).
74

5+
[![NPM version](https://badge.fury.io/js/disconnect.svg)](http://badge.fury.io/js/disconnect) [![Dependency Status](https://david-dm.org/bartve/disconnect.png)](https://david-dm.org/bartve/disconnect)
6+
87
## Features
98

109
* Covers all API endpoints
11-
* All functions implement the standard `function(err, data)` format for the callback
10+
* All functions implement a standard `function(err, data, rateLimit)` format for the callback
1211
* Includes OAuth 1.0a tools. Just plug in your consumer key and secret and do the OAuth dance
1312
* API functions grouped in their own namespace for easy access and isolation
1413

@@ -112,6 +111,7 @@ app.get('/callback', function(req, res){
112111
);
113112
});
114113
```
114+
115115
#### 4. Make OAuth calls
116116
Simply provide the constructor with the access data object persisted in step 3.
117117
```javascript
@@ -127,6 +127,23 @@ The User-Agent may still be passed for OAuth calls.
127127
var dis = new Discogs('MyUserAgent/1.0', accessData);
128128
```
129129

130+
### Images
131+
Image requests require authentication and are subject to [rate limiting](http://www.discogs.com/developers/accessing.html#rate-limiting).
132+
```javascript
133+
app.get('/image/:filename', function(req, res){
134+
var db = new Discogs(accessData).database(),
135+
file = req.params.filename;
136+
db.image(file, function(err, data, rateLimit){
137+
// Data contains the raw binary image data
138+
require('fs').writeFile(file, data, 'binary', function(err){
139+
// See your current limits
140+
console.log(rateLimit);
141+
res.send('Image saved!');
142+
});
143+
});
144+
});
145+
```
146+
130147
## Resources
131148

132149
* [Discogs API 2.0 documentation](http://www.discogs.com/developers/)

lib/client.js

+28-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var config = {
2929
oauthAuthorizeUrl: 'http://www.discogs.com/oauth/authorize',
3030
port: 80,
3131
customHeaders: {
32-
'Accept': 'application/json',
32+
'Accept': 'application/json; application/octet-stream',
3333
'Accept-Encoding': 'gzip,deflate',
3434
'User-Agent': 'DisConnectClient/'+package.version
3535
}
@@ -154,7 +154,8 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
154154
var data = options.data||null,
155155
method = options.method||'GET',
156156
urlParts = url.parse(options.url),
157-
oauth = options.oauth||this.oauth;
157+
oauth = options.oauth||this.oauth,
158+
encoding = options.encoding||'utf8';
158159

159160
// Build request headers
160161
var headers = {
@@ -193,19 +194,34 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
193194
// Build the HTTP request
194195
var req = http.request(options, function(res){
195196
var data = '',
197+
rateLimit = null,
196198
add = function(chunk){ data += chunk.toString(); },
197-
parse = function(){ (typeof callback === 'function')&&callback(null, data); };
199+
passData = function(){ (typeof callback === 'function')&&callback(null, data, rateLimit); };
200+
201+
// Set encoding
202+
res.setEncoding(encoding);
203+
204+
// Find and add rate limiting when present
205+
if(res.headers['x-ratelimit-type']){
206+
rateLimit = {
207+
type: res.headers['x-ratelimit-type'],
208+
limit: res.headers['x-ratelimit-limit'],
209+
reset: res.headers['x-ratelimit-reset'],
210+
remaining: res.headers['x-ratelimit-remaining']
211+
};
212+
}
213+
// Get the response content and pass it to the callback
198214
switch(res.headers['content-encoding']){
199215
case 'gzip':
200-
var gunzip = zlib.createGunzip().on('data', add).on('end', parse);
216+
var gunzip = zlib.createGunzip().on('data', add).on('end', passData);
201217
res.pipe(gunzip);
202218
break;
203219
case 'deflate':
204-
var inflate = zlib.createInflate().on('data', add).on('end', parse);
220+
var inflate = zlib.createInflate().on('data', add).on('end', passData);
205221
res.pipe(inflate);
206222
break;
207223
default:
208-
res.on('data', add).on('end', parse);
224+
res.on('data', add).on('end', passData);
209225
}
210226
}).on('error', function(err){
211227
(typeof callback === 'function')&&callback(err);
@@ -216,7 +232,7 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
216232
};
217233

218234
/**
219-
* Send a request and parse the JSON response data
235+
* Send a request and parse text response to JSON
220236
* @param {Object|String} options - Request options or just the URL as a string for a quick GET
221237
* {
222238
* url: '', // May be a relative path when accessing the discogs API
@@ -228,8 +244,11 @@ DiscogsClient.prototype._rawRequest = function(options, callback){
228244

229245
DiscogsClient.prototype._request = function(options, callback){
230246
(typeof options === 'string')&&(options = {url: options});
231-
return this._rawRequest(options, function(err, data){
232-
(typeof callback === 'function')&&callback(err, (data ? JSON.parse(data) : null));
247+
return this._rawRequest(options, function(err, data, rateLimit){
248+
if((typeof options === 'string') || (options.encoding !== 'binary')){
249+
data = JSON.parse(data)
250+
}
251+
(typeof callback === 'function')&&callback(err, data, rateLimit);
233252
});
234253
};
235254

lib/database.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ module.exports = function(client){
9191

9292
database.image = function(file, callback){
9393
if(client.authenticated()){
94-
client.get('/images/'+file, callback);
94+
client.get({url: '/image/'+file, encoding: 'binary'}, callback);
9595
}else{
9696
callback(new Error('You must be authenticated in order to retrieve an image.'));
9797
}

package.json

+10-25
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
11
{
22
"name": "disconnect",
3-
"description": "Easy to use client with OAuth support to connect with the discogs.com API v2.0",
4-
"version": "0.1.1",
5-
"keywords": [
6-
"discogs",
7-
"api",
8-
"client",
9-
"oauth"
10-
],
3+
"description": "Easy to use client to connect with the discogs.com API v2.0",
4+
"version": "0.2.0",
5+
"keywords": ["discogs", "api", "client", "oauth"],
6+
"homepage": "https://github.com/bartve/disconnect",
7+
"bugs": "https://github.com/bartve/disconnect/issues",
8+
"license": "MIT",
9+
"author": "Bart van Eijck <[email protected]>",
1110
"main": "index.js",
1211
"directories": {
1312
"lib": "./lib"
1413
},
15-
"author": {
16-
"name": "Bart van Eijck",
17-
"email": "[email protected]"
18-
},
1914
"repository": {
2015
"type": "git",
2116
"url": "https://github.com/bartve/disconnect.git"
2217
},
23-
"license": "MIT",
18+
"scripts": {},
2419
"dependencies": {
2520
"oauth-1.0a": "0.1.x"
2621
},
2722
"devDependencies": {},
2823
"engines": {
2924
"node": ">= 0.10.0"
30-
},
31-
"bugs": {
32-
"url": "https://github.com/bartve/disconnect/issues"
33-
},
34-
"homepage": "https://github.com/bartve/disconnect",
35-
"readme": "## About\r\n\r\n`disconnect` is a [Node.js](http://www.nodejs.org) client library that connects with the [Discogs.com API v2.0](http://www.discogs.com/developers/).\r\n\r\n## Features\r\n\r\n * Covers all API endpoints (well, soon anyway ;)\r\n * All functions implement the standard `function(err, data)` format for the callback\r\n * Includes OAuth 1.0a tools. Just plug in your consumer key and secret and do the OAuth dance\r\n * API functions grouped in their own namespace for easy access and isolation\r\n \r\n## Todo\r\n\r\n * Add collection folder functions (soon)\r\n * Add [rate limiting](http://www.discogs.com/developers/accessing.html#rate-limiting) support\r\n * Add tests\r\n\r\n## Installation\r\n\r\n`$ npm install disconnect`\r\n\r\n## Structure\r\nThe global structure of `disconnect` looks as follows:\r\n```\r\nrequire('disconnect') -> new Client() -> database()\r\n -> marketplace()\r\n -> user() -> collection()\r\n -> wantlist()\r\n -> util\r\n```\r\nTo get the user wantlist functions: \r\n```javascript\r\nvar Discogs = require('disconnect').Client;\r\nvar wantlist = new Discogs().user().wantlist();\r\n```\r\nMore examples below.\r\n\r\n## Usage\r\n\r\n### Basic\r\nHere are some basic usage examples that connect with the public API. Error handling has been left out for demonstrational purposes.\r\n\r\n#### Init\r\n\r\n```javascript\r\nvar Discogs = require('disconnect').Client;\r\n```\r\n#### Go\r\n\r\nGet release data\r\n```javascript\r\napp.get('/release/:id', function(req, res){\r\n\tvar db = new Discogs().database();\r\n\tdb.release(req.params.id, function(err, data){\r\n\t\tres.send(data);\r\n\t});\r\n});\r\n```\r\n\r\nGet page 2 of user's public collection showing 75 releases.\r\nThe second param is the collection folder ID where 0 is always the \"All\" folder.\r\n```javascript\r\napp.get('/collection/:user', function(req, res){\r\n\tvar col = new Discogs().user().collection();\r\n\tcol.releases(req.params.user, 0, {page:2, per_page:75}, function(err, data){\r\n\t\tres.send(data);\r\n\t});\r\n});\r\n```\r\n\r\nEasy!\r\n\r\n### OAuth\r\nBelow are the steps that involve getting a valid OAuth access token from Discogs.\r\n\r\n#### 1. Get a request token\r\n```javascript\r\napp.get('/authorize', function(req, res){\r\n\tvar dis = new Discogs();\r\n\tdis.getRequestToken(\r\n\t\t'CONSUMER_KEY', \r\n\t\t'CONSUMER_SECRET', \r\n\t\t'http://your-script-url/callback', \r\n\t\tfunction(err, requestData){\r\n\t\t\t// Persist \"requestData\" here so that the callback handler can \r\n\t\t\t// access it later after returning from the authorize url\r\n\t\t\tres.redirect(requestData.authorizeUrl);\r\n\t\t}\r\n\t);\r\n});\r\n```\r\n#### 2. Authorize\r\nAfter redirection to the Discogs authorize URL in step 1, authorize the application.\r\n\r\n#### 3. Get an access token\r\n```javascript\r\napp.get('/callback', function(req, res){\r\n\tvar dis = new Discogs();\r\n\tdis.getAccessToken(\r\n\t\trequestData, \r\n\t\treq.query.oauth_verifier, // Verification code sent back by Discogs\r\n\t\tfunction(err, accessData){\r\n\t\t\t// From this point on we no longer need \"requestData\", so it can be deleted\r\n\t\t\t// Persist \"accessData\" here so that it can be used to make further OAuth calls \r\n\t\t\tres.send('Received access token!');\r\n\t\t}\r\n\t);\r\n});\r\n```\r\n#### 4. Make OAuth calls\r\n```javascript\r\napp.get('/identity', function(req, res){\r\n\tvar dis = new Discogs(accessData);\r\n\tdis.identity(function(err, data){\r\n\t\tres.send(data);\r\n\t});\r\n});\r\n```\r\n\r\nNow that wasn't too hard, was it?\r\n\r\n## Resources\r\n\r\n * [Discogs API 2.0 documentation](http://www.discogs.com/developers/)\r\n * [The OAuth Bible](http://oauthbible.com/)\r\n\r\n## License\r\n\r\nMIT",
36-
"readmeFilename": "README.md",
37-
38-
"scripts": {},
39-
"_shasum": "a420a4a24288a1a5aed329555620b0db63f42921",
40-
"_from": "disconnect@"
41-
}
25+
}
26+
}

0 commit comments

Comments
 (0)