rapgenius 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
data/lib/rapgenius.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'rapgenius/version'
2
+ require 'rapgenius/scraper'
3
+ require 'rapgenius/annotation'
4
+ require 'rapgenius/song'
5
+ require 'rapgenius/exceptions'
@@ -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,4 @@
1
+ module RapGenius
2
+ class ScraperError < StandardError
3
+ end
4
+ 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
@@ -0,0 +1,3 @@
1
+ module RapGenius
2
+ VERSION = "0.0.1"
3
+ 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
@@ -0,0 +1,6 @@
1
+ require 'rapgenius'
2
+ require 'mocha/api'
3
+
4
+ RSpec.configure do |config|
5
+ config.mock_framework = :mocha
6
+ end
@@ -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&#39; get this rain like it&#39;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&#39; get this rain like it&#39;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&#39; get this rain like it&#39;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 &ldquo;Money&rdquo; <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">&copy; 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>