Giter Site home page Giter Site logo

disconnect's Introduction

About

disconnect is a Node.js client library that connects with the Discogs.com API v2.0.

Dependency Status

Features

  • Covers all API endpoints
  • Supports pagination, rate limiting, etc.
  • All database, marketplace and user functions implement a standard function(err, data, rateLimit) format for the callback or return a native JS Promise when no callback is provided
  • Easy access to protected endpoints with Discogs Auth
  • Includes OAuth 1.0a tools. Just plug in your consumer key and secret and do the OAuth dance
  • API functions grouped in their own namespace for easy access and isolation

Todo

  • Add more tests

Installation

NPM

Structure

The global structure of disconnect looks as follows:

require('disconnect') -> new Client() -> oauth()
                                      -> database()
                                      -> marketplace()
                                      -> user() -> collection()
                                                -> wantlist()
                                                -> list()
                      -> util

Usage

Quick start

Here are some basic usage examples that connect with the public API. Error handling has been left out for demonstrational purposes.

Init

var Discogs = require('disconnect').Client;

Go!

Get the release data for a release with the id 176126.

var db = new Discogs().database();
db.getRelease(176126, function(err, data){
	console.log(data);
});

Set your own custom User-Agent. This is optional as when omitted disconnect will set a default one with the value DisConnectClient/x.x.x where x.x.x is the installed version of disconnect.

var dis = new Discogs('MyUserAgent/1.0');

Get page 2 of USER_NAME's public collection showing 75 releases. The second param is the collection folder ID where 0 is always the "All" folder.

var col = new Discogs().user().collection();
col.getReleases('USER_NAME', 0, {page: 2, per_page: 75}, function(err, data){
	console.log(data);
});

Promises

When no callback is provided, the API functions return a native JS Promise for easy chaining.

var db = new Discogs().database();
db.getRelease(1)
	.then(function(release){ 
		return db.getArtist(release.artists[0].id);
	})
	.then(function(artist){
		console.log(artist.name);
	});

Output format

User, artist and label profiles can be formatted in different ways: plaintext, html and discogs. disconnect defaults to discogs, but the output format can be set for each client instance.

// Set the output format to HTML
var dis = new Discogs().setConfig({outputFormat: 'html'});

Discogs Auth

Just provide the client constructor with your preferred way of authentication.

// Authenticate by user token
var dis = new Discogs({userToken: 'YOUR_USER_TOKEN'});

// Authenticate by consumer key and secret
var dis = new Discogs({
	consumerKey: 'YOUR_CONSUMER_KEY', 
	consumerSecret: 'YOUR_CONSUMER_SECRET'
});

The User-Agent can still be passed for authenticated calls.

var dis = new Discogs('MyUserAgent/1.0', {userToken: 'YOUR_USER_TOKEN'});

OAuth

Below are the steps that involve getting a valid OAuth access token from Discogs. Note that in the following examples the app variable is an Express instance to handle incoming HTTP requests.

1. Get a request token

app.get('/authorize', function(req, res){
	var oAuth = new Discogs().oauth();
	oAuth.getRequestToken(
		'YOUR_CONSUMER_KEY', 
		'YOUR_CONSUMER_SECRET', 
		'http://your-script-url/callback', 
		function(err, requestData){
			// Persist "requestData" here so that the callback handler can 
			// access it later after returning from the authorize url
			res.redirect(requestData.authorizeUrl);
		}
	);
});

2. Authorize

After redirection to the Discogs authorize URL in step 1, authorize the application.

3. Get an access token

app.get('/callback', function(req, res){
	var oAuth = new Discogs(requestData).oauth();
	oAuth.getAccessToken(
		req.query.oauth_verifier, // Verification code sent back by Discogs
		function(err, accessData){
			// Persist "accessData" here for following OAuth calls 
			res.send('Received access token!');
		}
	);
});

4. Make OAuth calls

Simply provide the constructor with the accessData object persisted in step 3.

app.get('/identity', function(req, res){
	var dis = new Discogs(accessData);
	dis.getIdentity(function(err, data){
		res.send(data);
	});
});

Images

Image requests themselves don't require authentication, but obtaining the image URLs through, for example, release data does.

var db = new Discogs(accessData).database();
db.getRelease(176126, function(err, data){
	var url = data.images[0].resource_url;
	db.getImage(url, function(err, data, rateLimit){
		// Data contains the raw binary image data
		require('fs').writeFile('/tmp/image.jpg', data, 'binary', function(err){
			console.log('Image saved!');
		});
	});
});

