Class: Grooveshark::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/grooveshark/client.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Client

Returns a new instance of Client.



6
7
8
9
10
# File 'lib/grooveshark/client.rb', line 6

def initialize(params = {})
  @ttl = params[:ttl] || 120 # 2 minutes
  @uuid = UUID.new.generate.upcase
  get_token_data
end

Instance Attribute Details

#comm_tokenObject

Returns the value of attribute comm_token.



3
4
5
# File 'lib/grooveshark/client.rb', line 3

def comm_token
  @comm_token
end

#comm_token_ttlObject (readonly)

Returns the value of attribute comm_token_ttl.



4
5
6
# File 'lib/grooveshark/client.rb', line 4

def comm_token_ttl
  @comm_token_ttl
end

#countryObject (readonly)

Returns the value of attribute country.



4
5
6
# File 'lib/grooveshark/client.rb', line 4

def country
  @country
end

#sessionObject

Returns the value of attribute session.



3
4
5
# File 'lib/grooveshark/client.rb', line 3

def session
  @session
end

#userObject (readonly)

Returns the value of attribute user.



4
5
6
# File 'lib/grooveshark/client.rb', line 4

def user
  @user
end

Instance Method Details

#create_token(method) ⇒ Object

Sign method



125
126
127
128
129
130
131
# File 'lib/grooveshark/client.rb', line 125

def create_token(method)
  rnd = get_random_hex_chars(6)
  salt = "gooeyFlubber"
  plain = [method, @comm_token, salt, rnd].join(':')
  hash = Digest::SHA1.hexdigest(plain)
  "#{rnd}#{hash}"
end

#get_random_hex_chars(length) ⇒ Object



133
134
135
136
# File 'lib/grooveshark/client.rb', line 133

def get_random_hex_chars(length)
  chars = ('a'..'f').to_a | (0..9).to_a
  (0...length).map { chars[rand(chars.length)] }.join
end

#get_song_url(song) ⇒ Object

Get song stream



102
103
104
# File 'lib/grooveshark/client.rb', line 102

def get_song_url(song)
  get_song_url_by_id(song.id)
end

#get_song_url_by_id(id) ⇒ Object

Get song stream url by ID



96
97
98
99
# File 'lib/grooveshark/client.rb', line 96

def get_song_url_by_id(id)
  resp = get_stream_auth_by_songid(id)
  "http://#{resp['ip']}/stream.php?streamKey=#{resp['stream_key']}"
end

#get_stream_auth(song) ⇒ Object

Get stream authentication for song object



91
92
93
# File 'lib/grooveshark/client.rb', line 91

def get_stream_auth(song)
  get_stream_auth_by_songid(song.id)
end

#get_stream_auth_by_songid(song_id) ⇒ Object

Get stream authentication by song ID



76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/grooveshark/client.rb', line 76

def get_stream_auth_by_songid(song_id)
  result = request('getStreamKeyFromSongIDEx', {
    'type' => 0,
    'prefetch' => false,
    'songID' => song_id,
    'country' => @country,
    'mobile' => false,
  })
  if result == [] then
    raise GeneralError, "No data for this song. Maybe Grooveshark banned your IP."
  end
  result
end

#get_token_dataObject

Raises:



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/grooveshark/client.rb', line 106

def get_token_data
  response = RestClient.get('http://grooveshark.com')

  preload_regex = /gsPreloadAjax\(\{url: '\/preload.php\?(.*)&hash=' \+ clientPage\}\)/
  preload_id = response.to_s.scan(preload_regex).flatten.first
  preload_url = "http://grooveshark.com/preload.php?#{preload_id}&getCommunicationToken=1&hash=%2F"
  preload_response = RestClient.get(preload_url)

  token_data_json = preload_response.to_s.scan(/window.tokenData = (.*);/).flatten.first
  raise GeneralError, "token data not found" if not token_data_json
  token_data = JSON.parse(token_data_json)
  @comm_token = token_data['getCommunicationToken']
  @comm_token_ttl = Time.now.to_i
  config = token_data['getGSConfig']
  @country = config['country']
  @session = config['sessionID']
