karaoke 0.0.1
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/Gemfile +6 -0
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +17 -0
- data/lib/karaoke.rb +16 -0
- data/lib/karaoke/search.rb +33 -0
- data/lib/karaoke/song.rb +23 -0
- data/lib/karaoke/song/azlyrics.rb +39 -0
- data/lib/karaoke/song/base.rb +56 -0
- data/lib/karaoke/song/directlyrics.rb +48 -0
- data/lib/karaoke/song/genius.rb +37 -0
- data/lib/karaoke/song/lyrics_mania.rb +37 -0
- data/lib/karaoke/song/lyricsfreak.rb +40 -0
- data/lib/karaoke/song/lyricsmode.rb +42 -0
- data/lib/karaoke/song/metro_lyrics.rb +41 -0
- data/lib/karaoke/version.rb +3 -0
- data/spec/spec_helper.rb +7 -0
- metadata +113 -0
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2014 Douwe Maan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# karaoke
|
2
|
+
|
3
|
+
A Ruby library for easily finding the lyrics to your favorite songs.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
```sh
|
8
|
+
gem install karaoke
|
9
|
+
```
|
10
|
+
|
11
|
+
Or in your Gemfile:
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
gem "karaoke"
|
15
|
+
```
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
require "karaoke"
|
21
|
+
|
22
|
+
# To find the lyrics to a song, simply search for it:
|
23
|
+
song = Karaoke.search("Armin van Buuren - This Is What It Feels Like")
|
24
|
+
# Be as creative as you want, karaoke usually knows what you're looking for:
|
25
|
+
song = Karaoke.search("This Is What It Feels Like - Armin van Buuren")
|
26
|
+
song = Karaoke.search("This Is What It Feels Like by Armin van Buuren")
|
27
|
+
song = Karaoke.search("Song by Armin van Buuren with vocals by Trevor Guthrie")
|
28
|
+
|
29
|
+
# This will return a Song object containing the following information:
|
30
|
+
song.artist # => "Armin van Buuren"
|
31
|
+
song.title # => "This Is What It Feels Like"
|
32
|
+
song.lyrics # => "Nobody here knocking at my door\n" and so on.
|
33
|
+
|
34
|
+
# If you're only interested in the lyrics, save a couple of keystrokes:
|
35
|
+
lyrics = Karaoke.lyrics("Armin van Buuren - This Is What It Feels Like")
|
36
|
+
# => "Nobody here knocking at my door\n" and so on.
|
37
|
+
|
38
|
+
# Behind the scenes, karaoke searches Google to find results on any of these sites:
|
39
|
+
# (Rap)Genius, MetroLyrics, Lyricsfreak, AZLyrics, DirectLyrics and LyricsMania
|
40
|
+
# Next, karaoke reads the lyrics from the highest ranked Google search result.
|
41
|
+
|
42
|
+
# If, for whatever reason, you want access to all of the found lyrics
|
43
|
+
# instead of just the highest ranked one, use `Karaoke::Search` directly:
|
44
|
+
Karaoke::Search.new("Armin van Buuren - This Is What It Feels Like").results
|
45
|
+
# => [
|
46
|
+
# #<Karaoke::Song::Azlyrics:0x007fef3a080b98>,
|
47
|
+
# #<Karaoke::Song::MetroLyrics:0x007fef3c01c9c0>,
|
48
|
+
# #<Karaoke::Song::Genius:0x007fef3a0cf900>,
|
49
|
+
# #<Karaoke::Song::LyricsMania:0x007fef3a0d1a98>
|
50
|
+
# ]
|
51
|
+
```
|
52
|
+
|
53
|
+
## Examples
|
54
|
+
Check out the [`examples/`](examples) folder for an example that I actually use myself.
|
55
|
+
|
56
|
+
## License
|
57
|
+
Copyright (c) 2014 Douwe Maan
|
58
|
+
|
59
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
60
|
+
a copy of this software and associated documentation files (the
|
61
|
+
"Software"), to deal in the Software without restriction, including
|
62
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
63
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
64
|
+
permit persons to whom the Software is furnished to do so, subject to
|
65
|
+
the following conditions:
|
66
|
+
|
67
|
+
The above copyright notice and this permission notice shall be
|
68
|
+
included in all copies or substantial portions of the Software.
|
69
|
+
|
70
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
71
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
72
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
73
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
74
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
75
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
76
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
|
3
|
+
spec = Gem::Specification.load("karaoke.gemspec")
|
4
|
+
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task default: :spec
|
8
|
+
|
9
|
+
desc "Build the .gem file"
|
10
|
+
task :build do
|
11
|
+
system "gem build #{spec.name}.gemspec"
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Push the .gem file to rubygems.org"
|
15
|
+
task release: :build do
|
16
|
+
system "gem push #{spec.name}-#{spec.version}.gem"
|
17
|
+
end
|
data/lib/karaoke.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require "google-search"
|
2
|
+
|
3
|
+
require "karaoke/song"
|
4
|
+
|
5
|
+
module Karaoke
|
6
|
+
class Search
|
7
|
+
attr_reader :query
|
8
|
+
|
9
|
+
def initialize(query)
|
10
|
+
@query = query
|
11
|
+
end
|
12
|
+
|
13
|
+
def search_query
|
14
|
+
"#{self.query} lyrics"
|
15
|
+
end
|
16
|
+
|
17
|
+
def results
|
18
|
+
@results ||= begin
|
19
|
+
song_results = []
|
20
|
+
|
21
|
+
search_results = Google::Search::Web.new(query: search_query)
|
22
|
+
search_results.each do |result|
|
23
|
+
klass = Song.song_type_for(result.uri)
|
24
|
+
next unless klass
|
25
|
+
|
26
|
+
song_results << klass.new(result.uri)
|
27
|
+
end
|
28
|
+
|
29
|
+
song_results
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/karaoke/song.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module Karaoke
|
2
|
+
module Song
|
3
|
+
class << self
|
4
|
+
@@services = []
|
5
|
+
|
6
|
+
def register_song_type(song_type)
|
7
|
+
@@services |= [song_type]
|
8
|
+
end
|
9
|
+
|
10
|
+
def song_type_for(lyrics_uri)
|
11
|
+
@@services.find { |song_type| song_type.matches?(lyrics_uri) }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require "karaoke/song/genius"
|
18
|
+
require "karaoke/song/metro_lyrics"
|
19
|
+
require "karaoke/song/lyricsfreak"
|
20
|
+
# require "karaoke/song/lyricsmode"
|
21
|
+
require "karaoke/song/azlyrics"
|
22
|
+
require "karaoke/song/directlyrics"
|
23
|
+
require "karaoke/song/lyrics_mania"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class Azlyrics < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
URI.parse(lyrics_url).host.end_with?("azlyrics.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
return @artist if defined?(@artist)
|
12
|
+
|
13
|
+
@artist = data.match(/ArtistName = "([^"]+)";/)[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
return @title if defined?(@title)
|
18
|
+
|
19
|
+
@title = data.match(/SongName = "([^"]+)";/)[1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def lyrics
|
23
|
+
return @lyrics if defined?(@lyrics)
|
24
|
+
|
25
|
+
el = document.css("div[style='margin-left:10px;margin-right:10px;']").first
|
26
|
+
return @lyrics = nil unless el
|
27
|
+
|
28
|
+
el.css("i").each { |i_el| i_el.replace(i_el.inner_html) }
|
29
|
+
|
30
|
+
lyrics = clean_html(el.inner_html)
|
31
|
+
lyrics.gsub!("<!-- start of lyrics -->", "")
|
32
|
+
lyrics.gsub!("<!-- end of lyrics -->", "")
|
33
|
+
@lyrics = lyrics
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
register_song_type Azlyrics
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
require "nokogiri"
|
4
|
+
|
5
|
+
module Karaoke
|
6
|
+
module Song
|
7
|
+
class Base
|
8
|
+
attr_reader :lyrics_url
|
9
|
+
|
10
|
+
def initialize(lyrics_url)
|
11
|
+
@lyrics_url = lyrics_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def artist
|
15
|
+
raise NotImplementedError.new("The Song::Base subclass needs to override the #artist method.")
|
16
|
+
end
|
17
|
+
|
18
|
+
def title
|
19
|
+
raise NotImplementedError.new("The Song::Base subclass needs to override the #title method.")
|
20
|
+
end
|
21
|
+
|
22
|
+
def lyrics
|
23
|
+
raise NotImplementedError.new("The Song::Base subclass needs to override the #lyrics method.")
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def data
|
28
|
+
@data ||= begin
|
29
|
+
redirects = 0
|
30
|
+
begin
|
31
|
+
raise "Too many redirects" if redirects == 5
|
32
|
+
|
33
|
+
uri = URI.parse(@lyrics_url)
|
34
|
+
connection = Net::HTTP.new(uri.host, uri.port)
|
35
|
+
connection.use_ssl = uri.is_a?(URI::HTTPS)
|
36
|
+
|
37
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
38
|
+
response = connection.request(request)
|
39
|
+
|
40
|
+
redirects += 1
|
41
|
+
end while response.is_a?(Net::HTTPRedirection) && @lyrics_url = response["location"]
|
42
|
+
|
43
|
+
response.body
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def document
|
48
|
+
@document ||= Nokogiri::HTML::Document.parse(data)
|
49
|
+
end
|
50
|
+
|
51
|
+
def clean_html(html)
|
52
|
+
html.gsub(/[\t\n\r]/, "").gsub("<br>", "\n")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class Directlyrics < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
URI.parse(lyrics_url).host.end_with?("directlyrics.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
return @artist if defined?(@artist)
|
12
|
+
|
13
|
+
el = document.css(".breadcrumb a[href$='-artist.html']").first ||
|
14
|
+
document.css("#hd-bar a[href$='-artist.html']").first
|
15
|
+
|
16
|
+
return @artist = nil unless el
|
17
|
+
|
18
|
+
@artist = el.text
|
19
|
+
end
|
20
|
+
|
21
|
+
def title
|
22
|
+
return @title if defined?(@title)
|
23
|
+
|
24
|
+
el = document.css(".hd h1").first || document.css("#hd h1").first
|
25
|
+
return @title = nil unless el
|
26
|
+
|
27
|
+
@title = el.text.match("^[^-]+- (.+?) lyrics$")[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def lyrics
|
31
|
+
return @lyrics if defined?(@lyrics)
|
32
|
+
|
33
|
+
el = document.css(".lyrics p").first || begin
|
34
|
+
lyrics_class = data.match(/\$\('\.([a-z0-9]+)'\)\.addClass\('lyrics'\);/)[1]
|
35
|
+
document.css("[class='#{lyrics_class}'] p").first
|
36
|
+
end
|
37
|
+
|
38
|
+
return @lyrics = nil unless el
|
39
|
+
|
40
|
+
el.css("ins").remove
|
41
|
+
|
42
|
+
@lyrics = clean_html(el.inner_html)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
register_song_type Directlyrics
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class Genius < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
URI.parse(lyrics_url).host.end_with?("genius.com") # Matches new *.genius.com URLs as well as rapgenius.com.
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
@artist ||= tracking_data["Primary Artist"] || tracking_data["Primary Arist"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def title
|
15
|
+
@title ||= tracking_data["Title"]
|
16
|
+
end
|
17
|
+
|
18
|
+
def lyrics
|
19
|
+
return @lyrics if defined?(@lyrics)
|
20
|
+
|
21
|
+
el = document.css(".lyrics p").first
|
22
|
+
return @lyrics = nil unless el
|
23
|
+
|
24
|
+
el.css("a").each { |a_el| a_el.replace(a_el.inner_html) }
|
25
|
+
|
26
|
+
@lyrics = clean_html(el.inner_html)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def tracking_data
|
31
|
+
@tracking_data ||= JSON.parse(data.match("var TRACKING_DATA = (\{.+?\})")[1])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
register_song_type Genius
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class LyricsMania < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
URI.parse(lyrics_url).host.end_with?("lyricsmania.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
return @artist if defined?(@artist)
|
12
|
+
|
13
|
+
@artist = data.match(/cf_page_artist = "([^"]+)";/)[1]
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
return @title if defined?(@title)
|
18
|
+
|
19
|
+
@title = data.match(/cf_page_song = "([^"]+)";/)[1]
|
20
|
+
end
|
21
|
+
|
22
|
+
def lyrics
|
23
|
+
return @lyrics if defined?(@lyrics)
|
24
|
+
|
25
|
+
el = document.css(".lyrics-body").first
|
26
|
+
return @lyrics = nil unless el
|
27
|
+
|
28
|
+
el.css("div").remove
|
29
|
+
el.css("strong").remove
|
30
|
+
|
31
|
+
@lyrics = clean_html(el.inner_html)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
register_song_type LyricsMania
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class Lyricsfreak < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
URI.parse(lyrics_url).host.end_with?("lyricsfreak.com")
|
8
|
+
end
|
9
|
+
|
10
|
+
def artist
|
11
|
+
return @artist if defined?(@artist)
|
12
|
+
|
13
|
+
el = document.css(%Q{a[data-tracking='\["Meta","Lyrics","ArtistName"\]']}).first
|
14
|
+
return @artist = nil unless el
|
15
|
+
|
16
|
+
@artist = el.text
|
17
|
+
end
|
18
|
+
|
19
|
+
def title
|
20
|
+
return @title if defined?(@title)
|
21
|
+
|
22
|
+
el = document.css(".song-info-panel h1").first
|
23
|
+
return @title = nil unless el
|
24
|
+
|
25
|
+
@title = el.text.match("^(.+?) Lyrics$")[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
def lyrics
|
29
|
+
return @lyrics if defined?(@lyrics)
|
30
|
+
|
31
|
+
el = document.css("#content_h").first
|
32
|
+
return @lyrics = nil unless el
|
33
|
+
|
34
|
+
@lyrics = clean_html(el.inner_html)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
register_song_type Lyricsfreak
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
# Doesn't work, because Lyricsmode blocks access from bots with 403 Forbidden.
|
4
|
+
|
5
|
+
module Karaoke
|
6
|
+
module Song
|
7
|
+
class Lyricsmode < Base
|
8
|
+
def self.matches?(lyrics_url)
|
9
|
+
URI.parse(lyrics_url).host.end_with?("lyricsmode.com")
|
10
|
+
end
|
11
|
+
|
12
|
+
def artist
|
13
|
+
return @artist if defined?(@artist)
|
14
|
+
|
15
|
+
el = document.css(%Q{a[data-tracking='\["Meta","Lyrics","ArtistName"\]']}).first
|
16
|
+
return @artist = nil unless el
|
17
|
+
|
18
|
+
@artist = el.text
|
19
|
+
end
|
20
|
+
|
21
|
+
def title
|
22
|
+
return @title if defined?(@title)
|
23
|
+
|
24
|
+
el = document.css("h1.song_name").first
|
25
|
+
return @title = nil unless el
|
26
|
+
|
27
|
+
@title = el.text.trim.match("^(.+?) Lyrics$")[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
def lyrics
|
31
|
+
return @lyrics if defined?(@lyrics)
|
32
|
+
|
33
|
+
el = document.css(".meaning_inside_frame").first
|
34
|
+
return @lyrics = nil unless el
|
35
|
+
|
36
|
+
@lyrics = clean_html(el.inner_html)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
register_song_type Lyricsmode
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "karaoke/song/base"
|
2
|
+
|
3
|
+
module Karaoke
|
4
|
+
module Song
|
5
|
+
class MetroLyrics < Base
|
6
|
+
def self.matches?(lyrics_url)
|
7
|
+
uri = URI.parse(lyrics_url)
|
8
|
+
|
9
|
+
uri.host.end_with?("metrolyrics.com") && !uri.path.end_with?("-lyrics.html")
|
10
|
+
end
|
11
|
+
|
12
|
+
def artist
|
13
|
+
@artist ||= tracking_data["musicArtistName"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def title
|
17
|
+
@title ||= tracking_data["musicSongTitle"]
|
18
|
+
end
|
19
|
+
|
20
|
+
def lyrics
|
21
|
+
return @lyrics if defined?(@lyrics)
|
22
|
+
|
23
|
+
el = document.css("#lyrics-body-text").first
|
24
|
+
return @lyrics = nil unless el
|
25
|
+
|
26
|
+
lyrics = clean_html(el.inner_html)
|
27
|
+
lyrics.gsub!("</p><p class=\"verse\">", "\n\n")
|
28
|
+
lyrics.gsub!("<p class=\"verse\">", "")
|
29
|
+
lyrics.gsub!("</p>", "")
|
30
|
+
@lyrics = lyrics
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
def tracking_data
|
35
|
+
@tracking_data ||= JSON.parse(data.match("var utag_data=(\{.+?\})")[1])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
register_song_type MetroLyrics
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: karaoke
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Douwe Maan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-09-13 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: nokogiri
|
16
|
+
requirement: &70358367183500 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70358367183500
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: google-search
|
27
|
+
requirement: &70358367183080 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70358367183080
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70358367182660 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70358367182660
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70358367182060 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70358367182060
|
58
|
+
description: A Ruby library for easily finding the lyrics to your favorite songs
|
59
|
+
email: douwe@selenight.nl
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- lib/karaoke/search.rb
|
65
|
+
- lib/karaoke/song/azlyrics.rb
|
66
|
+
- lib/karaoke/song/base.rb
|
67
|
+
- lib/karaoke/song/directlyrics.rb
|
68
|
+
- lib/karaoke/song/genius.rb
|
69
|
+
- lib/karaoke/song/lyrics_mania.rb
|
70
|
+
- lib/karaoke/song/lyricsfreak.rb
|
71
|
+
- lib/karaoke/song/lyricsmode.rb
|
72
|
+
- lib/karaoke/song/metro_lyrics.rb
|
73
|
+
- lib/karaoke/song.rb
|
74
|
+
- lib/karaoke/version.rb
|
75
|
+
- lib/karaoke.rb
|
76
|
+
- LICENSE
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- Gemfile
|
80
|
+
- spec/spec_helper.rb
|
81
|
+
homepage: https://github.com/DouweM/karaoke
|
82
|
+
licenses:
|
83
|
+
- MIT
|
84
|
+
post_install_message:
|
85
|
+
rdoc_options: []
|
86
|
+
require_paths:
|
87
|
+
- lib
|
88
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
hash: 1283531912695341570
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
segments:
|
104
|
+
- 0
|
105
|
+
hash: 1283531912695341570
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 1.8.6
|
109
|
+
signing_key:
|
110
|
+
specification_version: 3
|
111
|
+
summary: Find lyrics to your favorite songs
|
112
|
+
test_files:
|
113
|
+
- spec/spec_helper.rb
|