isrc 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +5 -13
  2. data/lib/isrc.rb +124 -71
  3. data/lib/isrc/version.rb +1 -1
  4. data/spec/isrc_spec.rb +26 -8
  5. metadata +17 -17
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NjRhOTMyZWJiMzZiNjg5YzVjYTNjNTgzYzk5MTZjMjEyOGM4Njc3Mg==
5
- data.tar.gz: !binary |-
6
- ZmRiYTg5YWQzYTg4OWIzNzU5NDI3YTU5YmQ3OTA5MWVmZWZlMDRkNg==
2
+ SHA1:
3
+ metadata.gz: bd97834b5c09da196ffc4e68c34b6be56cc63ed7
4
+ data.tar.gz: 0159b3fe894a23048a316f50818e3dc83b6fdc97
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- NTk2NDcwMjBlYzIxMmRiM2FjODY0MzNmNGJkODBjZGExYzY3MzJhNjNlNTUx
10
- OGRlMWU3ZTE5MjM3OWNhNWY0ODJlNDYwNWMyOTU4MTNmNmViMjRkZTRhYTQ2
11
- OTIwMTc2YWRiMDJhZjE1NzI0MDU2MTk1OWJmYzhiODNmODMzNTc=
12
- data.tar.gz: !binary |-
13
- YTZiMmFmMDkxNTQ5OWVlNGE0NGJlNmE5ZjUzMzlkNzJlMzRiNTJlYTk4MjM1
14
- MWNhYzIxYTc5NTFjZGZlNmJhYzg3NWJkNjE5Y2E2NTkwMDUxMmFlNGYzYmYx
15
- NDc3OGI1N2NjYmUxYTI0MTdjZDA0NDhlOTBlZTAzYmUwMzBjMzU=
6
+ metadata.gz: da759b2fdeb7f8e97e593002ca9ab2c3aa2f9cfff4f12b68614e1c6a4384c499dc7df87458a8862856dbef0ba8791ef55a0a6b92825fd2a095700e5cbd1184cd
7
+ data.tar.gz: a1c1f55955dbcacca8d21f4c0adadfe179395a478370f3522dfa1e284dba66712b0104d62f0fa31a006e723be055d841a93a53dad5111760d3bc2c1cd583f49a
@@ -9,86 +9,57 @@ module ISRC
9
9
  PPLUK_SESSION_GRAB_URL = 'http://repsearch.ppluk.com/ARSWeb/appmanager/ARS/main'
10
10
  PPLUK_AJAX_SEARCH_URL = 'http://repsearch.ppluk.com/ARSWeb/block/send-receive-updates'
11
11
 
12
+ def self.configure(&block)
13
+ ISRC::Configuration.instance_eval(&block)
14
+ end
15
+
12
16
  class PPLUK
13
17
  def retrieve(opts)
14
- # default options
15
- opts = { :title_size => 2 }.merge(opts)
18
+ # NOTE the online search is a bit funky: adding more to the search make the results worse
19
+ # trying out a three word limit
16
20
 
17
- agent = Mechanize.new
18
- agent.log = Logger.new "mech.log"
19
- agent.user_agent_alias = 'Mac Safari'
21
+ pieces = self.extract_song_peices(opts[:title])
20
22
 
21
- isrc_session_init = agent.get PPLUK_SESSION_GRAB_URL
22
- view_state = self.extract_view_state(isrc_session_init.body)
23
- ice_session, ice_session_count = self.extract_ice_session(isrc_session_init.body)
23
+ # try the first two pieces at first
24
24
 
25
- # add the ice_sessions cookie
26
- ice_cookie = Mechanize::Cookie.new('ice.sessions', "#{ice_session}##{ice_session_count}")
27
- ice_cookie.path = "/"
28
- ice_cookie.domain = "repsearch.ppluk.com"
29
- agent.cookie_jar.add!(ice_cookie)
25
+ # if the song is only one word, submit request with on processing
26
+ if pieces[:all].size == 1
27
+ @matches = self.request(opts)
28
+ elsif pieces[:all].size > 1
29
+ # let's try increasing the number of pieces, starting from 2
30
+ pieces_count = 1
30
31
 
31
- # NOTE the online search is a bit funky: adding more to the search make the results worse
32
- # trying out a three word limit
32
+ begin
33
+ pieces_count += 1
33
34
 
