rapgenius 0.1.0 → 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +8 -1
- data/LICENSE +1 -1
- data/README.md +95 -72
- data/lib/rapgenius.rb +40 -3
- data/lib/rapgenius/artist.rb +54 -0
- data/lib/rapgenius/client.rb +57 -0
- data/lib/rapgenius/exceptions.rb +1 -1
- data/lib/rapgenius/line.rb +59 -0
- data/lib/rapgenius/media.rb +11 -0
- data/lib/rapgenius/song.rb +105 -33
- data/lib/rapgenius/version.rb +1 -1
- data/rapgenius.gemspec +5 -4
- data/spec/rapgenius/artist_spec.rb +33 -0
- data/spec/rapgenius/client_spec.rb +42 -0
- data/spec/rapgenius/line_spec.rb +23 -0
- data/spec/rapgenius/media_spec.rb +19 -0
- data/spec/rapgenius/song_spec.rb +46 -44
- metadata +27 -46
- data/lib/rapgenius/annotation.rb +0 -37
- data/lib/rapgenius/scraper.rb +0 -82
- data/spec/rapgenius/annotation_spec.rb +0 -41
- data/spec/rapgenius/scraper_spec.rb +0 -54
metadata
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rapgenius
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 1.0.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Tim Rogers
|
@@ -10,28 +9,11 @@ authors:
|
|
10
9
|
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2014-01-27 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: nokogiri
|
17
|
-
requirement: !ruby/object:Gem::Requirement
|
18
|
-
none: false
|
19
|
-
requirements:
|
20
|
-
- - ~>
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: 1.6.0
|
23
|
-
type: :runtime
|
24
|
-
prerelease: false
|
25
|
-
version_requirements: !ruby/object:Gem::Requirement
|
26
|
-
none: false
|
27
|
-
requirements:
|
28
|
-
- - ~>
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 1.6.0
|
31
14
|
- !ruby/object:Gem::Dependency
|
32
15
|
name: httparty
|
33
16
|
requirement: !ruby/object:Gem::Requirement
|
34
|
-
none: false
|
35
17
|
requirements:
|
36
18
|
- - ~>
|
37
19
|
- !ruby/object:Gem::Version
|
@@ -39,7 +21,6 @@ dependencies:
|
|
39
21
|
type: :runtime
|
40
22
|
prerelease: false
|
41
23
|
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
24
|
requirements:
|
44
25
|
- - ~>
|
45
26
|
- !ruby/object:Gem::Version
|
@@ -47,7 +28,6 @@ dependencies:
|
|
47
28
|
- !ruby/object:Gem::Dependency
|
48
29
|
name: rspec
|
49
30
|
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
31
|
requirements:
|
52
32
|
- - ~>
|
53
33
|
- !ruby/object:Gem::Version
|
@@ -55,7 +35,6 @@ dependencies:
|
|
55
35
|
type: :development
|
56
36
|
prerelease: false
|
57
37
|
version_requirements: !ruby/object:Gem::Requirement
|
58
|
-
none: false
|
59
38
|
requirements:
|
60
39
|
- - ~>
|
61
40
|
- !ruby/object:Gem::Version
|
@@ -63,7 +42,6 @@ dependencies:
|
|
63
42
|
- !ruby/object:Gem::Dependency
|
64
43
|
name: mocha
|
65
44
|
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
45
|
requirements:
|
68
46
|
- - ~>
|
69
47
|
- !ruby/object:Gem::Version
|
@@ -71,7 +49,6 @@ dependencies:
|
|
71
49
|
type: :development
|
72
50
|
prerelease: false
|
73
51
|
version_requirements: !ruby/object:Gem::Requirement
|
74
|
-
none: false
|
75
52
|
requirements:
|
76
53
|
- - ~>
|
77
54
|
- !ruby/object:Gem::Version
|
@@ -79,7 +56,6 @@ dependencies:
|
|
79
56
|
- !ruby/object:Gem::Dependency
|
80
57
|
name: webmock
|
81
58
|
requirement: !ruby/object:Gem::Requirement
|
82
|
-
none: false
|
83
59
|
requirements:
|
84
60
|
- - ~>
|
85
61
|
- !ruby/object:Gem::Version
|
@@ -87,7 +63,6 @@ dependencies:
|
|
87
63
|
type: :development
|
88
64
|
prerelease: false
|
89
65
|
version_requirements: !ruby/object:Gem::Requirement
|
90
|
-
none: false
|
91
66
|
requirements:
|
92
67
|
- - ~>
|
93
68
|
- !ruby/object:Gem::Version
|
@@ -95,7 +70,6 @@ dependencies:
|
|
95
70
|
- !ruby/object:Gem::Dependency
|
96
71
|
name: vcr
|
97
72
|
requirement: !ruby/object:Gem::Requirement
|
98
|
-
none: false
|
99
73
|
requirements:
|
100
74
|
- - ~>
|
101
75
|
- !ruby/object:Gem::Version
|
@@ -103,16 +77,17 @@ dependencies:
|
|
103
77
|
type: :development
|
104
78
|
prerelease: false
|
105
79
|
version_requirements: !ruby/object:Gem::Requirement
|
106
|
-
none: false
|
107
80
|
requirements:
|
108
81
|
- - ~>
|
109
82
|
- !ruby/object:Gem::Version
|
110
83
|
version: 2.5.0
|
111
|
-
description:
|
112
|
-
|
113
|
-
|
84
|
+
description: |-
|
85
|
+
Up until until now, to quote RapGenius themselves,
|
86
|
+
"working at Rap Genius is the API". With this magical gem using the
|
87
|
+
private API in the 'Genius' iOS app you can access the wealth of data on
|
88
|
+
the internet Talmud in Ruby.
|
114
89
|
email:
|
115
|
-
- me
|
90
|
+
- me@timrogers.co.uk
|
116
91
|
- rspeicher@gmail.com
|
117
92
|
executables: []
|
118
93
|
extensions: []
|
@@ -125,47 +100,53 @@ files:
|
|
125
100
|
- README.md
|
126
101
|
- Rakefile
|
127
102
|
- lib/rapgenius.rb
|
128
|
-
- lib/rapgenius/
|
103
|
+
- lib/rapgenius/artist.rb
|
104
|
+
- lib/rapgenius/client.rb
|
129
105
|
- lib/rapgenius/exceptions.rb
|
130
|
-
- lib/rapgenius/
|
106
|
+
- lib/rapgenius/line.rb
|
107
|
+
- lib/rapgenius/media.rb
|
131
108
|
- lib/rapgenius/song.rb
|
132
109
|
- lib/rapgenius/version.rb
|
133
110
|
- pkg/rapgenius-0.0.1.gem
|
134
111
|
- pkg/rapgenius-0.0.2.gem
|
135
112
|
- pkg/rapgenius-0.0.3.gem
|
136
113
|
- rapgenius.gemspec
|
137
|
-
- spec/rapgenius/
|
138
|
-
- spec/rapgenius/
|
114
|
+
- spec/rapgenius/artist_spec.rb
|
115
|
+
- spec/rapgenius/client_spec.rb
|
116
|
+
- spec/rapgenius/line_spec.rb
|
117
|
+
- spec/rapgenius/media_spec.rb
|
139
118
|
- spec/rapgenius/song_spec.rb
|
140
119
|
- spec/spec_helper.rb
|
141
120
|
- spec/support/vcr.rb
|
142
121
|
homepage: https://github.com/timrogers/rapgenius
|
143
|
-
licenses:
|
122
|
+
licenses:
|
123
|
+
- MIT
|
124
|
+
metadata: {}
|
144
125
|
post_install_message:
|
145
126
|
rdoc_options: []
|
146
127
|
require_paths:
|
147
128
|
- lib
|
148
129
|
required_ruby_version: !ruby/object:Gem::Requirement
|
149
|
-
none: false
|
150
130
|
requirements:
|
151
|
-
- -
|
131
|
+
- - '>='
|
152
132
|
- !ruby/object:Gem::Version
|
153
133
|
version: '0'
|
154
134
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
155
|
-
none: false
|
156
135
|
requirements:
|
157
|
-
- -
|
136
|
+
- - '>='
|
158
137
|
- !ruby/object:Gem::Version
|
159
138
|
version: '0'
|
160
139
|
requirements: []
|
161
140
|
rubyforge_project:
|
162
|
-
rubygems_version:
|
141
|
+
rubygems_version: 2.0.3
|
163
142
|
signing_key:
|
164
|
-
specification_version:
|
143
|
+
specification_version: 4
|
165
144
|
summary: A gem for accessing lyrics and explanations on RapGenius.com
|
166
145
|
test_files:
|
167
|
-
- spec/rapgenius/
|
168
|
-
- spec/rapgenius/
|
146
|
+
- spec/rapgenius/artist_spec.rb
|
147
|
+
- spec/rapgenius/client_spec.rb
|
148
|
+
- spec/rapgenius/line_spec.rb
|
149
|
+
- spec/rapgenius/media_spec.rb
|
169
150
|
- spec/rapgenius/song_spec.rb
|
170
151
|
- spec/spec_helper.rb
|
171
152
|
- spec/support/vcr.rb
|
data/lib/rapgenius/annotation.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
module RapGenius
|
2
|
-
class Annotation
|
3
|
-
include RapGenius::Scraper
|
4
|
-
|
5
|
-
attr_reader :id, :song
|
6
|
-
|
7
|
-
def self.find(id)
|
8
|
-
self.new(id: id)
|
9
|
-
end
|
10
|
-
|
11
|
-
def initialize(kwargs)
|
12
|
-
@id = kwargs.delete(:id)
|
13
|
-
@song = kwargs.delete(:song)
|
14
|
-
@lyric = kwargs.delete(:lyric)
|
15
|
-
self.url = @id
|
16
|
-
end
|
17
|
-
|
18
|
-
def lyric
|
19
|
-
@lyric ||= document.css('meta[property="rap_genius:referent"]').
|
20
|
-
attr('content').to_s
|
21
|
-
end
|
22
|
-
|
23
|
-
def explanation
|
24
|
-
@explanation ||= document.css('meta[property="rap_genius:body"]').
|
25
|
-
attr('content').to_s
|
26
|
-
end
|
27
|
-
|
28
|
-
def song
|
29
|
-
@song ||= Song.new(song_url)
|
30
|
-
end
|
31
|
-
|
32
|
-
def song_url
|
33
|
-
@song_url ||= document.css('meta[property="rap_genius:song"]').
|
34
|
-
attr('content').to_s
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/lib/rapgenius/scraper.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'nokogiri'
|
2
|
-
require 'httparty'
|
3
|
-
|
4
|
-
module RapGenius
|
5
|
-
module Scraper
|
6
|
-
# Custom HTTParty parser that parses the returned body with Nokogiri
|
7
|
-
class NokogiriParser < HTTParty::Parser
|
8
|
-
SupportedFormats.merge!('text/html' => :html)
|
9
|
-
|
10
|
-
def html
|
11
|
-
Nokogiri::HTML(body)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# HTTParty client
|
16
|
-
#
|
17
|
-
# Sets some useful defaults for all of our requests.
|
18
|
-
#
|
19
|
-
# See Scraper#fetch
|
20
|
-
class Client
|
21
|
-
include HTTParty
|
22
|
-
|
23
|
-
format :html
|
24
|
-
parser NokogiriParser
|
25
|
-
base_uri 'http://rapgenius.com'
|
26
|
-
headers 'User-Agent' => "rapgenius.rb v#{RapGenius::VERSION}"
|
27
|
-
|
28
|
-
# Perform a search
|
29
|
-
#
|
30
|
-
# query - Query string
|
31
|
-
#
|
32
|
-
# Note: Currently only supports Song searching
|
33
|
-
#
|
34
|
-
# Returns a non-parsed (i.e., plaintext) response body
|
35
|
-
def self.search(query)
|
36
|
-
response = get("/search/quick", query: {q: query}, headers: default_search_headers)
|
37
|
-
response.body
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
# Default headers for a search request
|
43
|
-
#
|
44
|
-
# Tells RapGenius we only want Javascript so we get plaintext results back.
|
45
|
-
def self.default_search_headers
|
46
|
-
{
|
47
|
-
'X-Requested-With' => 'XMLHttpRequest',
|
48
|
-
'Referer' => base_uri,
|
49
|
-
'Accept' => 'application/x-javascript,text/javascript'
|
50
|
-
}
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
BASE_URL = Client.base_uri + "/".freeze
|
55
|
-
|
56
|
-
attr_reader :url
|
57
|
-
|
58
|
-
def url=(url)
|
59
|
-
unless url =~ /^https?:\/\//
|
60
|
-
@url = BASE_URL + url.gsub(/^\//, '')
|
61
|
-
else
|
62
|
-
@url = url
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def document
|
67
|
-
@document ||= fetch(@url)
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
def fetch(url)
|
73
|
-
response = Client.get(url)
|
74
|
-
|
75
|
-
if response.code != 200
|
76
|
-
raise ScraperError, "Received a #{response.code} HTTP response"
|
77
|
-
end
|
78
|
-
|
79
|
-
response.parsed_response
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module RapGenius
|
4
|
-
describe Annotation, vcr: {cassette_name: "big-sean-annotation"} do
|
5
|
-
|
6
|
-
let(:annotation) { described_class.new(id: "2092393") }
|
7
|
-
subject { annotation }
|
8
|
-
|
9
|
-
its(:id) { should eq "2092393" }
|
10
|
-
its(:url) { should eq "http://rapgenius.com/2092393" }
|
11
|
-
its(:song) { should be_a Song }
|
12
|
-
its(:song_url) { should eq "http://rapgenius.com/Big-sean-control-lyrics" }
|
13
|
-
|
14
|
-
describe "#lyric" do
|
15
|
-
it "should have the correct lyric" do
|
16
|
-
annotation.lyric.should match "You gon' get this rain like it's May weather"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "#explanation" do
|
21
|
-
it "should have the correct explanation" do
|
22
|
-
annotation.explanation.should include "making it rain"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
describe '.find' do
|
27
|
-
it "returns a new instance at the specified path" do
|
28
|
-
i = described_class.find("foobar")
|
29
|
-
i.should be_an Annotation
|
30
|
-
i.id.should eq "foobar"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
context "with additional parameters passed into the constructor" do
|
35
|
-
let(:annotation) { described_class.new(id: "5678", lyric: "foo") }
|
36
|
-
|
37
|
-
its(:id) { should eq "5678" }
|
38
|
-
its(:lyric) { should eq "foo" }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class ScraperTester
|
4
|
-
include RapGenius::Scraper
|
5
|
-
end
|
6
|
-
|
7
|
-
module RapGenius
|
8
|
-
describe Scraper do
|
9
|
-
|
10
|
-
let(:scraper) { ScraperTester.new }
|
11
|
-
|
12
|
-
describe "#url=" do
|
13
|
-
it "forms the URL with the base URL, if the current path is relative" do
|
14
|
-
scraper.url = "foobar"
|
15
|
-
scraper.url.should include RapGenius::Scraper::BASE_URL
|
16
|
-
end
|
17
|
-
|
18
|
-
it "leaves the URL as it is if already complete" do
|
19
|
-
scraper.url = "http://foobar.com/baz"
|
20
|
-
scraper.url.should eq "http://foobar.com/baz"
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe "#document" do
|
25
|
-
before do
|
26
|
-
scraper.url = "http://foo.bar/"
|
27
|
-
end
|
28
|
-
|
29
|
-
context "with a successful request" do
|
30
|
-
before do
|
31
|
-
stub_request(:get, "http://foo.bar").to_return({body: 'ok', status: 200})
|
32
|
-
end
|
33
|
-
|
34
|
-
it "returns a Nokogiri document object" do
|
35
|
-
scraper.document.should be_a Nokogiri::HTML::Document
|
36
|
-
end
|
37
|
-
|
38
|
-
it "contains the tags in page received back from the HTTP request" do
|
39
|
-
scraper.document.css('body').length.should eq 1
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
context "with a failed request" do
|
44
|
-
before do
|
45
|
-
stub_request(:get, "http://foo.bar").to_return({body: '', status: 404})
|
46
|
-
end
|
47
|
-
|
48
|
-
it "raises a ScraperError" do
|
49
|
-
expect { scraper.document }.to raise_error(RapGenius::ScraperError)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|