diff --git a/bin/soundcloud2000 b/bin/soundcloud2000 index 4e40656..3c004fd 100755 --- a/bin/soundcloud2000 +++ b/bin/soundcloud2000 @@ -2,4 +2,10 @@ require_relative '../lib/soundcloud2000' -Soundcloud2000.start +mode = ARGV.shift + +if mode == "--auth" + Soundcloud2000.authenticate(ARGV) +else + Soundcloud2000.start +end diff --git a/lib/soundcloud2000.rb b/lib/soundcloud2000.rb index ba4e038..831c9d4 100644 --- a/lib/soundcloud2000.rb +++ b/lib/soundcloud2000.rb @@ -1,8 +1,11 @@ require_relative 'soundcloud2000/client' require_relative 'soundcloud2000/application' +require_relative 'soundcloud2000/auth' module Soundcloud2000 - CLIENT_ID = '29f8e018e1272c27bff7d510a10da2a8' + CLIENT_ID = '29f8e018e1272c27bff7d510a10da2a8' + APP_FOLDER = File.expand_path("~/.soundcloud2000") + AUTH_FILE = File.join(APP_FOLDER, 'auth.json') def self.start client = Client.new(CLIENT_ID) @@ -15,4 +18,8 @@ def self.start application.run end + def self.authenticate(credentials) + auth = Soundcloud2000::Auth.new(credentials, CLIENT_ID) + auth.authenticate_and_save + end end diff --git a/lib/soundcloud2000/auth.rb b/lib/soundcloud2000/auth.rb new file mode 100644 index 0000000..3a882ec --- /dev/null +++ b/lib/soundcloud2000/auth.rb @@ -0,0 +1,62 @@ +module Soundcloud2000 + class Auth + def initialize(credentials, client_id) + @username, @password = credentials + @client_id = client_id + end + + def options + { + client_id: @client_id, + redirect_uri: 'http://developers.soundcloud.com/callback.html', + state: "SoundCloud_Dialog_#{token}", + response_type: 'code_and_token', + scope: 'non-expiring', + display: 'popup' + } + end + + def authenticate + uri_params = URI.escape(options.collect{|k,v| "#{k}=#{v}"}.join('&')) + + # need to fake the login window + login_window_request = Net::HTTP::Get.new("/connect?#{uri_params}") + login_window_result = request(login_window_request) + + # login with username and password + login_request = Net::HTTP::Post.new("/connect/login") + login_request.set_form_data(options.merge(username: @username, + password: @password)) + login_result = request(login_request) + + if login_result.code == '302' + access_token = login_result.body.match(/access_token=(.*)&/)[1] + else + puts "an error occured during authentication, please try again later" + end + end + + def authenticate_and_save + save(authenticate) + end + + def save(access_token) + return if access_token.nil? + File.open(AUTH_FILE, 'w') { |f| f.write(JSON.dump({access_token: access_token})) } + end + + def token + @token ||= rand(1000000).to_s(16) + end + + def request(request) + Net::HTTP.start('soundcloud.com', 443, use_ssl: true) do |http| + http.request(request) + end + end + + def self.access_token + JSON.parse(File.read(AUTH_FILE))["access_token"] + end + end +end diff --git a/lib/soundcloud2000/client.rb b/lib/soundcloud2000/client.rb index 6486223..f90902f 100644 --- a/lib/soundcloud2000/client.rb +++ b/lib/soundcloud2000/client.rb @@ -30,18 +30,30 @@ def request(type, path, params={}) params[:client_id] = client_id params[:format] = 'json' + req = if type == :post + _p = Net::HTTP::Post.new("#{path}?#{uri_escape params}") + _p.set_form_data(params) + _p + else + Net::HTTP::Get.new("#{path}?#{uri_escape params}") + end + Net::HTTP.start('api.soundcloud.com', 443, :use_ssl => true) do |http| - http.request(type.new("#{path}?#{uri_escape params}")) + http.request(req) end end def get(path, params={}) - JSON.parse(request(Net::HTTP::Get, path, params).body) + JSON.parse(request(:get, path, params).body) + end + + def post(path, params={}) + JSON.parse(request(:post, path, params).body) end def location(url) uri = URI.parse(url) - res = request(Net::HTTP::Get, uri.path) + res = request(:get, uri.path) if res.code == '302' res.header['Location'] end diff --git a/lib/soundcloud2000/models/player.rb b/lib/soundcloud2000/models/player.rb index 6f5ccd8..8786dbd 100644 --- a/lib/soundcloud2000/models/player.rb +++ b/lib/soundcloud2000/models/player.rb @@ -10,7 +10,7 @@ def initialize(logger) @logger = logger @track = nil @events = Events.new - @folder = File.expand_path("~/.soundcloud2000") + @folder = APP_FOLDER @seek_speed = {} @seek_time = {}