34
- title_pieces = extract_song_peices(opts[:title])
35
- shortened_title = title_pieces.slice(0, [opts[:title_size], title_pieces.size].min).join(' ')
36
-
37
- # puts "Title: #{shortened_title}\nArtist: #{opts[:artist]}"
38
-
39
- begin
40
- isrc_search = agent.post PPLUK_AJAX_SEARCH_URL, {
41
- 'ice.submit.partial' => 'false',
42
- # 'ice.event.target' => 'T400335881332330323192:ars_form:search_button',
43
- # 'ice.event.captured' => 'T400335881332330323192:ars_form:search_button',
44
- # 'ice.event.type' => 'onclick',
45
- # 'ice.event.alt' => 'false',
46
- # 'ice.event.ctrl' => 'false',
47
- # 'ice.event.shift' => 'false',
48
- # 'ice.event.meta' => 'false',
49
- # 'ice.event.x' => '47',
50
- # 'ice.event.y' => '65',
51
- # 'ice.event.left' => 'false',
52
- # 'ice.event.right' => 'false',
53
- 'T5000782701386267377497:ars_form:search_button' => 'Search',
54
- 'T5000782701386267377497:ars_form:isrc_code' => '',
55
- 'T5000782701386267377497:ars_form:rec_title_idx' => '',
56
- 'T5000782701386267377497:ars_form:rec_title' => shortened_title,
57
- 'T5000782701386267377497:ars_form:rec_band_artist_idx' => '',
58
- 'T5000782701386267377497:ars_form:rec_band_artist' => opts[:artist],
59
- 'javax.faces.RenderKitId' => 'ICEfacesRenderKit',
60
- 'javax.faces.ViewState' => view_state,
61
- 'icefacesCssUpdates' => '',
62
- 'T5000782701386267377497:ars_form' => '',
63
- 'ice.session' => ice_session,
64
- 'ice.view' => view_state,
65
- 'ice.focus' => '',
66
-
67
- # the rand is 19 characters long in the browser's HTTP requests
68
- 'rand' => sprintf('%1.17f', rand)
69
- }
70
- rescue Mechanize::ResponseCodeError => e
71
- agent.log.error "Error submitting AJAX request: #{e.page.body}"
72
- end
35
+ shortened_title = pieces[:all].slice(0, pieces_count).join(' ')
73
36
 
74
- # creates an array representation of the table:
75
- # artist, title, isrc, rights holder, released, time
76
- isrc_html = Nokogiri::HTML(isrc_search.body)
77
- @matches = isrc_html.css("table[id='T5000782701386267377497:ars_form:searchResultsTable'] tbody tr").map do |m|
78
- columns = m.css('td')
37
+ @matches = self.request({
38
+ title: shortened_title,
39
+ artist: opts[:artist]
40
+ })
41
+ end while @matches.empty? && pieces[:all].size > pieces_count + 1
79
42
 
80
- # if there is no ISRC don't bother looking
81
- next if columns[2] == 'Not Supplied'
43
+ # given 'Surrender [Original Mix]' the above algorithm will submit the entire title
44
+ # if that didn't work, strip out all meta elements and try greatest to least number of song pieces
82
45
 
83
- # zero length music wont be used
84
- next if columns[-1] == '0:00sec'
46
+ # TODO we shouldn't allow one letter or two letter title requests
47
+ # TODO remove stop words
48
+ # TODO detect when meta == title pieces
85
49
 
86
- columns.map &:text
87
- end
50
+ pieces_count = pieces[:title].size
51
+
52
+ while @matches.empty? && pieces_count > 0
53
+ shortened_title = pieces[:title].slice(0, pieces_count).join(' ')
54
+
55
+ @matches = self.request({
56
+ title: shortened_title,
57
+ artist: opts[:artist]
58
+ })
59
+
60
+ pieces_count -= 1
61
+ end
88
62
 
89
- # if the shortened title did not work, try making it longer
90
- if @matches.empty? && opts[:title_size] < title_pieces.size
91
- self.retrieve(opts.merge({:title_size => opts[:title_size] + 1}))
92
63
  end
93
64
  end
94
65
 
@@ -132,9 +103,20 @@ module ISRC
132
103
 
133
104
  protected
134
105
  def extract_song_peices(title)
