Skip to content

Instantly share code, notes, and snippets.

@rguggemos
Created April 12, 2011 19:50
Show Gist options
  • Save rguggemos/916242 to your computer and use it in GitHub Desktop.
Save rguggemos/916242 to your computer and use it in GitHub Desktop.
class SoundcloudAccount < ActiveRecord::Base
belongs_to :user
validates_presence_of :user, :on => :create, :message => "can't be blank"
validates_uniqueness_of :sc_user_id, :message => "must be unique"
def get_tracks
if self.sc_user_id.present?
client = self.get_client
logger.debug "trying to get users/#{self.sc_user_id}/tracks"
begin
@tracks = client.get("/users/#{self.sc_user_id}/tracks")
rescue Soundcloud::ResponseError => e
logger.debug "error!\n#{e.inspect}"
#re-raise this error
raise e
@tracks = nil
ensure
[]
end
end
end
def get_track_from_song(song)
if self.sc_user_id.present?
client = self.get_client
logger.debug "trying to get tracks/#{song.soundcloud_track.track_id}"
begin
@track = client.get("/tracks/#{song.soundcloud_track.track_id}")
rescue Soundcloud::ResponseError => e
logger.debug "error!\n#{e.inspect}"
raise e
@track = nil
ensure
nil
end
end
end
def expired?
(self.token_expires_at.nil? || self.token_expires_at < Time.now)
end
def create_track_from song
require 'open-uri'
begin
file = open song.url
mp3_filename = file.path + ".mp3"
#The file needs a *.mp3 name in order to be accepted by the API
File.rename file.path, mp3_filename
file = File.new mp3_filename
track_response = get_client.post('/tracks',
:track => {:title => song.title,
:asset_data => file,
:sharing => 'private'}
)
SoundcloudTrack.create(:secret_token => track_response[:secret_token],
:track_id => track_response[:id],
:sc_user_id => track_response[:user][:id]
)
rescue => e
logger.info e.message
ensure
File.delete file.path if file #clean up
end
end
# Background it by default
def move_all
SoundcloudAccountWorker.asynch_move_all(:id => self.id)
end
def do_move_all
logger.info "do_move_all: moving all networkSongs to soundcloud.------------"
logger.info "songs length: #{user.songs.all(:conditions => {:soundcloud_track_id => nil}).length}"
user.songs.all(:conditions => {:soundcloud_track_id => nil}, :order => 'network_songs.created_at desc').each do |song|
logger.info "moving song: #{song.id}: #{song.title}------------!"
track = create_track_from song
song.soundcloud_track = track
song.save
end
end
def get_client
@sc_client ||= Soundcloud.new :client_id => SoundcloudAccount.get_config[:client_id],
:client_secret => SoundcloudAccount.get_config[:client_secret],
:access_token => self.access_token,
:refresh_token => self.refresh_token,
:on_exchange_token => lambda {|client|
update_attributes client.options.slice(:expires_at, :access_token, :refresh_token)
logger.info 'Updated client'
}
end
def self.new_client
@sc_client ||= Soundcloud.new :client_id => SoundcloudAccount.get_config[:client_id],
:client_secret => SoundcloudAccount.get_config[:client_secret]
end
def self.get_config
@config ||= self.parse_credentials("config/soundcloud.yml")
end
private
def self.find_credentials creds
case creds
when File
YAML.load_file(creds.path)
when String
YAML.load_file(creds)
when Hash
creds
else
raise ArgumentError, "Credentials are not a path, file, or hash."
end
end
def self.parse_credentials creds
creds = find_credentials(creds).stringify_keys
(creds[ENV['RAILS_ENV']] || creds).symbolize_keys
end
end
class SoundcloudsController < ApplicationController
before_filter :login_required, :except => [:show]
def new
client = SoundcloudAccount.new_client
redirect_to client.authorize_url(:redirect_uri => soundcloud_create_url, :display => "popup") + "&display=popup"
end
def create
client = SoundcloudAccount.new_client
logger.info client.inspect
begin
token = client.exchange_token(:redirect_uri => soundcloud_create_url, :code => params[:code])
@sc_user = client.get('/me')
rescue Soundcloud::ResponseError => e
logger.error "Soundcloud Error on Connecting"
logger.error e.inspect
render :partial => :soundcloud_error
end
if @sc_user
sc_account = SoundcloudAccount.new(:refresh_token => client.refresh_token,
:access_token => client.access_token,
:sc_user_id => @sc_user.id,
:sc_username => @sc_user.username,
:permalink_url => @sc_user.permalink_url,
:expires_at => client.expires_at)
current_user.soundcloud_account = sc_account
#soundcloud_accounts are unique on sc_user_id, so that it doesn't do horrible things to us
unless current_user.save
logger.error "Cannot sync user to more than one Soundcloud Account at a time."
logger.error "Soundcloud wants to connect '#{current_user.name}' with SC:#{@sc_user.username}"
logger.error @sc_user.inspect
render :partial => :soundcloud_error
else
#Sync all networkSongs to SoundCloud, in the background
sc_account.move_all
end
end
...
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment