spot 2.0.1 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/spot.rb +7 -45
- data/lib/spot/clean.rb +2 -2
- data/lib/spot/prime.rb +73 -0
- data/spec/clean_spec.rb +8 -0
- data/spec/prime_spec.rb +31 -0
- data/spec/spot_spec.rb +0 -30
- data/spot.gemspec +4 -4
- metadata +24 -21
data/lib/spot.rb
CHANGED
@@ -2,10 +2,10 @@
|
|
2
2
|
require "spot/song"
|
3
3
|
require "spot/artist"
|
4
4
|
require "spot/album"
|
5
|
+
require "spot/prime"
|
5
6
|
require "spot/clean"
|
6
7
|
require "json"
|
7
8
|
require "rest-client"
|
8
|
-
require "levenshteinish"
|
9
9
|
require "charlock_holmes/string"
|
10
10
|
require "yaml"
|
11
11
|
require "uri"
|
@@ -96,53 +96,15 @@ module Spot
|
|
96
96
|
end
|
97
97
|
|
98
98
|
def result
|
99
|
-
@prime
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
match = clean!([song, artist].join(" ")).split(/\s+/)
|
105
|
-
raw = clean!(search).split(/\s+/)
|
106
|
-
|
107
|
-
if raw.length < match.length
|
108
|
-
diff = match - raw
|
109
|
-
res = diff.length.to_f/match.length
|
110
|
-
else
|
111
|
-
diff = raw - match
|
112
|
-
res = diff.length.to_f/raw.length
|
113
|
-
end
|
114
|
-
|
115
|
-
if diff.length > 1 and not match.map{ |m| diff.include?(m) }.all?
|
116
|
-
res =+ diff.map do |value|
|
117
|
-
match.map do |m|
|
118
|
-
Levenshtein.distance(value, m)
|
119
|
-
end.inject(:+)
|
120
|
-
end.inject(:+) / @config[:offset]
|
121
|
-
end
|
122
|
-
|
123
|
-
[res - r.popularity/@config[:popularity], r]
|
124
|
-
end.reject do |distance, song|
|
125
|
-
exclude?(song.to_s) or not song.valid?
|
126
|
-
end.sort_by do |distance, _|
|
127
|
-
distance
|
128
|
-
end.map(&:last).first : results.select(&:valid?).first
|
129
|
-
end
|
130
|
-
|
131
|
-
def type_of(r)
|
132
|
-
if @type == :songs
|
133
|
-
return r.name.to_s.downcase, r.artist.name.to_s.downcase
|
134
|
-
elsif @type == :artists
|
135
|
-
return r.song.title.to_s.downcase, r.name.to_s.downcase
|
99
|
+
if @prime
|
100
|
+
Spot::Prime.new(results.sort_by(&:popularity).reverse[0..6], search).
|
101
|
+
results.
|
102
|
+
select(&:valid?).
|
103
|
+
first
|
136
104
|
else
|
137
|
-
|
105
|
+
results.select(&:valid?).first
|
138
106
|
end
|
139
107
|
end
|
140
|
-
|
141
|
-
def exclude?(compare)
|
142
|
-
@exclude.
|
143
|
-
reject{ |value| @search.to_s.match(/#{value}/i) }.
|
144
|
-
map{ |value| compare.match(/#{value}/i) }.any?
|
145
|
-
end
|
146
108
|
|
147
109
|
#
|
148
110
|
# @value String To be cleaned
|
data/lib/spot/clean.rb
CHANGED
@@ -26,11 +26,11 @@ module Spot
|
|
26
26
|
/\.[a-z0-9]{2,3}$/,
|
27
27
|
/\[[^\]]*\]/,
|
28
28
|
/".*"/,
|
29
|
-
/'.*'
|
29
|
+
/(\s+|^)'.*'(\s+|$)/,
|
30
30
|
/[&|\/|\+][^\z]*/,
|
31
31
|
/^(\d+.*?[^a-z]+?)/i
|
32
32
|
].each do |reg|
|
33
|
-
string = string.gsub(reg, '').strip
|
33
|
+
string = string.gsub(reg, ' ').strip
|
34
34
|
end
|
35
35
|
|
36
36
|
[
|
data/lib/spot/prime.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require "levenshtein"
|
2
|
+
require_relative "clean"
|
3
|
+
|
4
|
+
module Spot
|
5
|
+
class Prime
|
6
|
+
@@ignore = YAML.load(File.read("#{File.dirname(__FILE__)}/ignore.yml"))
|
7
|
+
|
8
|
+
#
|
9
|
+
# @results Array<Object>
|
10
|
+
# @compare String
|
11
|
+
# @options Hash
|
12
|
+
#
|
13
|
+
def initialize(results, compare, options = {})
|
14
|
+
@options = {
|
15
|
+
popularity: 7,
|
16
|
+
exclude: 2,
|
17
|
+
limit: 0.7,
|
18
|
+
offset: 10
|
19
|
+
}.merge(options)
|
20
|
+
|
21
|
+
@results, @compare = results, compare
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @return Array<Object>
|
26
|
+
#
|
27
|
+
def results
|
28
|
+
@results.sort_by(&:popularity).map do |result|
|
29
|
+
match = clean(result.to_s).split(/\s+/).sort
|
30
|
+
raw = clean(@compare).split(/\s+/).sort
|
31
|
+
|
32
|
+
if raw.length < match.length
|
33
|
+
diff = (match - raw)
|
34
|
+
res = diff.length.to_f / match.length
|
35
|
+
else
|
36
|
+
diff = (raw - match)
|
37
|
+
res = diff.length.to_f / raw.length
|
38
|
+
end
|
39
|
+
|
40
|
+
if diff.length > 1 and not match.map{ |m| diff.include?(m) }.all?
|
41
|
+
res =+ diff.map do |value|
|
42
|
+
match.map { |m| Levenshtein.normalized_distance(value, m) }.inject(:+)
|
43
|
+
end.inject(:+) / @options[:offset]
|
44
|
+
end
|
45
|
+
|
46
|
+
[res - result.popularity / @options[:popularity], result]
|
47
|
+
end.reject do |_, result|
|
48
|
+
Spot::Prime.ignore?(result.to_s, @compare)
|
49
|
+
end.sort_by do |distance, _|
|
50
|
+
distance
|
51
|
+
end.map(&:last)
|
52
|
+
end
|
53
|
+
|
54
|
+
#
|
55
|
+
# @value String To be cleaned
|
56
|
+
# @return String A cleaned string
|
57
|
+
#
|
58
|
+
def clean(value)
|
59
|
+
Spot::Clean.new(value).process
|
60
|
+
end
|
61
|
+
|
62
|
+
#
|
63
|
+
# @this String
|
64
|
+
# @compare String
|
65
|
+
# @return Boolean
|
66
|
+
#
|
67
|
+
def self.ignore?(this, compare = nil)
|
68
|
+
@@ignore.
|
69
|
+
reject{ |value| compare.to_s.match(/#{value}/i) }.
|
70
|
+
map{ |value| this.match(/#{value}/i) }.any?
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/spec/clean_spec.rb
CHANGED
@@ -20,6 +20,10 @@ describe Spot::Clean do
|
|
20
20
|
Spot::Clean.new("Song A \"abc def\"").process.should eq("song a")
|
21
21
|
end
|
22
22
|
|
23
|
+
it "Sweet Child O' Mine by Guns N' Roses => sweet child o' mine by guns n' roses" do
|
24
|
+
Spot::Clean.new("Sweet Child O' Mine by Guns N' Roses").process.should eq("sweet child o' mine by guns n' roses")
|
25
|
+
end
|
26
|
+
|
23
27
|
it "Song - A [B + C] => Song - A" do
|
24
28
|
Spot::Clean.new("Song - A [B + C]").process.should eq("song a")
|
25
29
|
end
|
@@ -103,6 +107,10 @@ describe Spot::Clean do
|
|
103
107
|
Spot::Clean.new("Knockin' On Heaven's Door").process.should eq("knockin' on heaven's door")
|
104
108
|
end
|
105
109
|
|
110
|
+
it "I Love Rock'n'roll => i love rock'n'roll" do
|
111
|
+
Spot::Clean.new("I Love Rock'n'roll").process.should eq("i love rock'n'roll")
|
112
|
+
end
|
113
|
+
|
106
114
|
it "Jason Derulo - Undefeated" do
|
107
115
|
Spot::Clean.new("Undefeated").process.should eq("undefeated")
|
108
116
|
end
|
data/spec/prime_spec.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
describe Spot::Prime do
|
2
|
+
context "exclude" do
|
3
|
+
it "should have a working exclude? method" do
|
4
|
+
{
|
5
|
+
"tribute" => true,
|
6
|
+
"cover random" => true,
|
7
|
+
"live" => true,
|
8
|
+
"club mix random" => true,
|
9
|
+
"LIVE" => true,
|
10
|
+
"karaoKE" => true,
|
11
|
+
"instrumental" => true,
|
12
|
+
"Karaoke - Won't Get Fooled Again" => true,
|
13
|
+
"club version" => true,
|
14
|
+
"instrumentals" => true,
|
15
|
+
"demo" => true,
|
16
|
+
"made famous by" => true,
|
17
|
+
"remixes" => true,
|
18
|
+
"ringtone" => true,
|
19
|
+
"ringtones" => true,
|
20
|
+
"riingtonerandom" => false,
|
21
|
+
"club random mix" => false,
|
22
|
+
"random" => false,
|
23
|
+
"oliver" => false,
|
24
|
+
"acoustic" => true,
|
25
|
+
"aacoustic" => false
|
26
|
+
}.each do |comp, outcome|
|
27
|
+
Spot::Prime.ignore?(comp).should eq(outcome)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/spec/spot_spec.rb
CHANGED
@@ -130,36 +130,6 @@ describe Spot::Search do
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
context "exclude" do
|
134
|
-
it "should have a working exclude? method" do
|
135
|
-
{
|
136
|
-
"tribute" => true,
|
137
|
-
"cover random" => true,
|
138
|
-
"live" => true,
|
139
|
-
"club mix random" => true,
|
140
|
-
"LIVE" => true,
|
141
|
-
"karaoKE" => true,
|
142
|
-
"instrumental" => true,
|
143
|
-
"Karaoke - Won't Get Fooled Again" => true,
|
144
|
-
"club version" => true,
|
145
|
-
"instrumentals" => true,
|
146
|
-
"demo" => true,
|
147
|
-
"made famous by" => true,
|
148
|
-
"remixes" => true,
|
149
|
-
"ringtone" => true,
|
150
|
-
"ringtones" => true,
|
151
|
-
"riingtonerandom" => false,
|
152
|
-
"club random mix" => false,
|
153
|
-
"random" => false,
|
154
|
-
"oliver" => false,
|
155
|
-
"acoustic" => true,
|
156
|
-
"aacoustic" => false
|
157
|
-
}.each do |comp, outcome|
|
158
|
-
@spot.exclude?(comp).should eq(outcome)
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
133
|
context "territory" do
|
164
134
|
it "should not find any songs when using a non valid territory" do
|
165
135
|
@spot.territory("RANDOM").find_all_songs("search").results.should be_empty
|
data/spot.gemspec
CHANGED
@@ -3,7 +3,7 @@ $:.push File.expand_path("../lib", __FILE__)
|
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "spot"
|
6
|
-
s.version = "2.0.
|
6
|
+
s.version = "2.0.4"
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.authors = ["Linus Oleander"]
|
9
9
|
s.email = ["linus@oleander.nu"]
|
@@ -17,13 +17,13 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
18
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
|
-
|
20
|
+
|
21
21
|
s.add_dependency("json_pure")
|
22
22
|
s.add_dependency("rest-client")
|
23
23
|
s.add_dependency("abstract")
|
24
|
-
s.add_dependency("
|
24
|
+
s.add_dependency("levenshtein", "~> 0.2.2")
|
25
25
|
s.add_dependency("charlock_holmes")
|
26
|
-
|
26
|
+
|
27
27
|
s.add_development_dependency("rspec")
|
28
28
|
s.add_development_dependency("vcr")
|
29
29
|
s.add_development_dependency("webmock", "~> 1.8.0")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-06-
|
12
|
+
date: 2012-06-26 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json_pure
|
16
|
-
requirement: &
|
16
|
+
requirement: &70221274908280 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70221274908280
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rest-client
|
27
|
-
requirement: &
|
27
|
+
requirement: &70221274907840 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70221274907840
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: abstract
|
38
|
-
requirement: &
|
38
|
+
requirement: &70221274907420 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,21 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70221274907420
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
|
-
name:
|
49
|
-
requirement: &
|
48
|
+
name: levenshtein
|
49
|
+
requirement: &70221274906920 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 0.2.2
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70221274906920
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: charlock_holmes
|
60
|
-
requirement: &
|
60
|
+
requirement: &70221274906500 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70221274906500
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rspec
|
71
|
-
requirement: &
|
71
|
+
requirement: &70221274906040 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70221274906040
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: vcr
|
82
|
-
requirement: &
|
82
|
+
requirement: &70221274905620 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :development
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70221274905620
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: webmock
|
93
|
-
requirement: &
|
93
|
+
requirement: &70221274905120 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,7 +98,7 @@ dependencies:
|
|
98
98
|
version: 1.8.0
|
99
99
|
type: :development
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70221274905120
|
102
102
|
description: A Ruby implementation of the Spotify Meta API.
|
103
103
|
email:
|
104
104
|
- linus@oleander.nu
|
@@ -118,6 +118,7 @@ files:
|
|
118
118
|
- lib/spot/clean.rb
|
119
119
|
- lib/spot/exclude.yml
|
120
120
|
- lib/spot/ignore.yml
|
121
|
+
- lib/spot/prime.rb
|
121
122
|
- lib/spot/song.rb
|
122
123
|
- spec/album_spec.rb
|
123
124
|
- spec/artist_spec.rb
|
@@ -128,6 +129,7 @@ files:
|
|
128
129
|
- spec/fixtures/exclude.tribute.json
|
129
130
|
- spec/fixtures/track.json
|
130
131
|
- spec/fixtures/vcr_cassettes/spotify.yml
|
132
|
+
- spec/prime_spec.rb
|
131
133
|
- spec/song_spec.rb
|
132
134
|
- spec/spec_helper.rb
|
133
135
|
- spec/spot_spec.rb
|
@@ -166,6 +168,7 @@ test_files:
|
|
166
168
|
- spec/fixtures/exclude.tribute.json
|
167
169
|
- spec/fixtures/track.json
|
168
170
|
- spec/fixtures/vcr_cassettes/spotify.yml
|
171
|
+
- spec/prime_spec.rb
|
169
172
|
- spec/song_spec.rb
|
170
173
|
- spec/spec_helper.rb
|
171
174
|
- spec/spot_spec.rb
|