rapgenius 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +38 -0
- data/Rakefile +7 -0
- data/lib/rapgenius.rb +5 -0
- data/lib/rapgenius/annotation.rb +36 -0
- data/lib/rapgenius/exceptions.rb +4 -0
- data/lib/rapgenius/scraper.rb +35 -0
- data/lib/rapgenius/song.rb +44 -0
- data/lib/rapgenius/version.rb +3 -0
- data/rapgenius.gemspec +26 -0
- data/spec/annotation_spec.rb +68 -0
- data/spec/scraper_spec.rb +64 -0
- data/spec/song_spec.rb +29 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/support/annotation.html +440 -0
- data/spec/support/song.html +1358 -0
- metadata +133 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
rapgenius (0.0.1)
|
5
|
+
httparty (~> 0.11.0)
|
6
|
+
nokogiri (~> 1.6.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
diff-lcs (1.2.4)
|
12
|
+
httparty (0.11.0)
|
13
|
+
multi_json (~> 1.0)
|
14
|
+
multi_xml (>= 0.5.2)
|
15
|
+
metaclass (0.0.1)
|
16
|
+
mini_portile (0.5.1)
|
17
|
+
mocha (0.14.0)
|
18
|
+
metaclass (~> 0.0.1)
|
19
|
+
multi_json (1.7.9)
|
20
|
+
multi_xml (0.5.5)
|
21
|
+
nokogiri (1.6.0)
|
22
|
+
mini_portile (~> 0.5.0)
|
23
|
+
rspec (2.14.1)
|
24
|
+
rspec-core (~> 2.14.0)
|
25
|
+
rspec-expectations (~> 2.14.0)
|
26
|
+
rspec-mocks (~> 2.14.0)
|
27
|
+
rspec-core (2.14.5)
|
28
|
+
rspec-expectations (2.14.2)
|
29
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
30
|
+
rspec-mocks (2.14.3)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
mocha (~> 0.14.0)
|
37
|
+
rapgenius!
|
38
|
+
rspec (~> 2.14.1)
|
data/Rakefile
ADDED
data/lib/rapgenius.rb
ADDED
@@ -0,0 +1,36 @@
|
|
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
|
+
entry_path = document.css('meta[property="rap_genius:song"]').
|
30
|
+
attr('content').to_s
|
31
|
+
|
32
|
+
@song ||= Song.new(entry_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'httparty'
|
3
|
+
|
4
|
+
module RapGenius
|
5
|
+
module Scraper
|
6
|
+
BASE_URL = "http://rapgenius.com/".freeze
|
7
|
+
|
8
|
+
attr_reader :url
|
9
|
+
|
10
|
+
|
11
|
+
def url=(url)
|
12
|
+
if !(url =~ /^https?:\/\//)
|
13
|
+
@url = "#{BASE_URL}#{url}"
|
14
|
+
else
|
15
|
+
@url = url
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def document
|
20
|
+
@document ||= Nokogiri::HTML(fetch(@url))
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def fetch(url)
|
25
|
+
response = HTTParty.get(url)
|
26
|
+
|
27
|
+
if response.code != 200
|
28
|
+
raise ScraperError, "Received a #{response.code} HTTP response"
|
29
|
+
end
|
30
|
+
|
31
|
+
response.body
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module RapGenius
|
3
|
+
class Song
|
4
|
+
include RapGenius::Scraper
|
5
|
+
|
6
|
+
def initialize(path)
|
7
|
+
self.url = path
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
document.css('.song_title a').text
|
12
|
+
end
|
13
|
+
|
14
|
+
def title
|
15
|
+
document.css('.edit_song_description i').text
|
16
|
+
end
|
17
|
+
|
18
|
+
def description
|
19
|
+
document.css('.description_body').text
|
20
|
+
end
|
21
|
+
|
22
|
+
def images
|
23
|
+
document.css('meta[property="og:image"]').
|
24
|
+
map { |meta| meta.attr('content') }
|
25
|
+
end
|
26
|
+
|
27
|
+
def full_artist
|
28
|
+
document.css('meta[property="og:title"]').attr('content').to_s.
|
29
|
+
split(" – ").first
|
30
|
+
end
|
31
|
+
|
32
|
+
def annotations
|
33
|
+
@annotations ||= document.css('.lyrics a').map do |a|
|
34
|
+
Annotation.new(
|
35
|
+
id: a.attr('data-id').to_s,
|
36
|
+
song: self,
|
37
|
+
lyric: a.text
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/rapgenius.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "rapgenius/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "rapgenius"
|
7
|
+
s.version = RapGenius::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Tim Rogers"]
|
10
|
+
s.email = ["me@timrogers.co.uk"]
|
11
|
+
s.homepage = "http://timrogers.co.uk"
|
12
|
+
s.summary = %q{A gem for accessing lyrics and explanations on RapGenius.com}
|
13
|
+
s.description = %q{Up until until now, to quote RapGenius themselves,
|
14
|
+
"working at Rap Genius is the API". With this magical screen-scraping gem,
|
15
|
+
you can access the wealth of data on the internet Talmud in Ruby.}
|
16
|
+
|
17
|
+
s.add_runtime_dependency "nokogiri", "~>1.6.0"
|
18
|
+
s.add_runtime_dependency "httparty", "~>0.11.0"
|
19
|
+
s.add_development_dependency "rspec", "~>2.14.1"
|
20
|
+
s.add_development_dependency "mocha", "~>0.14.0"
|
21
|
+
|
22
|
+
s.files = `git ls-files`.split("\n")
|
23
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
24
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RapGenius::Annotation do
|
4
|
+
|
5
|
+
let(:annotation) { described_class.new(id: "1234") }
|
6
|
+
subject { annotation }
|
7
|
+
|
8
|
+
before do
|
9
|
+
RapGenius::Annotation.any_instance.stubs(:fetch).
|
10
|
+
returns(
|
11
|
+
File.read(File.expand_path("../support/annotation.html", __FILE__))
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".find" do
|
16
|
+
subject { described_class.find("9999") }
|
17
|
+
|
18
|
+
its(:id) { should eq "9999"}
|
19
|
+
|
20
|
+
it "should fetch the document to get annotation details" do
|
21
|
+
subject.expects(:fetch).once.returns(
|
22
|
+
File.read(File.expand_path("../support/annotation.html", __FILE__))
|
23
|
+
)
|
24
|
+
|
25
|
+
subject.explanation
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
its(:id) { should eq "1234" }
|
30
|
+
its(:url) { should eq "http://rapgenius.com/1234" }
|
31
|
+
|
32
|
+
describe "#lyric" do
|
33
|
+
subject { annotation.lyric }
|
34
|
+
it "only calls fetch the first time" do
|
35
|
+
annotation.expects(:fetch).once.returns(
|
36
|
+
File.read(File.expand_path("../support/annotation.html", __FILE__))
|
37
|
+
)
|
38
|
+
|
39
|
+
2.times { annotation.lyric }
|
40
|
+
end
|
41
|
+
|
42
|
+
it { should eq "You gon' get this rain like it's May weather," }
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#explanation" do
|
46
|
+
subject { annotation.explanation }
|
47
|
+
it "only calls fetch the first time" do
|
48
|
+
annotation.expects(:fetch).once.returns(
|
49
|
+
File.read(File.expand_path("../support/annotation.html", __FILE__))
|
50
|
+
)
|
51
|
+
|
52
|
+
2.times { annotation.explanation }
|
53
|
+
end
|
54
|
+
|
55
|
+
it { should include "making it rain" }
|
56
|
+
end
|
57
|
+
|
58
|
+
its(:song) { should be_a RapGenius::Song }
|
59
|
+
its("song.url") { should eq "http://rapgenius.com/Big-sean-control-lyrics" }
|
60
|
+
|
61
|
+
context "with additional parameters passed into the constructor" do
|
62
|
+
let(:annotation) { described_class.new(id: "5678", lyric: "foo") }
|
63
|
+
|
64
|
+
its(:id) { should eq "5678" }
|
65
|
+
its(:lyric) { should eq "foo" }
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ScraperTester
|
4
|
+
include RapGenius::Scraper
|
5
|
+
end
|
6
|
+
|
7
|
+
describe RapGenius::Scraper do
|
8
|
+
|
9
|
+
let(:scraper) { ScraperTester.new }
|
10
|
+
let(:successful_request) { stub(body: "<body></body>", code: 200) }
|
11
|
+
let(:failed_request) { stub(body: "<html></html>", code: 404) }
|
12
|
+
|
13
|
+
it "stores a base URL" do
|
14
|
+
RapGenius::Scraper::BASE_URL.should be_a String
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#url=" do
|
18
|
+
it "forms the URL with the base URL, if the current path is relative" do
|
19
|
+
scraper.url = "foobar"
|
20
|
+
scraper.url.should include RapGenius::Scraper::BASE_URL
|
21
|
+
end
|
22
|
+
|
23
|
+
it "leaves the URL as it is if already complete" do
|
24
|
+
scraper.url = "http://foobar.com/baz"
|
25
|
+
scraper.url.should eq "http://foobar.com/baz"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#fetch" do
|
30
|
+
it "uses HTTParty's .get method" do
|
31
|
+
HTTParty.expects(:get).with("http://foo.bar").
|
32
|
+
once.returns(successful_request)
|
33
|
+
|
34
|
+
scraper.send(:fetch, "http://foo.bar")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises an exception if it doesn't get a 200 response" do
|
38
|
+
HTTParty.expects(:get).with("http://foo.bar").returns(failed_request)
|
39
|
+
|
40
|
+
expect{ scraper.send(:fetch, "http://foo.bar") }.
|
41
|
+
to raise_error RapGenius::ScraperError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#document" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
HTTParty.expects(:get).with("http://foo.bar").
|
49
|
+
once.returns(successful_request)
|
50
|
+
scraper.url = "http://foo.bar"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns a Nokogiri object" do
|
54
|
+
scraper.document.should be_a Nokogiri::HTML::Document
|
55
|
+
end
|
56
|
+
|
57
|
+
it "contains the tags in page received back from the HTTP request" do
|
58
|
+
scraper.document.css('body').length.should eq 1
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
data/spec/song_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe RapGenius::Song do
|
4
|
+
|
5
|
+
subject { described_class.new("foobar") }
|
6
|
+
|
7
|
+
before do
|
8
|
+
RapGenius::Song.any_instance.stubs(:fetch).
|
9
|
+
returns(File.read(File.expand_path("../support/song.html", __FILE__)))
|
10
|
+
end
|
11
|
+
|
12
|
+
its(:url) { should eq "http://rapgenius.com/foobar" }
|
13
|
+
its(:title) { should eq "Control" }
|
14
|
+
its(:artist) { should eq "Big Sean" }
|
15
|
+
its(:description) { should include "blew up the Internet" }
|
16
|
+
its(:images) { should be_a Array }
|
17
|
+
|
18
|
+
its(:images) do
|
19
|
+
should include(
|
20
|
+
"http://s3.amazonaws.com/rapgenius/1375029260_Big%20Sean.png"
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
its(:full_artist) { should include "(Ft. Jay Electronica & Kendrick Lamar)"}
|
25
|
+
its(:annotations) { should be_a Array }
|
26
|
+
its("annotations.length") { should eq 132 }
|
27
|
+
its("annotations.first") { should be_a RapGenius::Annotation }
|
28
|
+
|
29
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,440 @@
|
|
1
|
+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
2
|
+
"http://www.w3.org/TR/html4/strict.dtd">
|
3
|
+
<html>
|
4
|
+
<head><script type="text/javascript">var NREUMQ=NREUMQ||[];NREUMQ.push(["mark","firstbyte",new Date().getTime()]);</script>
|
5
|
+
<title>You gon' get this rain like it's May weather, – Control by Big Sean</title>
|
6
|
+
|
7
|
+
|
8
|
+
<script type="text/javascript">
|
9
|
+
var gaJsHost = "http://www.";
|
10
|
+
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
11
|
+
</script>
|
12
|
+
<script type="text/javascript">
|
13
|
+
try{
|
14
|
+
var pageTracker = _gat._getTracker("UA-10346621-1");
|
15
|
+
pageTracker._initData();
|
16
|
+
} catch(err) {}</script>
|
17
|
+
|
18
|
+
<!-- <script type="text/javascript">
|
19
|
+
var _sf_async_config={uid:3877,domain:"rapgenius.com"};
|
20
|
+
</script>
|
21
|
+
<script src='http://static.chartbeat.com/js/chartbeat.js' type="text/javascript" language="javascript"></script> -->
|
22
|
+
|
23
|
+
|
24
|
+
<script type="text/javascript">
|
25
|
+
//<![CDATA[
|
26
|
+
window.location = "http://rapgenius.com/Big-sean-control-lyrics#note-2092393"
|
27
|
+
//]]>
|
28
|
+
</script>
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
<meta property="og:type" content="rap_genius:annotation" />
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
<meta property="og:url" content="http://rapgenius.com/2092393/Big-sean-control/You-gon-get-this-rain-like-its-may-weather" />
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
<meta property="og:see_also" content="http://rapgenius.com/Big-sean-control-lyrics" />
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
<meta property="og:description" content="Rain is a pretty common occurrence in the month of May. But the line also includes some wordplay where rain refers to making it rain, like Floyd “Money” Mayweather. Floyd is the highest paid athlete in the world, so he sure can make it rain.
|
45
|
+
|
46
|
+
Making it rain refers to the act of throwing wads of cash in the air so that the bills rain down, normally onto a stripper.
|
47
|
+
|
48
|
+
" />
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
<meta property="og:image" content="http://s3.amazonaws.com/rapgenius/1376360792_floyd-mayweather46.jpg" />
|
53
|
+
|
54
|
+
<meta property="og:image" content="http://s3.amazonaws.com/rapgenius/1376434983_jay-electronica.jpg" />
|
55
|
+
|
56
|
+
<meta property="og:image" content="http://s3.amazonaws.com/rapgenius/1375029260_Big%20Sean.png" />
|
57
|
+
|
58
|
+
<meta property="og:image" content="http://s3.amazonaws.com/rapgenius/Kendrick-Lamar-1024x680.jpg" />
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
<meta property="og:title" content="Rap Genius’s annotation of “You gon' get this rain like it's May weather,” from “Control”" />
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
<meta property="rap_genius:song" content="http://rapgenius.com/Big-sean-control-lyrics" />
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
<meta property="rap_genius:body" content="Rain is a pretty common occurrence in the month of May. But the line also includes some wordplay where rain refers to making it rain, like Floyd “Money” Mayweather. Floyd is the highest paid athlete in the world, so he sure can make it rain.
|
76
|
+
|
77
|
+
Making it rain refers to the act of throwing wads of cash in the air so that the bills rain down, normally onto a stripper.
|
78
|
+
|
79
|
+
" />
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
<meta property="rap_genius:referent" content="You gon' get this rain like it's May weather," />
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
<meta property="rap_genius:song_title" content="Control" />
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
<meta name="description" content="Rain is a pretty common occurrence in the month of May. But the line also includes some wordplay where rain refers to making it rain, like Floyd “Money” Mayweather. Floyd is the highest paid athlete in the world, so he sure can make it rain.
|
92
|
+
|
93
|
+
Making it rain refers to the act of throwing wads of cash in the air so that the bills rain down, normally onto a stripper." />
|
94
|
+
|
95
|
+
<meta property="og:site_name" content="Rap Genius"/>
|
96
|
+
<meta property="fb:app_id" content="265539304824" />
|
97
|
+
|
98
|
+
<style>
|
99
|
+
@font-face {
|
100
|
+
font-family: 'DinBoldCondensed';
|
101
|
+
src: url(http://assets.rapgenius.com/fonts/DINWeb-CondBold.eot?1376699523&sub=);
|
102
|
+
src: local('☺'),
|
103
|
+
url(http://assets.rapgenius.com/fonts/DINWeb-CondBold.woff?1376699523&sub=) format('woff'),
|
104
|
+
url(http://assets.rapgenius.com/fonts/DINComp-CondBold.ttf?1376699523&sub=) format('truetype');
|
105
|
+
font-weight: normal;
|
106
|
+
font-style: normal;
|
107
|
+
}
|
108
|
+
</style>
|
109
|
+
|
110
|
+
<script type="text/javascript">
|
111
|
+
//<![CDATA[
|
112
|
+
var AUTH_TOKEN = "nF4AGT6o70aQ/geGVrgNIvi+8MUNwVYQBH4lN3ankw4=";
|
113
|
+
//]]>
|
114
|
+
</script>
|
115
|
+
<script type="text/javascript">
|
116
|
+
//<![CDATA[
|
117
|
+
var disqus_developer = 0;
|
118
|
+
//]]>
|
119
|
+
</script>
|
120
|
+
<script type="text/javascript">
|
121
|
+
//<![CDATA[
|
122
|
+
var PRODUCTION_ENV = true;
|
123
|
+
//]]>
|
124
|
+
</script>
|
125
|
+
<script type="text/javascript">
|
126
|
+
//<![CDATA[
|
127
|
+
var MOBILE_DEVICE = false;
|
128
|
+
//]]>
|
129
|
+
</script>
|
130
|
+
<script type="text/javascript">
|
131
|
+
//<![CDATA[
|
132
|
+
var CURRENT_USER = null
|
133
|
+
//]]>
|
134
|
+
</script>
|
135
|
+
<script type="text/javascript">
|
136
|
+
//<![CDATA[
|
137
|
+
var ADMIN_LOGGED_IN = false;
|
138
|
+
//]]>
|
139
|
+
</script>
|
140
|
+
|
141
|
+
|
142
|
+
<script type="text/javascript">
|
143
|
+
//<![CDATA[
|
144
|
+
var PUSHER_APP_KEY = '6d893fcc6a0c695853ac';
|
145
|
+
//]]>
|
146
|
+
</script>
|
147
|
+
<script type="text/javascript">
|
148
|
+
//<![CDATA[
|
149
|
+
var SOUNDCLOUD_CLIENT_ID = '632c544d1c382f82526f369877aab5c0';
|
150
|
+
//]]>
|
151
|
+
</script>
|
152
|
+
|
153
|
+
<script type="text/javascript">
|
154
|
+
//<![CDATA[
|
155
|
+
var FILEPICKER_API_KEY = 'Ar03MDs73TQm241ZgLwfjz';
|
156
|
+
//]]>
|
157
|
+
</script>
|
158
|
+
<script type="text/javascript">
|
159
|
+
//<![CDATA[
|
160
|
+
var FILEPICKER_POLICY = 'eyJjYWxsIjpbInBpY2siLCJwaWNrQW5kU3RvcmUiLCJzdG9yZSIsInJlYWQiXSwiZXhwaXJ5IjoiMTQ1ODIyODIyMiJ9';
|
161
|
+
//]]>
|
162
|
+
</script>
|
163
|
+
<script type="text/javascript">
|
164
|
+
//<![CDATA[
|
165
|
+
var FILEPICKER_SIGNATURE = '6dea69d4bb3a9273da40b82319809f8a65cbb452822bca47675cffb2b5dece92';
|
166
|
+
//]]>
|
167
|
+
</script>
|
168
|
+
<script type="text/javascript">
|
169
|
+
//<![CDATA[
|
170
|
+
var DISABLE_VIDEO_RECORDING = false;
|
171
|
+
//]]>
|
172
|
+
</script>
|
173
|
+
|
174
|
+
<script type="text/javascript">
|
175
|
+
//<![CDATA[
|
176
|
+
var FIREHOSE_PUSHER_CHANNEL = 'activity_stream.firehose';
|
177
|
+
//]]>
|
178
|
+
</script>
|
179
|
+
|
180
|
+
<script type="text/javascript">
|
181
|
+
//<![CDATA[
|
182
|
+
var S3_IMAGE_BUCKET = 'filepicker-images-rapgenius';
|
183
|
+
//]]>
|
184
|
+
</script>
|
185
|
+
<script type="text/javascript">
|
186
|
+
//<![CDATA[
|
187
|
+
var S3_AUDIO_BUCKET = 'rapgenius-audio';
|
188
|
+
//]]>
|
189
|
+
</script>
|
190
|
+
|
191
|
+
<script type="text/javascript">
|
192
|
+
//<![CDATA[
|
193
|
+
var EMBEDLY_KEY = 'fc778e44915911e088ae4040f9f86dcd'
|
194
|
+
//]]>
|
195
|
+
</script>
|
196
|
+
|
197
|
+
<script type="text/javascript">
|
198
|
+
//<![CDATA[
|
199
|
+
var CAMERA_TAG_UUID = '62243f30-7952-0130-3e29-1231390fcc11'
|
200
|
+
//]]>
|
201
|
+
</script>
|
202
|
+
<script type="text/javascript">
|
203
|
+
//<![CDATA[
|
204
|
+
var CAMERA_TAG_WIDTH = 450
|
205
|
+
//]]>
|
206
|
+
</script>
|
207
|
+
<script type="text/javascript">
|
208
|
+
//<![CDATA[
|
209
|
+
var CAMERA_TAG_HEIGHT = 253
|
210
|
+
//]]>
|
211
|
+
</script>
|
212
|
+
|
213
|
+
<script type="text/javascript">
|
214
|
+
//<![CDATA[
|
215
|
+
var CANONICAL_DOMAIN_PARTS_LENGTH = 2
|
216
|
+
//]]>
|
217
|
+
</script>
|
218
|
+
<script type="text/javascript">
|
219
|
+
//<![CDATA[
|
220
|
+
var VALID_SUBDOMAINS = ["rock","poetry","news"]
|
221
|
+
//]]>
|
222
|
+
</script>
|
223
|
+
|
224
|
+
<script type="text/javascript">
|
225
|
+
//<![CDATA[
|
226
|
+
|
227
|
+
var I18n = I18n || {};
|
228
|
+
|
229
|
+
I18n.defaultLocale = "en";
|
230
|
+
I18n.locale = "en";
|
231
|
+
|
232
|
+
I18n.translations = {"en":{"support":{"select":{"prompt":"Please select"},"array":{"words_connector":", ","two_words_connector":" and ","last_word_connector":", and "}},"date":{"order":["year","month","day"],"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"formats":{"default":"%Y-%m-%d","short":"%b %d","long":"%B %d, %Y"}},"annotation":{"present_participle":"annotating","singular_noun":"annotation","past_tense":"annotated","singular_present":"annotates","plural_noun":"annotations","present_tense":"annotate"},"contributor_guidelines":{"song_id":1582},"number":{"precision":{"format":{"delimiter":""}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"storage_units":{"units":{"gb":"GB","tb":"TB","kb":"KB","byte":{"one":"Byte","other":"Bytes"},"mb":"MB"},"format":"%n %u"},"format":{"delimiter":"","precision":1}},"percentage":{"format":{"delimiter":""}},"currency":{"format":{"delimiter":",","precision":2,"unit":"$","format":"%u%n","separator":"."}}},"poetry":{"text_type":"text","name_for_body_content":"the text","homepage_title":"Discover the Meaning of Literature | %{channel_name}","sle":{"edit_instruction":"Edit the description to add:","historical_context":"the work's place in history, how it was received","overall_story":"An explanation of the work's overall story (example: \"Here, Byron evokes the classic struggle of forbidden love against desire...\")","miscellaneous":"A description of the work's overall style and tone"},"iq":"Poetry IQ\u2122","search_placeholder":"author, title, or contents","suggestions":{"instructions":"You can also click the orange links to leave a comment on a specific portion of the text"},"intro_text":"%{channel_name} annotates all literature \u2013 your guide to the global canon"},"datetime":{"distance_in_words":{"less_than_x_seconds":{"one":"less than 1 second","other":"less than %{count} seconds"},"half_a_minute":"half a minute","about_x_hours":{"one":"an hour","other":"%{count} hours"},"about_x_years":{"one":"a year","other":"%{count} years"},"x_days":{"one":"1 day","other":"%{count} days"},"x_seconds":{"one":"1 second","other":"%{count} seconds"},"less_than_x_minutes":{"one":"less than a minute","other":"less than %{count} minutes"},"over_x_years":{"one":"a year","other":"%{count} years"},"about_x_months":{"one":"a month","other":"%{count} months"},"x_minutes":{"one":"1 minute","other":"%{count} minutes"},"almost_x_years":{"one":"a year","other":"%{count} years"},"x_months":{"one":"1 month","other":"%{count} months"}},"prompts":{"day":"Day","second":"Seconds","minute":"Minute","month":"Month","year":"Year","hour":"Hour"}},"activemodel":{"activity_stream_line_item_message":{"message":{"default":"%{actors} %{verb} %{target} %{context}","user":{"make_moderator":{"user":{"one":"%{actors} made %{target} a moderator","other":"%{actors} made %{target} moderators"}},"create":{"identity":"Your %{provider} friend %{name} is on Rap Genius!"},"Follow":{"artist":"%{actors} followed you"},"make_editor":{"user":{"one":"%{actors} made %{target} an editor","other":"%{actors} made %{target} editors"}}}},"targets":{"users":{"one":"%{target} and one other user","zero":"%{target}","other":"%{target} and %{count} other users"}}}},"rock":{"text_type":"song","name_for_body_content":"lyrics","homepage_title":"Discover the Meaning of Lyrics | %{channel_name}","sle":{"edit_instruction":"Edit song description to add:","historical_context":"what album the song's on, how popular it was","overall_story":"An explanation of the song's overall story (example: \"In this song, Kurt breaks down a day at his grandparents' house\")","miscellaneous":"The song's instrumentation and sound"},"iq":"Rock IQ\u2122","map":{"description":"Your Guide to International Sex, Drugs and Rock & Roll","description_meta_tag":"The Rock Map is your guide to international Sex, Drugs and Rock & Roll. If you're looking for the Eagles' real Hotel California, or what 'Back Home' means to Eric Clapton \u2013 check out the Rock Map.","name":"The Rock Map"},"search_placeholder":"artist, song title, or lyrics","suggestions":{"instructions":"You can also click the orange lyrics to leave a comment on a specific line"},"intro_text":"%{channel_name} is your guide to the world of rock, pop, indie, and more."},"news":{"text_type":"text","name_for_body_content":"the text","homepage_title":"Make Sense of the News | %{channel_name}","sle":{"edit_instruction":"Edit news description to add:","historical_context":"how the event or text affects the world and history","overall_story":"An explanation of the work's overall story (example: \"Here, President Obama confirms the legality of drone strikes...\")","miscellaneous":"The work's impact on current issues"},"iq":"News IQ\u2122","search_placeholder":"author, title, or contents","suggestions":{"instructions":"You can also click the orange links to leave a comment on a specific portion of the text"},"intro_text":"%{channel_name} breaks down breaking news \u2013 write on the wall of history"},"time":{"pm":"pm","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","short":"%d %b %H:%M","long":"%B %d, %Y %H:%M"},"am":"am"},"for_beginners":{"song_id":77368},"users":{"show":{"auto_syndicate":{"facebook":"Post annotations, upvotes, and songs you create to your timeline"}}},"activerecord":{"models":{"twitter_identity":"Twitter","facebook_identity":"Facebook","forum_post":"Post"},"errors":{"messages":{"not_a_number":"is not a number","less_than":"must be less than %{count}","taken":"has already been taken","empty":"can't be empty","too_short":"is too short (minimum is %{count} characters)","accepted":"must be accepted","record_invalid":"Validation failed: %{errors}","less_than_or_equal_to":"must be less than or equal to %{count}","too_long":"is too long (maximum is %{count} characters)","invalid":"is invalid","odd":"must be odd","blank":"can't be blank","greater_than":"must be greater than %{count}","confirmation":"doesn't match confirmation","even":"must be even","inclusion":"is not included in the list","greater_than_or_equal_to":"must be greater than or equal to %{count}","equal_to":"must be equal to %{count}","wrong_length":"is the wrong length (should be %{count} characters)","exclusion":"is reserved"},"template":{"body":"There were problems with the following fields:","header":{"one":"1 error prohibited this %{model} from being saved","other":"%{count} errors prohibited this %{model} from being saved"}},"full_messages":{"format":"%{attribute} %{message}"}}},"rap":{"text_type":"song","name_for_body_content":"lyrics","homepage_title":"Discover the Meaning of Rap Lyrics | %{channel_name}","sle":{"edit_instruction":"Edit song description to add:","historical_context":"what album the song's on, how popular it was","overall_story":"An explanation of the song's overall story (example: \"In this song, Eminem corresponds with a crazed fan who ends up...\")","miscellaneous":"The sample used for the beat \u2014 use <a href=\"http://whosampled.com\">WhoSampled.com</a> and wikipedia as references"},"iq":"Rap IQ\u2122","map":{"description":"Mapping the Hip-Hop Terrain of the Planet","description_meta_tag":"The Rap Map guides you through the hip-hop terrain of the planet. If you're looking for Jay-Z's birthplace or Lil Wayne's neighborhood \u2014 check out the Rap Map.","name":"The Rap Map"},"search_placeholder":"rapper, song title, or lyrics","suggestions":{"instructions":"You can also click the orange lyrics to leave a comment on a specific line"},"intro_text":"%{channel_name} annotates rap lyrics \u2013 a hip-hop Wikipedia"}}};
|
233
|
+
|
234
|
+
var CURRENT_CHANNEL = "rap"
|
235
|
+
|
236
|
+
//]]>
|
237
|
+
</script>
|
238
|
+
|
239
|
+
<link href="http://assets.rapgenius.com/stylesheets/compiled/screen-45f88782c55edfaa7e66f321db3149d1.css" media="screen" rel="stylesheet" type="text/css" />
|
240
|
+
<link href="http://assets.rapgenius.com/favicon.ico?1376699523" rel="shortcut icon" />
|
241
|
+
|
242
|
+
</head>
|
243
|
+
<body class="act-show cont-annotations">
|
244
|
+
<div id="container">
|
245
|
+
<div id="header"></div>
|
246
|
+
|
247
|
+
<div id="main">
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
|
253
|
+
|
254
|
+
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
<h1>You gon' get this rain like it's May weather,</h1>
|
259
|
+
|
260
|
+
<p>from <a href="/Big-sean-control-lyrics" class=" song_link">
|
261
|
+
<span class="title_with_artists">
|
262
|
+
Big Sean (Ft. Jay Electronica & Kendrick Lamar) – Control Lyrics
|
263
|
+
</span>
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
</a> on <a href="http://rapgenius.com/">Rap Genius</a></p>
|
268
|
+
|
269
|
+
<div class="big_header">Meaning</div>
|
270
|
+
<p><strong>Rain</strong> is a pretty common occurrence in the month of <strong>May</strong>. But the line also includes some wordplay where <strong>rain</strong> refers to <a href="http://www.urbandictionary.com/define.php?term=make%20it%20rain" rel="nofollow"><strong>making it rain</strong>,</a> like Floyd “Money” <strong>Mayweather</strong>. Floyd is the <a href="http://www.forbes.com/pictures/mli45igdi/1-floyd-mayweather/" rel="nofollow">highest paid athlete</a> in the world, so he sure <em>can</em> make it rain.</p>
|
271
|
+
|
272
|
+
<p>Making it rain refers to the act of throwing wads of cash in the air so that the bills rain down, normally onto a stripper.</p>
|
273
|
+
|
274
|
+
<p><img src="http://s3.amazonaws.com/rapgenius/1376360792_floyd-mayweather46.jpg" alt="" /></p>
|
275
|
+
|
276
|
+
<p><em>To help improve the meaning of these lyrics, visit <a href="/Big-sean-control-lyrics" class=" song_link">
|
277
|
+
<span class="title_with_artists">
|
278
|
+
"Control" by Big Sean (Ft. Jay Electronica & Kendrick Lamar) Lyrics
|
279
|
+
</span>
|
280
|
+
|
281
|
+
|
282
|
+
|
283
|
+
</a> and leave a comment on the lyrics box</em></p>
|
284
|
+
|
285
|
+
</div>
|
286
|
+
|
287
|
+
<div id="footer">
|
288
|
+
<div id="edit_annotation_form" style="display:none">
|
289
|
+
<div class='edit_annotation_form'>
|
290
|
+
|
291
|
+
<button class="correct_lyrics toggle_target" data-target="~ .lyric_editor" data-relative="true" data-focus=".lyric_editor:visible .lyric_text">Correct lyrics</button>
|
292
|
+
<div class="lyric_editor">
|
293
|
+
<div class="edit_label">Correct lyrics:</div>
|
294
|
+
<textarea class="lyric_text" rows=2 cols=20 tabindex="0"></textarea>
|
295
|
+
<button class="submit_annotation">Save <small>(shift+enter)</small></button>
|
296
|
+
</div>
|
297
|
+
|
298
|
+
<div class="video_controls">
|
299
|
+
<button class="record_video ">Record a Video Annotation </button>
|
300
|
+
</div>
|
301
|
+
<div class="video_recorder_container"></div>
|
302
|
+
|
303
|
+
<div class="or_divider">or</div>
|
304
|
+
|
305
|
+
<button class="verified_text_button toggle_target" data-target="~ .annotation_text_wrapper" data-relative="true" data-focus=".annotation_text_wrapper:visible .annotation_text">Write an Annotation</button>
|
306
|
+
|
307
|
+
<div class="annotation_text_wrapper">
|
308
|
+
<div class="edit_label">Write an Annotation:</div>
|
309
|
+
<textarea class="annotation_text" required="required" rows=10 cols=20 tabindex="1"></textarea>
|
310
|
+
<div class="image_adder_container"><a href="#" class="image_adder" tabindex="3">Click here to add an image</a> or just paste in a URL (ending .jpg, .png, etc.)</div>
|
311
|
+
|
312
|
+
<div class="verified_artist explanation_instructions">
|
313
|
+
To add an image, just paste in the URL (ending .jpg, .png, etc)
|
314
|
+
</div>
|
315
|
+
<button class="submit_annotation" tabindex="2">Save <small>(shift+enter)</small></button>
|
316
|
+
</div>
|
317
|
+
|
318
|
+
<div class="video_id_container">
|
319
|
+
Vidyard video id: <input class="video_id" tabindex="4"></input>
|
320
|
+
<button class="submit_annotation">Save <small>(shift+enter)</small></button>
|
321
|
+
</div>
|
322
|
+
|
323
|
+
<div class="explanation_instructions">
|
324
|
+
<h3 class="explanation_only">Style Guidelines:</h3>
|
325
|
+
<h3 class="popup_only">Formatting Help:</h3>
|
326
|
+
<ul>
|
327
|
+
|
328
|
+
<li class="explanation_only nerdspeak">Before annotating, ask yourself: <a href="/837333">is this interesting?</a> <a href="/837268">Does this add anything to the line?</a></li>
|
329
|
+
<li>Embed a video / Tweet / whatever by pasting the URL</li>
|
330
|
+
<li><p>Add a link like this:</p>
|
331
|
+
<pre>
|
332
|
+
[Check out my fave website](http://rapgenius.com)
|
333
|
+
</pre>
|
334
|
+
</li>
|
335
|
+
<li><p>Simple formatting:
|
336
|
+
<pre>
|
337
|
+
*This text is in italics*
|
338
|
+
**This text is bold**
|
339
|
+
</pre></p>
|
340
|
+
</li>
|
341
|
+
</ul>
|
342
|
+
|
343
|
+
<em><a href='#' onclick='$(this).closest("em").nextAll(".extended_explanation_instructions").toggle(); return false'>Click here for more formatting help (lists, blockquotes, etc)</a></em>
|
344
|
+
|
345
|
+
<div class="extended_explanation_instructions" style="display:none">
|
346
|
+
<ul>
|
347
|
+
<li><p>Links:</p>
|
348
|
+
<pre>
|
349
|
+
[Rap Genius](http://rapgenius.com) is my favorite site, [Kanye West's "Power"](http://rapgenius.com/kanye-west-power-lyrics) is my favorite song and [From whippin' the bacon rolls to outside whippin' the bacon Rolls](1256) is my favorite line
|
350
|
+
|
351
|
+
[[Kanye West]] auto-links his artist page
|
352
|
+
[[Scarface "My Block"]] auto-links to the song
|
353
|
+
</pre>
|
354
|
+
</li>
|
355
|
+
|
356
|
+
<li><p>Block quotes:</p>
|
357
|
+
|
358
|
+
<pre>In ["Juicy"](/The-notorious-big-juicy-lyrics), Biggie says:
|
359
|
+
> It was all a dream
|
360
|
+
I used to read Word Up magazine
|
361
|
+
Salt'n'Pepa and Heavy D up in the limousine</pre></li>
|
362
|
+
<li><p>Numbered lists:</p>
|
363
|
+
|
364
|
+
<pre>
|
365
|
+
The Best Rappers:
|
366
|
+
1. Cam'ron
|
367
|
+
2. Juelz Santana
|
368
|
+
3. Lil Wayne
|
369
|
+
</pre></li>
|
370
|
+
<li><p>Bulleted lists:</p>
|
371
|
+
|
372
|
+
<pre>
|
373
|
+
Words for gun:
|
374
|
+
- Gat
|
375
|
+
- Glock
|
376
|
+
- Nina
|
377
|
+
</pre></li>
|
378
|
+
<li><p>Text size:
|
379
|
+
<pre>
|
380
|
+
# Largest
|
381
|
+
## Large
|
382
|
+
### ...
|
383
|
+
</pre></p>
|
384
|
+
</li>
|
385
|
+
</ul>
|
386
|
+
<em class="explanation_only"><a href="http://rapgenius.com/Rap-genius-editors-rap-genius-for-beginners-lyrics" target="_blank">More ways to make your annotations better</a></em>
|
387
|
+
</div>
|
388
|
+
</div>
|
389
|
+
<button class="cancel_annotation" href='#' tabindex="5">cancel</button>
|
390
|
+
</div>
|
391
|
+
</div>
|
392
|
+
|
393
|
+
<div id="copy">
|
394
|
+
<span class="copyright">© 2013 Genius Media Group Inc.</span>
|
395
|
+
|
396
|
+
|
397
|
+
</div>
|
398
|
+
|
399
|
+
<div id="boring_links">
|
400
|
+
<a href="http://rapgenius.com/map" target="_blank">The Rap Map</a><span class="sep">|</span>
|
401
|
+
<a href="http://rock.rapgenius.com/map" target="_blank">The Rock Map</a><span class="sep">|</span>
|
402
|
+
<a href="/songs/all">All Songs</a><span class="sep">|</span>
|
403
|
+
<a href="/artists">All Artists</a><span class="sep">|</span>
|
404
|
+
<a href="/static/press" target="_blank">Press</a><span class="sep">|</span>
|
405
|
+
<a href="/static/terms" rel="nofollow" target="_blank">Terms of Use</a> <span class="sep">|</span>
|
406
|
+
<a href="/static/privacy_policy" rel="nofollow" target="_blank">Privacy Policy</a>
|
407
|
+
</div>
|
408
|
+
|
409
|
+
<div id="request_time" style="display:none">0.427</div>
|
410
|
+
|
411
|
+
</div>
|
412
|
+
</div>
|
413
|
+
|
414
|
+
<script type="text/javascript">
|
415
|
+
_atrk_opts = { atrk_acct:"w9qyh1acBa00aO", domain:"rapgenius.com",dynamic: true};
|
416
|
+
(function() {
|
417
|
+
var as = document.createElement('script');
|
418
|
+
as.type = 'text/javascript';
|
419
|
+
as.async = true;
|
420
|
+
as.src = "https://d31qbv1cthcecs.cloudfront.net/atrk.js";
|
421
|
+
var s = document.getElementsByTagName('script')[0];s.parentNode.insertBefore(as, s);
|
422
|
+
})();
|
423
|
+
</script>
|
424
|
+
<noscript>
|
425
|
+
<img src="https://d5nxst8fruw4z.cloudfront.net/atrk.gif?account=w9qyh1acBa00aO" style="display:none" height="1" width="1" alt="" />
|
426
|
+
</noscript>
|
427
|
+
|
428
|
+
<script type="text/javascript">if (!NREUMQ.f) { NREUMQ.f=function() {
|
429
|
+
NREUMQ.push(["load",new Date().getTime()]);
|
430
|
+
var e=document.createElement("script");
|
431
|
+
e.type="text/javascript";
|
432
|
+
e.src=(("http:"===document.location.protocol)?"http:":"https:") + "//" +
|
433
|
+
"js-agent.newrelic.com/nr-100.js";
|
434
|
+
document.body.appendChild(e);
|
435
|
+
if(NREUMQ.a)NREUMQ.a();
|
436
|
+
};
|
437
|
+
NREUMQ.a=window.onload;window.onload=NREUMQ.f;
|
438
|
+
};
|
439
|
+
NREUMQ.push(["nrfj","beacon-1.newrelic.com","25a615a0b6","309898","IFleFkcJCAhdERtXXA1ZRANBDwsKS0xHXl0U",10,47,new Date().getTime(),"","","","",""]);</script></body>
|
440
|
+
</html>
|