135
- title_pieces = title.split(/(\([^)]+\)|\[[^\]]+\])/).reject { |s| s.strip.empty? }
136
- title_pieces[0] = title_pieces[0].split(' ')
137
- title_pieces.flatten
106
+ # this splits a song title into peices:
107
+ # * 'bracket' peice (meta)
108
+ # * 'parenthesis' peice (meta)
109
+ # * song words (title)
110
+
111
+ all_pieces = title.split(/(\([^)]+\)|\[[^\]]+\])/).reject { |s| s.strip.empty? }
112
+ title_pieces = all_pieces.shift.split(' ')
113
+ meta_pieces = all_pieces
114
+
115
+ {
116
+ all: [title_pieces, meta_pieces].flatten,
117
+ meta: meta_pieces,
118
+ title: title_pieces
119
+ }
138
120
  end
139
121
 
140
122
  def extract_view_state(body)
@@ -151,5 +133,76 @@ module ISRC
151
133
  minutes.to_i * 60 + seconds.to_i
152
134
  end
153
135
 
136
+ def request(opts = {})
137
+ puts "Title: #{opts[:title]}\nArtist: #{opts[:artist]}"
138
+
139
+ agent = Mechanize.new
140
+ # TODO log path needs to be configurable
141
+ agent.log = Logger.new "mech.log"
142
+ agent.user_agent_alias = 'Mac Safari'
143
+
144
+ # grab the main page HTML to pull session vars to make the AJAX request
145
+ isrc_session_init = agent.get(PPLUK_SESSION_GRAB_URL)
146
+ view_state = self.extract_view_state(isrc_session_init.body)
147
+ ice_session, ice_session_count = self.extract_ice_session(isrc_session_init.body)
148
+
149
+ # add the ice_sessions cookie for the AJAX search request
150
+ ice_cookie = Mechanize::Cookie.new('ice.sessions', "#{ice_session}##{ice_session_count}")
151
+ ice_cookie.path = "/"
152
+ ice_cookie.domain = "repsearch.ppluk.com"
153
+ agent.cookie_jar.add!(ice_cookie)
154
+
155
+ begin
156
+ isrc_search = agent.post PPLUK_AJAX_SEARCH_URL, {
157
+ 'ice.submit.partial' => 'false',
158
+ # 'ice.event.target' => 'T400335881332330323192:ars_form:search_button',
159
+ # 'ice.event.captured' => 'T400335881332330323192:ars_form:search_button',
160
+ # 'ice.event.type' => 'onclick',
161
+ # 'ice.event.alt' => 'false',
162
+ # 'ice.event.ctrl' => 'false',
163
+ # 'ice.event.shift' => 'false',
164
+ # 'ice.event.meta' => 'false',
165
+ # 'ice.event.x' => '47',
166
+ # 'ice.event.y' => '65',
167
+ # 'ice.event.left' => 'false',
168
+ # 'ice.event.right' => 'false',
169
+ 'T5000782701386267377497:ars_form:search_button' => 'Search',
170
+ 'T5000782701386267377497:ars_form:isrc_code' => '',
171
+ 'T5000782701386267377497:ars_form:rec_title_idx' => '',
172
+ 'T5000782701386267377497:ars_form:rec_title' => opts[:title],
173
+ 'T5000782701386267377497:ars_form:rec_band_artist_idx' => '',
174
+ 'T5000782701386267377497:ars_form:rec_band_artist' => opts[:artist],
175
+ 'javax.faces.RenderKitId' => 'ICEfacesRenderKit',
176
+ 'javax.faces.ViewState' => view_state,
177
+ 'icefacesCssUpdates' => '',
178
+ 'T5000782701386267377497:ars_form' => '',
179
+ 'ice.session' => ice_session,
180
+ 'ice.view' => view_state,
181
+ 'ice.focus' => '',
182
+
183
+ # the rand is 19 characters long in the browser's HTTP requests
184
+ 'rand' => sprintf('%1.17f', rand)
185
+ }
186
+ rescue Mechanize::ResponseCodeError => e
187
+ agent.log.error "Error submitting AJAX request: #{e.page.body}"
188
+ end
189
+
190
+ # creates an array representation of the table:
191
+ # artist, title, isrc, rights holder, released, time
192
+
193
+ isrc_table = Nokogiri::HTML(isrc_search.body).css("table[id='T5000782701386267377497:ars_form:searchResultsTable'] tbody tr")
194
+ isrc_table.map do |m|
195
+ columns = m.css('td')
196
+
197
+ # if there is no ISRC don't bother looking
198
+ next if columns[2] == 'Not Supplied'
199
+
200
+ # zero length music wont be used
201
+ next if columns[-1] == '0:00sec'
202
+
203
+ columns.map &:text
204
+ end
205
+ end
206
+
154
207
  end
155
208
  end