end

#get_user_by_id(id) ⇒ Object

Find user by ID



21
22
23
24
# File 'lib/grooveshark/client.rb', line 21

def get_user_by_id(id)
  resp = request('getUserByID', {:userID => id})['user']
  resp['username'].empty? ? nil : User.new(self, resp)
end

#get_user_by_username(name) ⇒ Object

Find user by username



27
28
29
30
# File 'lib/grooveshark/client.rb', line 27

def get_user_by_username(name)
  resp = request('getUserByUsername', {:username => name})['user']
  resp['username'].empty? ? nil : User.new(self, resp)
end

#login(user, password) ⇒ Object

Authenticate user



13
14
15
16
17
18
# File 'lib/grooveshark/client.rb', line 13

def (user, password)
  data = request('authenticateUser', {:username => user, :password => password}, true)
  @user = User.new(self, data)
  raise InvalidAuthentication, 'Wrong username or password!' if @user.id == 0
  return @user
end

Get popular songs type => daily, monthly

Raises:

  • (ArgumentError)


39
40
41
42
# File 'lib/grooveshark/client.rb', line 39

def popular_songs(type='daily')
  raise ArgumentError, 'Invalid type' unless ['daily', 'monthly'].include?(type)
  request('popularGetSongs', {:type => type})['songs'].map { |s| Song.new(s) }
end

#recent_usersObject

Get recently active users



33
34
35
# File 'lib/grooveshark/client.rb', line 33

def recent_users
  request('getRecentlyActiveUsers', {})['users'].map { |u| User.new(self, u) }
end

#refresh_tokenObject

Refresh communications token on ttl



173
174
175
# File 'lib/grooveshark/client.rb', line 173

def refresh_token
  get_token_data if Time.now.to_i - @comm_token_ttl > @ttl
end

#request(method, params = {}, secure = false) ⇒ Object

Perform API request



139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/grooveshark/client.rb', line 139

def request(method, params={}, secure=false)
  refresh_token if @comm_token

  url = "#{secure ? 'https' : 'http'}://grooveshark.com/more.php?#{method}"
  body = {
    'header' => {
      'client' => 'mobileshark',
      'clientRevision' => '20120830',
      'country' => @country,
      'privacy' => 0,
      'session' => @session,
      'uuid' => @uuid
    },
    'method' => method,
    'parameters' => params
  }
  body['header']['token'] = create_token(method) if @comm_token
  begin
    data = RestClient.post(url, body.to_json, {'Content-Type' => 'application/json'})
  rescue Exception => ex
    raise GeneralError, ex.message
  end

  data = JSON.parse(data)
  data = data.normalize if data.kind_of?(Hash)

  if data.key?('fault')
    raise ApiError.new(data['fault'])
  else
    data['result']
  end
end

#search(type, query) ⇒ Object

Perform search request for query



60
61
62
63
# File 'lib/grooveshark/client.rb', line 60

def search(type, query)
  results = request('getResultsFromSearch', {:type => type, :query => query})['result']
  results.map { |song| Song.new song }
end

#search_songs(query) ⇒ Object

Perform songs search request for query



66
67
68
# File 'lib/grooveshark/client.rb', line 66

def search_songs(query)
  search('Songs', query)
end

#search_songs_pure(query) ⇒ Object

Return raw response for songs search request



71
72
73
# File 'lib/grooveshark/client.rb', line 71

def search_songs_pure(query)
  request('getSearchResultsEx', {:type => 'Songs', :query => query})
end

#top_broadcasts(count = 10) ⇒ Object

Get top broadcasts count => specifies how many broadcasts to get



46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/grooveshark/client.rb', line 46

def top_broadcasts(count=10)
  top_broadcasts = []
  request('getTopBroadcastsCombined').each do |key,val|
    broadcast_id = key.split(':')[1]
    top_broadcasts.push(Broadcast.new(self, broadcast_id))
    count -= 1
    if count == 0
      break
    end
  end
  return top_broadcasts
end