spotify-export icon indicating copy to clipboard operation
spotify-export copied to clipboard

undefined method `each' for nil:NilClass

Open OwenRay opened this issue 8 years ago • 14 comments

The application throws an exception when trying the example command:

$ ./bin/spotify-export.rb spec/support/multiple-tracks.txt

/Users/owenray/spotify-export/lib/spotify-track.rb:49:in `format_artists': undefined method `each' for nil:NilClass (NoMethodError)
	from /Users/owenray/spotify-export/lib/spotify-track.rb:82:in `get_track_attributes'
	from /Users/owenray/spotify-export/lib/spotify-track.rb:32:in `attributes'
	from /Users/owenray/spotify-export/lib/spotify-track.rb:22:in `name'
	from bin/spotify-export.rb:23:in `block in <main>'
	from bin/spotify-export.rb:20:in `each'
	from bin/spotify-export.rb:20:in `each_with_index'
	from bin/spotify-export.rb:20:in `<main>'

Running on macOS Sierra 10.12.5 ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin16]

OwenRay avatar Jul 04 '17 13:07 OwenRay

just noticed this gets resolved by https://github.com/jlund/spotify-export/pull/14

OwenRay avatar Jul 04 '17 13:07 OwenRay

I have the same issue here, but In my case #14 does not solve the problem, it causes infinite recursion. The problem seems that artists parameter is null, not a typo.

xaviarias avatar Jul 10 '17 15:07 xaviarias

I'm getting it here too. git reset'ed (9/17/2017). Anyone found a solution for this? Thanks

fredericoabraham avatar Sep 17 '17 15:09 fredericoabraham

The problem is that the API call to Spotify in lib/spotify-track.rb is returning a 401 because no token is passed with the request. As stated by the API used in this gem, https://developer.spotify.com/web-api/get-track/ you will need to implement an Authorization workflow (https://developer.spotify.com/web-api/authorization-guide/) to generate a user token that will be passed in the requests to Spotify.

BachirC avatar Oct 17 '17 13:10 BachirC

How I made it work :

  • Create a spotify app at https://developer.spotify.com/my-applications/#!/applications/create

  • Use the Client Credential workflow to get an api token from Spotify https://developer.spotify.com/web-api/authorization-guide/#client-credentials-flow

For this part, you will need to Base64 encode the string client_id:client_secret of your Spotify app. I used this https://www.base64encode.org/. Also, beware to pass the grant_type params in the body and not as an URL-encoded param otherwise you will get a 400.

  • You get the access_token (expires in 1 hour) in the response. I added two lines to the code (last ones) :

lib/spotify-track.rb

  def get_track_attributes
    if local
      local_array = uri.split(':')

      # The array should be length 6
      # ["spotify", "local", "artist", "album", "song title", "duration"]
      name   = URI.decode(local_array[4].gsub('+', ' '))
      album  = URI.decode(local_array[3].gsub('+', ' '))
      artist = URI.decode(local_array[2].gsub('+', ' '))
    else
      track_id = uri[/track(:|\/)(.+)/, 2]
      target  = URI.parse("https://api.spotify.com/v1/tracks/#{ track_id }")
      http    = Net::HTTP.new(target.host, target.port)
      http.use_ssl = true
      request = Net::HTTP::Get.new(target.request_uri)
      access_token = "Zwejkrhqwlkrq..."
      request['Authorization'] = "Bearer #{access_token}"

If I have some time, I'll do a PR to allow a user to pass the access token directly in the args when launching the script (the access token generation will be done manually as I explained above). It is not optimal as the token will stay in your bash history but for now it'll do and I'm sure we'll come up with a better solution. Hope this helps.

⚠️ Don't commit or share your Spotify token.

BachirC avatar Oct 17 '17 14:10 BachirC

Hi. Still trying to make this work. Does the token look something like this after base 64 encode? (I messed with it so it's wrong):

  access_token = "YTU5YTc3AmVmADk4NDI2M2E2MGU2ZTU4NGFiYWYyM2Y="

Thanks.

fredericoabraham avatar Nov 07 '17 05:11 fredericoabraham

Looks like it, yes. Did you try it out ?

BachirC avatar Nov 15 '17 13:11 BachirC

Ok wait didn't read well. It's not the token that should be base64 encoded, it is the string client_id:client_secret.

Checkout the second link I posted in my workflow, it is well explained.

BachirC avatar Nov 15 '17 13:11 BachirC

Still throwing me the same exception, even with adding the access token (which I obtained with curl passing the base64 string) to spotify-track.rb. When encoding the client id and secret to base64, does the string need to follow the exact 'client_id:client_secret" format, with the colon in the middle?

Thanks.

glfaulkner avatar Jul 08 '18 18:07 glfaulkner

It works, cheers!

regisbsb avatar Aug 08 '18 14:08 regisbsb

@glfaulkner Yes it does.

BachirC avatar Oct 13 '18 14:10 BachirC

Hello all. I've been trying to use spotify-export again, but haven't been able to log in to the developer site. Wanted to know if you guys could: https://developer.spotify.com/ https://developer.spotify.com/web-api/get-track/ I try to log in, when clicking on dashboard shows the same as before, as if I wasn't logged in.

Thanks, -- Fred

On Sat, Oct 13, 2018 at 11:10 AM Bachir [email protected] wrote:

@glfaulkner https://github.com/glfaulkner Yes it does.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/jlund/spotify-export/issues/17#issuecomment-429545186, or mute the thread https://github.com/notifications/unsubscribe-auth/ABLxdlRlJvF9utS2w5F1btQKn_Be9OP3ks5ukfQ5gaJpZM4ONXwC .

-- -- Fred

fredericoabraham avatar Nov 20 '19 21:11 fredericoabraham

@snakenerd works for me, I'm logging in with username & password if that helps.

OwenRay avatar Nov 21 '19 07:11 OwenRay

Complementing the awesome instructions above, for those who are as new to javascript as me, you need to run the following script (adapted from the example from Spotify that's not directly runnable 😂):

var request = require('request'); // "Request" library

var client_id = 'YOUR CLIENT ID';
var client_secret = 'YOUR CLIENT SCRET';

var authOptions = {
  url: 'https://accounts.spotify.com/api/token',
  headers: {
    'Authorization': 'Basic ' + (new Buffer(client_id + ':' + client_secret).toString('base64'))
  },
  form: {
    grant_type: 'client_credentials'
  },
  json: true
};

request.post(authOptions, function(error, response, body) {
  if (!error && response.statusCode === 200) {
    var token = body.access_token;
    console.log(token);
  }
});

So the steps are:

  1. Save the snippet above into a file called fetch_token.js. Fill in the client_id and client_secret. You don't have to encode them to base64 since Buffer does it for you.
  2. You can run it with, for example, nodejs: node fetch_token.js
  3. It will return your with a token, you don't have to encode or decode it any further, just copy it.
  4. change te lib/spotify-track.rb as suggested above, fill in your copied token in the line access_token = "...".
  5. Run ./bin/spotify-export.rb your_playlist.text

yijiangh avatar Sep 21 '22 15:09 yijiangh