Resources

License

MIT

disconnect's People

Contributors

0xflotus avatar bartve avatar joeyfromspace avatar pedro-otero avatar trott avatar wolf4ood avatar workeffortwaste avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

disconnect's Issues

Error integrating in Aurelia

Hello,
I'm using aurelia.io, and I'd like to use your npm package in my app.
I install it normally, typing npm install disconnect --save in the folder of my app.
I also edit aurelia.json correctly to insert in the vendor-bundle.js section :

          {
            "name": "disconnect",
            "path": "../node_modules/disconnect",
            "main": "index"
          },

Then I buikd my app typing au build, but I get this error:

{ uid: 8,
  name: 'writeBundles',
  branch: false,
  error: 
   { Error: ENOENT: no such file or directory, open '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js'
       at Object.fs.openSync (fs.js:558:18)
       at Object.fs.readFileSync (fs.js:468:33)
       at Object.exports.readFileSync (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/file-system.js:49:13)
       at fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/bundled-source.js:83:31)
       at Object.context.fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:176:18)
       at Object.context.load (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:357:30)
       at Module.load (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:832:29)
       at Module.fetch (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:822:66)
       at Module.check (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:854:30)
       at Module.enable (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:1173:22)
     errno: -2,
     code: 'ENOENT',
     syscall: 'open',
     path: '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js',
     moduleTree: [ 'disconnect/index' ],
     fileName: '/home/cesar/projets/aurelia/tracklist-manager/node_modules/disconnect/index.js' },
  duration: [ 4, 789092986 ],
  time: 1490043332523 }
{ uid: 0,
  name: '<series>',
  branch: true,
  error: 
   { Error: ENOENT: no such file or directory, open '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js'
       at Object.fs.openSync (fs.js:558:18)
       at Object.fs.readFileSync (fs.js:468:33)
       at Object.exports.readFileSync (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/file-system.js:49:13)
       at fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/bundled-source.js:83:31)
       at Object.context.fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:176:18)
       at Object.context.load (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:357:30)
       at Module.load (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:832:29)
       at Module.fetch (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:822:66)
       at Module.check (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:854:30)
       at Module.enable (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:1173:22)
     errno: -2,
     code: 'ENOENT',
     syscall: 'open',
     path: '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js',
     moduleTree: [ 'disconnect/index' ],
     fileName: '/home/cesar/projets/aurelia/tracklist-manager/node_modules/disconnect/index.js' },
  duration: [ 8, 704096699 ],
  time: 1490043332559 }
{ Error: ENOENT: no such file or directory, open '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js'
    at Object.fs.openSync (fs.js:558:18)
    at Object.fs.readFileSync (fs.js:468:33)
    at Object.exports.readFileSync (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/file-system.js:49:13)
    at fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/bundled-source.js:83:31)
    at Object.context.fileRead (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:176:18)
    at Object.context.load (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:357:30)
    at Module.load (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:832:29)
    at Module.fetch (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:822:66)
    at Module.check (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:854:30)
    at Module.enable (eval at <anonymous> (/home/cesar/projets/aurelia/tracklist-manager/node_modules/aurelia-cli/lib/build/amodro-trace/lib/loader/Loader.js:14:1), <anonymous>:1173:22)
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/home/cesar/projets/aurelia/tracklist-manager/disconnect/lib/util.js',
  moduleTree: [ 'disconnect/index' ],
  fileName: '/home/cesar/projets/aurelia/tracklist-manager/node_modules/disconnect/index.js' }

I don't know what's wrong...
If you can help me, it would be great :)

Problem with Client().database().getRelease()

Hi!

I have recently started to get multiple errors of type UnhandledPromiseRejectionWarning while using Problem with Client().database().getRelease(), even though I do have a catch block in place in my code.

This is the error:

(node:43691) UnhandledPromiseRejectionWarning: DiscogsError: Unknown error.
    at IncomingMessage.passData (/<path-to-my-project>/node_modules/disconnect/lib/client.js:212:23)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:43691) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)

And this is my code:

public getRelease({ id }): Promise<any> {
  return new Promise((resolve, reject) => {
    const db = new Client(this.token).database();

    db.getRelease(id)
      .then(response => resolve(response))
      .catch(error => reject(error));
  });
}