@@ -1,3 +1,3 @@
1
1
  module ISRC
2
- VERSION = "1.0.2"
2
+ VERSION = "1.0.3"
3
3
  end
@@ -29,6 +29,16 @@ describe ISRC do
29
29
  # however, the length delta is huge
30
30
  end
31
31
 
32
+ it "handles results with brackets" do
33
+ isrc.retrieve artist: 'Curiosity Killed The Cat', title: 'Down to Earth'
34
+ isrc.match(time:'03:54')[:isrc].should == 'GBF088600037'
35
+ end
36
+
37
+ it 'handles a mixed version of a song when there is not a mixed version listed' do
38
+ isrc.retrieve artist:'Kings of Leon', title: 'Use Somebody (Chew Fu Festival Fix)'
39
+ isrc.match(time:'5:37')[:isrc].should == 'USRC10800301'
40
+ end
41
+
32
42
  it "handles edge cases that don't make sense" do
33
43
  isrc.retrieve artist:'Toni Braxton', title:'Youre Making me High'
34
44
  isrc.match(time:'4:12')[:isrc].should == 'USLF29600183'
@@ -49,17 +59,22 @@ describe ISRC do
49
59
  end
50
60
 
51
61
  context "song title processing" do
52
- it "should handle bracket mixes" do
53
- pieces = isrc.send(:extract_song_peices, "Surrender [Original Mix]")
54
- pieces.size.should == 2
55
- pieces.last.should == "[Original Mix]"
62
+ context 'of brackets' do
63
+ it "should parse them correctly with a one word song" do
64
+ pieces = isrc.send(:extract_song_peices, "Surrender [Original Mix]")
65
+ pieces[:all].size.should == 2
66
+ pieces[:all].last.should == "[Original Mix]"
67
+ pieces[:meta].size.should == 1
68
+ end
56
69
  end
57
70
 
58
71
  context 'of parenthesis' do
59
72
  it "should count parenthesis as a single song peice" do
60
73
  pieces = isrc.send(:extract_song_peices, "Want Me (Like Water) (New Vocal Mix No 1)")
61
- pieces.size.should == 4
62
- pieces.last.should == '(New Vocal Mix No 1)'
74
+ pieces[:all].size.should == 4
75
+ pieces[:all].last.should == '(New Vocal Mix No 1)'
76
+ pieces[:meta].size.should == 2
77
+ pieces[:title].size.should == 2
63
78
  end
64
79
 
65
80
  it "should handle a single word song with parenthesis" do
@@ -70,13 +85,16 @@ describe ISRC do
70
85
  isrc.retrieve artist:'Frank Sinatra', title: 'Chicago (Digitally Remastered)'
71
86
  isrc.match(time:'2:14')[:isrc].should == 'USCA20300966'
72
87
  # or USCA29800388; they are basically the same
88
+
89
+ # Bagatelle in A minor, WoO 59 -`Für Elise` by Bella Davidovich...
73
90
  end
74
91
  end
75
92
 
76
93
  it "should handle a standard multi-word title" do
77
94
  pieces = isrc.send(:extract_song_peices, "Take Your Time")
78
- pieces.size.should == 3
79
- pieces.last.should == "Time"
95
+ pieces[:all].size.should == 3
96
+ pieces[:title].size.should == 3
97
+ pieces[:title].last.should == "Time"
80
98
  end
81
99
 
82
100
  end
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isrc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Bianco
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-27 00:00:00.000000000 Z
11
+ date: 2014-03-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: nokogiri
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: mechanize
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: guard
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ! '>='
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ! '>='
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: Pull ISRC codes from PPLK UK's database
@@ -87,8 +87,8 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
- - .gitignore
91
- - .rspec
90
+ - ".gitignore"
91
+ - ".rspec"
92
92
  - Gemfile
93
93
  - Guardfile
94
94
  - LICENSE
@@ -110,17 +110,17 @@ require_paths:
110
110
  - lib
111
111
  required_ruby_version: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - ! '>='
113
+ - - ">="
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  required_rubygems_version: !ruby/object:Gem::Requirement
117
117
  requirements:
118
- - - ! '>='
118
+ - - ">="
119
119
  - !ruby/object:Gem::Version
120
120
  version: '0'
121
121
  requirements: []
122
122
  rubyforge_project:
123
- rubygems_version: 2.1.11
123
+ rubygems_version: 2.2.0
124
124
  signing_key:
125
125
  specification_version: 4
126
126
  summary: Pull ISRC codes from PPLK UK's database