Am I doing something wrong? This has been working for months, it's only recently that I started to get this error ocasionally.

Thank you!

Rate Limiting Example in ReadMe?

Hey, not so much an issue but I can't seem to get rate limiting to work and I notice that theres no documentation for it in the readme. I've tried to replicate from the queue.js file but I'm still getting

{ [DiscogsError: Too many requests] statusCode: 429, message: 'Too many requests' }

Any chance of including an example?

Thanks for the awesome tool :)

Client.get no method .get

I get an internal error in database.js saying client doesn't have a method get.

Given the following code:

var Discogs = require('disconnect').Client;
var dis;

function setupDiscogs(apiKey) {
    dis = new Discogs('HowMuchIsTheFish/1.0', {userToken: apiKey});

    var db = new dis.database();
    db.search(
    "Mind the gap",
    {
        "type": "release",
        "artist": "scooter",
        "year": "2004"
    }, function(err, data) {
        if (err) {
            console.log(err);
        } else {
            console.log(data);
        }
    });
}

This produces the following result:

/Users/x/node_modules/disconnect/lib/database.js:113
        client.get({url: util.addParams('/database/search', obj), authLevel: 1}, cal
               ^
TypeError: Object [object Object] has no method 'get'
    at Object.database.search (/Users/x/node_modules/disconnect/lib/database.js:113:10)
    at setupDiscogs (/Users/x/source/howmuchisthe.fish/app.js:282:8)

Getting Next Page Of Search?

I see that search calls are returning the pagination object from Discogs, but since the search call doesn't let me specify a page to return, what's the correct way to page through results?

Thanks!

including disconnect in react app

Hi, i found your library for Discocgs, but i have a problem including it in my app.

I tried many ways:
import Discogs from 'disconnect/lib/client'
import Discogs from 'disconnect';
var Discogs = require('disconnect').Client;

Every time i get this error:

ERROR in ./~/disconnect/package.json
Module parse failed: C:\WORK\budgies\node_modules\disconnect\package.json Unexpected token (2:8)
You may need an appropriate loader to handle this file type.
SyntaxError: Unexpected token (2:8)

I googled and found and tried many things like: http://stackoverflow.com/questions/33469929/you-may-need-an-appropriate-loader-to-handle-this-file-type-with-webpack-and-b

My webpack.js is like this:

`var path = require('path')
var webpack = require('webpack')

module.exports = {
devtool: 'cheap-module-eval-source-map',
entry: [
'webpack-hot-middleware/client',
'./index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
module: {
loaders: [
{
test: /.js$/,
loaders: [ 'babel' ],
exclude: /node_modules/,
include: __dirname
}
]
}
}
`

My package.json is like this:

{ "name": "redux-todomvc-example", "version": "0.0.0", "description": "Redux TodoMVC example", "scripts": { "start": "node server.js", "test": "NODE_ENV=test mocha --recursive --compilers js:babel-core/register --require ./test/setup.js", "test:watch": "npm test -- --watch" }, "repository": { "type": "git", "url": "https://github.com/rackt/redux.git" }, "license": "MIT", "bugs": { "url": "https://github.com/rackt/redux/issues" }, "homepage": "http://rackt.github.io/redux", "dependencies": { "babel-polyfill": "^6.3.14", "classnames": "^2.1.2", "es6-promise": "^3.1.2", "isomorphic-fetch": "^2.2.1", "react": "^0.14.6", "react-bootstrap": "^0.28.4", "react-dom": "^0.14.6", "react-redux": "^4.0.6", "react-youtube": "^5.1.0", "redux": "^3.0.6", "redux-persist": "^4.0.0-alpha7", "redux-sequence-action": "^0.2.0", "redux-thunk": "^0.1.0", "immutability-helper": "^2.0.0", "disconnect": "^1.0.2" }, "devDependencies": { "babel-core": "^6.3.15", "babel-loader": "^6.2.0", "babel-preset-es2015": "^6.3.13", "babel-preset-react": "^6.3.13", "babel-preset-react-hmre": "^1.1.1", "babel-register": "^6.3.13", "expect": "^1.8.0", "express": "^4.13.3", "jsdom": "^5.6.1", "json-loader": "^0.5.4", "mocha": "^2.2.5", "node-libs-browser": "^0.5.2", "raw-loader": "^0.5.1", "react-addons-test-utils": "^0.14.0", "react-transform-hmr": "^1.0.0", "style-loader": "^0.12.3", "todomvc-app-css": "^2.0.1", "webpack": "^1.9.11", "webpack-dev-middleware": "^1.2.0", "webpack-hot-middleware": "^2.2.0" } }

I also have babelrc:

{ "presets": ["es2015", "react"], "env": { "development": { "presets": ["react-hmre"] } } }

What is wrong? Cannot i use disconnect like this?

CORS Error on res.redirect() to OAuth authorizeURL -- Ngrok, Express, Ubuntu

Hi devs,

hope this is the right place to ask this. I've got a Node/Express server on an Ubuntu DigitalOcean droplet and I'm using Ngrok to get a HTTP/S tunnel to the port exposed by the Express app.

Following the OAuth code template in the README, I successfully get the authorizeURL from Discogs, but cannot res.redirect() there without running into:

Access to XMLHttpRequest at 'https://www.discogs.com/oauth/authorize?oauth_token=foobar' (redirected from 'https://foo.ngrok.io/authorize') from origin 'https://foo.ngrok.io' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I can, however, manually open a new tab in the browser and grant access via that URL. My server script is copied below. The thing that's confusing me is that the initial GET request to the Discogs authorize endpoint returns successfully with a 302 status code with the same request (https://foo.ngrok.io) origin. Any ideas about what it is I am not understanding? Any other information needed from me to help debug? Any help/links/references are much appreciated, thank you.

Nick

[Edit: I should maybe note: I'm tunneling to the server because at some point the client will trigger the authorization process on my website in their browser]

#!/usr/bin/env nodejs
'use strict';
const express = require('express');
const app = express();
const port = 8080;
const Discogs = require('disconnect').Client;
const keys = require('./private/consumer.keys.json');
const KEY = keys.installed.key;
const SECRET = keys.installed.secret;
let requestData = ''

app.get('/', (req, res) => res.sendFile('index.html', { root: __dirname + '/public/'}));

app.get('/authorize', function(req, res){
	let oAuth = new Discogs().oauth();
	oAuth.getRequestToken(
		`${KEY}`,
		`${SECRET}`,
		'https://foo.ngrok.io/handleRequestTokenResponse',
		function(err, data){
			if (data){
				requestData = data
				console.log('authorizeURL: ' + data.authorizeUrl);
			}
			res.redirect(data.authorizeUrl);
		}
	);
});

Handle statusMessage: 'Too Many Requests' ?

During my tests i run into this http response a few times:

statusCode: 429, statusMessage: 'Too Many Requests',

But the library only yields an error saying "DiscogsError: Unknown error."

Would it be possible to yield a more descriptive error in this case?

Also, I'm wondering if wouldn't be better to have some settings on the library to automatically "cool down" ( wait a 1 minute ) and retry the call again if a message like that happens?

Also: can't thank you enough for the work you have put into this library, thank you!

"Unexpected token u" when request fails

Some calls have been throwing this error after some delay:

SyntaxError: Unexpected token u
    at Object.parse (native)
    at C:\dev\node_modules\disconnect\lib\client.js:279:18
    at ClientRequest.<anonymous> (C:\dev\node_modules\disconnect\lib\client.js:254:37)
    at ClientRequest.emit (events.js:95:17)
    at Socket.socketErrorListener (http.js:1547:9)
    at Socket.emit (events.js:95:17)
    at net.js:440:14
    at process._tickCallback (node.js:419:13)

The line in question is just the parsing of the json response:

DiscogsClient.prototype._request = function(options, callback){
    var self = this;
    (typeof options === 'string')&&(options = {url: options});
    queue.add(function(err){ // Add API request to the execution queue
        if(!err){
            self._rawRequest(options, function(err, data, rateLimit){
                if((typeof options === 'string') || (options.encoding !== 'binary')){
                    data = JSON.parse(data) // line 279
                }
                (typeof callback === 'function')&&callback(err, data, rateLimit);
            });
        }else{
            callback(err);
        }
    });
};

The error "unexpected token u" makes me suspect data was undefined and that value got cast as a string. This is consistent with the fact that I was having connectivity problems -- it just means the request failed. But a failed request is a normal case, and it shouldn't cause an error to be thrown. It looks like the code expected err to be populated in cases where data is undefined, but apparently it isn't always...

Cannot access to my data w/ OAuth or userToken

I try to connect to my inventory but everytime I get zero items.

const express = require('express');
const storage = require('node-persist');
const bodyParser = require('body-parser');
const Discogs = require('disconnect').Client;
const app = express();

storage.init();

app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs');

app.get('/', function (req, res) {
  res.render('index');
});

app.get('/authorize', function(req, res){
  var oAuth = new Discogs().oauth();
  oAuth.getRequestToken(
    'myconsumerKey',
    'myconsumerSecret',
    'http://localhost:8080/callback',
    function(err, requestData){
      storage.setItem('requestData', requestData);
      res.redirect(requestData.authorizeUrl);
    }
  );
});

app.get('/callback', function(req, res){
  storage.getItem('requestData').then((requestData) => {
    var oAuth = new Discogs(requestData).oauth();
    oAuth.getAccessToken(
      req.query.oauth_verifier,
      function(err, accessData){
        storage.setItem('accessData', accessData);
        res.redirect('/identity');
      }
    );
  });
});

app.get('/identity', function(req, res){
  storage.getItem('accessData').then((accessData) => {
    var dis = new Discogs(accessData);
    dis.getIdentity(function(err, data){
      res.send(data);
    });
  });
});

app.get('/inventory', function(req, res){
  storage.getItem('accessData').then((accessData) => {
    var col = new Discogs(accessData).user().getInventory();
    col.then((a) => {
      console.log(a);
    });
  });
});

app.listen(8080, function () {
  console.log('Example app listening on port 8080!');
});

The output in "inventory" method is just.:

{ pagination: { per_page: 50, items: 0, page: 1, urls: {}, pages: 1 },
listings: [] }

0 items. Also when I try to show my profile, the urls are missing my username. There is just "undefined" in the link. It would look like this.:

app.get('/profile', function(req, res){
  storage.getItem('accessData').then((accessData) => {
    var profile = new Discogs(accessData).user().getProfile();
    profile.then((a) => {
      console.log(a);
    });
  });
});

The output is:

{ profile: '',
  banner_url: '',
  wantlist_url: 'https://api.discogs.com/users/undefined/wants',
  seller_num_ratings: 0,
  rank: 4,
  is_staff: false,
  num_pending: 1,
  id: 1032059,
  marketplace_suspended: false,
  buyer_rating: 0,
  num_for_sale: 0,
  home_page: '',
  location: '',
  collection_folders_url: 'https://api.discogs.com/users/undefined/collection/folders',
  username: 'undefined',
  collection_fields_url: 'https://api.discogs.com/users/undefined/collection/fields',
  releases_contributed: 1,
  activated: true,
  registered: '2011-02-11T13:18:35-08:00',
  rating_avg: 5,
  num_collection: 1,
  releases_rated: 1,
  curr_abbr: 'EUR',
  seller_rating_stars: 0,
  num_lists: 0,
  name: '',
  buyer_rating_stars: 0,
  num_wantlist: 0,
  inventory_url: 'https://api.discogs.com/users/undefined/inventory',
  uri: 'https://www.discogs.com/user/undefined',
  buyer_num_ratings: 0,
  avatar_url:
   'https://secure.gravatar.com/avatar/ee0787acbde96eba8f230d13c0e798e9?s=500&r=pg&d=mm',
  resource_url: 'https://api.discogs.com/users/undefined',
  seller_rating: 0 }

You see a lot of "undefined" values in the urls.
What I'm doing wrong?

database.search not working when query is ommited and params object is passed

I came across this issue when trying to perform this search:

/database/search?artist=Lana Del Rey&title=Honeymoon&type=master

There is no query parameter. This search runs ok with an http client returning 2 results. So I invoke the search function like this:

db.search({artist: 'Lana Del Rey', title: 'Honeymoon', type: 'master'})

And disconnect ignores my params object altogether. In the response I get pagination.urls.last is https://api.discogs.com/database/search?q=&per_page=50&page=1000.

Collection value support

Hi,

I forked the project as I'm trying to include the collection value API all (https://www.discogs.com/developers/#page:user-collection,header:user-collection-collection-value).

I made the following change in collection.js:

/**
	 * Gets the colection value for the given user.
	 * @param {string} user - The user name
	 * @returns {DiscogsClient|Promise}
	 */
	collection.getValue = function(user, callback) {
		return client.get({ url: '/users/' + util.escape(user) + '/collection/value', authLevel: 2 }, callback);
	}

I have successfully obtained a token and a tokenSecret using the oath method calls, and I got an object that pretty much looks like this:

{
  "method": "oauth",
  "level": 2,
  "consumerKey": "consumerKey",
  "consumerSecret": "consumerSecret",
  "token": "token",
  "tokenSecret": "tokenSecret"
}

I can use that object to make requests to the user lists, and I do get lists which are marked as private, so in theory, the token+secret are working as expected.

However, when I call the collectionValue method, I get:

DiscogsError: You are not allowed to view this resource. Please authenticate as the owner to view this content.

I don't know if this is an error in my implementation, or if the Discogs API endpoint is bogus.

If you could provide some info, that'd be great.

Thanks,
Jose.-

sorting releases from marketplace

I can't see the examples of using the marketplace. I'm trying to get only the recently added records from the store, is it possible?

Error ReferenceError: requestData is not defined

I'm new to node and disconnect. I get a error Error: ReferenceError: requestData is not defined here

app.get('/callback', function(req, res){ var oAuth = new Discogs(requestData).oauth(); <=== Error ReferenceError: requestData is not defined oAuth.getAccessToken( req.query.oauth_verifier, // Verification code sent back by Discogs function(err, accessData){ // Persist "accessData" here for following OAuth calls res.send('Received access token!'); } ); });

Need some help. Thanks!

Receiving error on larger requests

Hi, Iยดm using the promise query of disconnect (NodeJS) library, like:

await dis.getRelease(collection.main_release) .then((result)=>{ discogsAlbums.push(result) }) .catch((error)=>{ console.log(error) })

But, sometimes I need to run a loop and query all artist albuns, which I'm receiving the ratelimit error from Discogs. Do I need to set up the rate limit or is it already defined by default?
With small queries everything runs fine. Do you have any suggestions on how to run this inside a loop without reach the ratelimit per-minute restriction?

My error is: discogs status code 429

I'm using my key, secret and agent ID correctly.

thanks

Getting 401 on /identity example

Cheers for the lib. Well handy. I'm just having a little trouble...

I'm passing back the access data (stored in session using session-cookie) using:

app.use('/identity', function(req, res) {
    var dis = new Discogs(req.session.accessData);

    dis.getIdentity(function(err, data) {
        console.log(err);
        res.end(data);
    });
});

and req.session.accessData has all the right keys present but I still get this back:

AuthError: You must authenticate to access this resource.

Any help would be appreciated ๐Ÿ‘

Identity AuthError: You must authenticate to access this resource

I have an accssData object in the format below with values obtained from all the authentication steps but when used in the identity example I receive the following error:

AuthError: You must authenticate to access this resource

accessData { method: 'oauth',
  level: 0,
  consumerKey: 'xxx',
  consumerSecret: 'xxx',
  token: 'xxx',
  tokenSecret: 'xxx',
  authorizeUrl:
   'https://www.discogs.com/oauth/authorize?oauth_token=xxx' }

It looks as if the requestData and accessData object are the same. Is this the issue? Please assist.

Andy

requestData is out of scope in get("/callback") request

Had to define requestData as a global variable to use in the get request for the callback URL.

let _requestData;
app.get("/authorize", function(req, res) {
  var oAuth = new Discogs().oauth();
  oAuth.getRequestToken(
    "sdfasdfadslfkjasdhf",
    "asdlfkjahsdflkajsdhf",
    "http://localhost:3000/callback",
    function(err, requestData) {
      _requestData = requestData;
      // Persist "requestData" here so that the callback handler can
      // access it later after returning from the authorize url
      res.redirect(requestData.authorizeUrl);
    }
  );
});

app.get("/callback", function(req, res) {
  var oAuth = new Discogs(_requestData).oauth();
  oAuth.getAccessToken(
    req.query.oauth_verifier, // Verification code sent back by Discogs
    function(err, accessData) {
      // Persist "accessData" here for following OAuth calls
      res.send("Received access token!");
    }
  );
});

Is the code above how you had intended the package to be used? A more complete example of these get requests in action would be helpful to understand their uses.

Need more usage examples. It's a real struggle to decipher.

At first, I thought the documentation for this library was going to be really good. The README.md shows how to instantiate the client, make a simple request, set output format, authenticate a few different ways and then...

... it just sort of drops off, leaving the user completely hanging. I've had to dig into the source code (including test files) to figure out how to make certain requests. But there's a lot of discogs API functionality that is a complete mystery.

A little bit of usage documentation would go a very long way. Specifically,

  • How to handle pagination
  • What functions are available and what syntax is required?
  • How to use the queue

I think this library could be useful and helpful to me, but without documentation, I may have to simply homebrew a client direct to the URLs in the Discogs main documentation so I can tell what I'm doing. Which would really be a shame since this library/utility is sitting here begging to be used.

edit: The name of the repo is unfortunate, too. Try googling "disconnect documentation" and see how far that gets you.

Search not working with Promise

Hey, great library. Nice with automatic rate limiting.

Database searching with Promise is not working for me however. For example

db.search('skrillex', { type: 'label' }, (err, res) => {
  console.log(res);
})

is returning just five items like their own API with https://api.discogs.com/database/search?q=skrillex&type=label&token=[redacted]. However if I am using a Promise like

db.search('skrillex', { type: 'label' })
  .then(console.log)

I get 870 items with all sorts of different results. Basically everything with Skrillex I assume.

Should it instead of this

if(arguments.length <= 2){
	if(typeof params === 'function'){ callback = params; } // No extra search params, the callback is the second function param
}else{
	obj = params;
}

just be a simple && check

if(arguments.length <= 2 && typeof params === 'function'){
	callback = params; // No extra search params, the callback is the second function param
}else{
	obj = params;
}

since the length is <= 2 but params is not a function, obj should just be set to params. I will create a pull request for you, just checking first that the logic is sound.

Output format doesn't seem to work

Hi, I'm trying to use the setConfig method to set the output format but it always returns the "Discogs" format.

const Discogs = require('disconnect').Client
const client = new Discogs().setConfig({outputFormat: 'html'})
const db = client.database()

// Route that fetches the profile of 'Michael Jackson' artist.
// Hopefully it'll be in HTML.
app.get('/', async (req, res) => {
  const data = await db.getArtist('15885')
  res.json(data.profile)
})

Am I doing it wrong? Here's a test case:

Readme

Forgive me if I'm missing something because I'm new to nodejs, but in the tutorial you use an 'app' variable without ever defining it, I was playing around with your module and the only way I could successfully get a request (going from your first example) was to make the following changes:

var Discogs = require('disconnect').Client;
var dis = new Discogs();
dis.get('/releases/:id', function(req, res){
    var db = new Discogs().database();
    db.release(req.params.id, function(err, data){
        res.send(data);
    });

note how app was changed to the Discogs object, release was changed to 'releases' (I don't see a 'release' action here: http://www.discogs.com/developers/#page:database,header:database-release).

Also, in that example code, the db.release callback will fail because req is null.

I'm I missing something from my inexperience? Is this the proper way to use your api wrapper?

How solve 403 Error?

How I authenticate with a owner and solve that error?

DiscogsError: 403 You are not allowed to view this resource. Please authenticate as the owner to view this content.

How to get Master Release by ID?

Thanks for an awesome module!

Looks like master release id and regular release id are not the same.

How to get master release by id?

I am aware of db.getRelease, but it doesn't work for master releases, but only for regular ones.

db.getRelease(176126, function(err, data){
	console.log(data);
});

Thanks!

ECMAScript 6

Research + start implementation of the most widely supported new ECMAScript 6 elements and syntax.

Unwinding sub-arrays

For example, sub_tracks. In release #10798921 I find this:

...
tracklist:
[ { duration: '7:48',
position: '1',
type_: 'track',
title: 'Overture: Coriolan, Opus 62' },
{ duration: '46:51',
position: '',
type_: 'index',
sub_tracks: [Array],
title: 'Symphony No.3 in Eb Major Opus 22 'Eroica'' } ],
...

The sub_tracks and especially their timings are exactly what I'm trying to get at in my project. How can I accomplish this?

Empty images uri

Hi Bart!

As written in the README, image URLs require auth.

Image requests themselves don't require authentication, but obtaining the image URLs through, for example, release data does.

However it is not clearly specified which type of auth. Providing a key and a secret while instanciating Disconnect does not seem to be enough as images URLs are always empty.

I tried setting the Authentication header via curl as well and same result.

Is it really mandatory to setup OAuth to get images URLs or am I doing something wrong ?

Thanks!

Search URI encoding

Currently database.search uses util.escape and util.addParams (with querystring.stringify inside) to encode a request URI. At least on my PC this results into wrong encoding for which discogs always returns zero results. For example, the query Theory & DanJah Wise - Tribulation gets encoded as /database/search?q=Theory%2520%2526%2520DanJah%2520Wise%2520-%2520Tribulation. When I change it to

client.get({url: "/database/search?q=" + encodeURIComponent(query), authLevel: 1}, callback);

it encodes as /database/search?q=Theory%20%26%20DanJah%20Wise%20-%20Tribulation and everything works fine (discogs returns a result).

orders method with order ID

The orders method is documented in the comments as being intended to be overloaded to accept either a single order ID or query parameters to retrieve multiple orders. However it thinks order IDs are numbers and anything else is a parameters object. In actuality order IDs are not numbers, they are strings -- they always contain a hyphen. As such it is not currently possible to retrieve a single order.

/**
 * List your orders or get the details of one order
 * @param {object|number} [params] - The optional sorting and pagination params or the order ID
 * @param {function} [callback] - The callback
 */

marketplace.orders = function(params, callback){
    var path = '/marketplace/orders';
    if((arguments.length === 1) && (typeof params === 'function')){
        callback = params;
    }else{
        if(isNaN(params)){
            path = util.addParams(path, params);
        }else{ // Params is the order ID
            path += '/'+params;
        }
    }
    client.get({url: path, requireAuth: true}, callback);
};

Get image error

Getting images through the getImage function doesn't work anymore and returns the following:

{ DiscogsError
at IncomingMessage.passData (/Users/silvereletellier/dev/ChezEmile/node_modules/disconnect/lib/client.js:212:23)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:188:7)
at endReadableNT (_stream_readable.js:974:12)
at _combinedTickCallback (internal/process/next_tick.js:80:11)
at process._tickDomainCallback (internal/process/next_tick.js:128:9) statusCode: 500, message: 'Unknown error.' }

'\n\n\n<title>Fastly error: unknown domain api.discogs.com</title>\n\n\n

Fastly error: unknown domain: api.discogs.com. Please check that this domain has been added to a service.'

Furthermore when I try and download an image with the request module I get the following http response:

503 - Service Unavailable

Any idea?

Support for browsers

Hi! Do I understand correctly that the lib works only in NodeJS environment at the moment?

As I can see there are three NodeJS modules used:

  • https
  • zlib
  • url

https

https is used in the client.js. The only method is needed is request. It should be easy to replace it with a cross-platform lib.

zlib

I'm not sure is it possible to implement its functional in browser at all?

url

If I correctly understand it's already implemented:
https://www.npmjs.com/package/url

Missing referenced dependencies

Thanks for putting this together. I arrived here from a link in the Discogs API documentation.

While testing things out I noticed some of this project's library files reference node modules which are not listed in the package.json dependency manifest. Examples include querystring in lib/util.js, and https and zlib in lib/client.js.

I tried installing the missing dependencies manually but got hung up on a node-waf error installing zlib, which is currently deprecated yet required by this project.

Any pointers?

Marketplace Fee argument type

The annotation for this method defines the price argument as

@param {Float} price - The price as a float

However this will only work if the value has significant digits to the penny. It does work with a string, however. To fix this, a numerical price argument could be cast as a string with .toFixed(2) before submission.

discogs.marketplace().fee(10.00, log);
> { [DiscogsError: The requested resource was not found.] (...etc)

discogs.marketplace().fee('10.00', log);
> { currency: 'USD', value: 0.8 }

Question about getItems() of a list

I need help to get the items of a existing list. (/lists/list_id)
My current source looks like this...Browser get no response and waiting forever

app.get('/list/:nList', function(req, res){
    var accessData = app.get('accessData');
    var user = new Discogs(accessData).user();
    // req.params.sUser;
    if (validator.isNumeric(req.params.nList) === true) {
     console.log('user.list:', req.params.nList);      // <= I found this logging in console
     user.list(req.params.nList, function(err, data){
         console.log(data);
         res.send(data);
     });     
    } else {
     res.send({'error': 2});     
     console.log(req.params.nList);
    }
);

Don't know what's wrong

Promises not returned

Hello!

Getting started with Disconnect, and noticed that the documentation mentions: 'When no callback is provided, the API functions return a native JS Promise for easy chaining, ' but this does not seem to be implemented, unless I'm misunderstanding. Is this a planned future feature?

thanks!
Jason

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.