mp3lyrics 0.1.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/LICENSE +21 -0
- data/README.md +86 -0
- data/bin/mp3lyrics +4 -0
- data/lib/mp3lyrics.rb +112 -0
- data/lib/wiki/azlyrics.rb +25 -0
- data/lib/wiki/genius.rb +21 -0
- data/lib/wiki/lyricwiki.rb +26 -0
- data/lib/wiki/metrolyrics.rb +30 -0
- data/lib/wiki/wiki.rb +37 -0
- metadata +53 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 653d2e2af1835374a3c2d0487ab791b307dcb8c2cc0d5cacd5206ff1e4cacd9c
|
|
4
|
+
data.tar.gz: 76091b679f8465982f3bb83df1a418d94967161f93b5fcf6603db4fdc9601b72
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 610dc8c9d0a03e04c4357bf1dd541f2eddd2a684411bc2f7f07af21ec5d25d309ed673be0d650c769a685e5e306a0e3773a11d447ad23ec641f3e73ae7d46497
|
|
7
|
+
data.tar.gz: 9367bb514a4cc5997619345c3527b7d6dcbfe56484d53a0a20b9a489d84b4ef571249a949656fdab1f2f825612af34e06ee8ff69c4362cef70fa80e828788fe9
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Tim Brust
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# MP3Lyrics
|
|
2
|
+
[](https://github.com/timbru31/mp3lyrics/actions?query=workflow%3ARuby)
|
|
3
|
+
|
|
4
|
+
[](https://codeclimate.com/github/timbru31/mp3lyrics/coverage)
|
|
5
|
+

|
|
6
|
+
[](https://snyk.io/test/github/timbru31/mp3lyrics)
|
|
7
|
+
[](https://dependabot.com)
|
|
8
|
+
|
|
9
|
+
[](LICENSE.md)
|
|
10
|
+
|
|
11
|
+
### Still in Alpha, ugly and WIP :)
|
|
12
|
+
|
|
13
|
+
## Info
|
|
14
|
+
|
|
15
|
+
MP3Lyrics is a tool written in Ruby (currently only CLI) to download song lyrics from [LyricWiki](https://lyrics.fandom.com/wiki/LyricWikim), [MetroLyrics](http://metrolyrics.com), [AZLyrics](https://www.azlyrics.com) and [Genius](https://genius.com).
|
|
16
|
+
The lyrics are added to the mp3 file via the [USLT (Unsynchronised lyric/text transcription)](http://id3.org/id3v2.4.0-frames) tag (with the power of [ruby-mp3info](https://github.com/moumar/ruby-mp3info)).
|
|
17
|
+
|
|
18
|
+
## Motivation
|
|
19
|
+
|
|
20
|
+
#### Why Ruby?
|
|
21
|
+
|
|
22
|
+
Because I wanted to try another language than Java.
|
|
23
|
+
|
|
24
|
+
#### Why are you not using the LyricWiki API?
|
|
25
|
+
|
|
26
|
+
~~Although they have got a pretty neat [REST API](http://api.wikia.com/wiki/LyricWiki_API/REST) the lyrics can't be fully retrieved, most likely due to licensing issues.~~
|
|
27
|
+
They no longer offer an API since January 2016.
|
|
28
|
+
|
|
29
|
+
#### Why are you not using musiXmatch API?
|
|
30
|
+
|
|
31
|
+
Simply because they charge me (the developer) for retrieving the lyrics.
|
|
32
|
+
|
|
33
|
+
#### Why are you not using MetroLyrics API?
|
|
34
|
+
|
|
35
|
+
I don't have an API key (yet).
|
|
36
|
+
|
|
37
|
+
#### Why are you not using Genius API?
|
|
38
|
+
|
|
39
|
+
They do not offer fetching lyrics via the API (yet).
|
|
40
|
+
|
|
41
|
+
#### Why not iTunes Lyrics Adder, Lyrics for iTunes, iSongText, Get Lyrical, ...?
|
|
42
|
+
|
|
43
|
+
Either they were tied to iTunes and ugly DLL libraries, outdated/inactive, closed source or not cross platform. I'm mainly developing on my MacBook and my iTunes library is on my Windows system. I need something that works anywhere.
|
|
44
|
+
|
|
45
|
+
By dropping the need (and support) of iTunes running somewhere in the background, the tool is more lightweight.
|
|
46
|
+
|
|
47
|
+
## Dependencies
|
|
48
|
+
|
|
49
|
+
1. Bundler
|
|
50
|
+
2. Nokogiri for HTML parsing
|
|
51
|
+
3. mp3info as a MP3 library
|
|
52
|
+
4. require_all for easier requiring of the wiki_api folder
|
|
53
|
+
5. For testing purposes you should install rubocop, rake, minitest and optionally coverage reporters for CodeClimate
|
|
54
|
+
|
|
55
|
+
## Installation
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
```shell
|
|
59
|
+
gem install bundler
|
|
60
|
+
bundle install
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
```shell
|
|
66
|
+
./mp3lyrics.rb <dir> [-override true/false] [-use lyricwiki/genius/metrolyrics/azlyrics]
|
|
67
|
+
```
|
|
68
|
+
**dir** is the folder with your music, it's iterated recursively.
|
|
69
|
+
**override** is a boolean toggle to override existing lyrics (defaults to *false*).
|
|
70
|
+
**use** is a specific wiki to be used to download lyrics (all wikis are used by default).
|
|
71
|
+
|
|
72
|
+
## Tests
|
|
73
|
+
|
|
74
|
+
To execute the tests run
|
|
75
|
+
```shell
|
|
76
|
+
bundle exec rake
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Future plans // ToDo
|
|
80
|
+
|
|
81
|
+
- ~~Add support to other lyrics sites when 404 is returned from LyricWiki~~
|
|
82
|
+
- GUI for easier usage (maybe)
|
|
83
|
+
- Add test cases, see [#1](https://github.com/timbru31/mp3lyrics/issues/1)
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
Built by (c) Tim Brust and contributors. Released under the MIT license.
|
data/bin/mp3lyrics
ADDED
data/lib/mp3lyrics.rb
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'mp3info'
|
|
5
|
+
require 'require_all'
|
|
6
|
+
|
|
7
|
+
require_all './lib/wiki/'
|
|
8
|
+
|
|
9
|
+
def to_b(string)
|
|
10
|
+
!(string =~ /^(true|t|yes|y|1)$/i).nil?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def usage_message(override_options, use_options)
|
|
14
|
+
'Usage: ./mp3lyrics.rb <dir> [-override ' + override_options.join('/') + '] [-use ' + use_options.join('/') + ']'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
override_options = [true, false]
|
|
18
|
+
use_options = %w[lyricwiki genius metrolyrics azlyrics]
|
|
19
|
+
|
|
20
|
+
if ARGV.length.even? ||
|
|
21
|
+
ARGV.count('-override') > 1 ||
|
|
22
|
+
ARGV.count('-use') > 1
|
|
23
|
+
# If there is an even number of arguments (includes no arguments)
|
|
24
|
+
# or a flag has been used more than once
|
|
25
|
+
puts usage_message(override_options, use_options)
|
|
26
|
+
exit
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
dir = ARGV[0]
|
|
30
|
+
override = false
|
|
31
|
+
wiki_to_use = nil
|
|
32
|
+
|
|
33
|
+
i = 1
|
|
34
|
+
while i < ARGV.length
|
|
35
|
+
if ARGV[i] == '-override'
|
|
36
|
+
if override_options.include?(to_b(ARGV[i + 1]))
|
|
37
|
+
override = to_b(ARGV[i + 1])
|
|
38
|
+
else
|
|
39
|
+
# If the argument after the override flag is invalid
|
|
40
|
+
puts usage_message(override_options, use_options)
|
|
41
|
+
exit
|
|
42
|
+
end
|
|
43
|
+
elsif ARGV[i] == '-use'
|
|
44
|
+
if use_options.include?(ARGV[i + 1])
|
|
45
|
+
wiki_to_use = ARGV[i + 1]
|
|
46
|
+
else
|
|
47
|
+
# If the argument after the use flag is invalid
|
|
48
|
+
puts usage_message(override_options, use_options)
|
|
49
|
+
exit
|
|
50
|
+
end
|
|
51
|
+
else
|
|
52
|
+
# If the argument is not a valid flag
|
|
53
|
+
puts usage_message(override_options, use_options)
|
|
54
|
+
exit
|
|
55
|
+
end
|
|
56
|
+
i += 2
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
puts "
|
|
60
|
+
Welcome to
|
|
61
|
+
__ __ _____ ____ _ _
|
|
62
|
+
| \\\/ | __ \\___ \\| | (_)
|
|
63
|
+
| \\ \/ | |__) |__) | | _ _ _ __ _ ___ ___
|
|
64
|
+
| |\\/| | ___\/|__ <| | | | | | \'__| |\/ __\/ __|
|
|
65
|
+
| | | | | ___) | |___| |_| | | | | (__\\__ \\
|
|
66
|
+
|_| |_|_| |____\/|______\\__, |_| |_|\\___|___\/
|
|
67
|
+
__\/ |
|
|
68
|
+
|___\/
|
|
69
|
+
|
|
70
|
+
The current working directory is #{dir}
|
|
71
|
+
Overriding existing lyrics is #{override}"
|
|
72
|
+
puts "Specific wiki to use is #{wiki_to_use}" unless wiki_to_use.nil?
|
|
73
|
+
puts "\n\r"
|
|
74
|
+
|
|
75
|
+
wiki = Wiki.new
|
|
76
|
+
files = Dir.glob("#{dir}/**/*")
|
|
77
|
+
files.each do |file|
|
|
78
|
+
filename = File.extname(file)
|
|
79
|
+
next unless filename == '.mp3'
|
|
80
|
+
|
|
81
|
+
Mp3Info.open(file) do |mp3|
|
|
82
|
+
artist = mp3.tag.artist || mp3.tag1.artist || mp3.tag2.artist
|
|
83
|
+
title = mp3.tag.title || mp3.tag1.title || mp3.tag2.title
|
|
84
|
+
if artist.nil? || title.nil?
|
|
85
|
+
puts "Skipping song because title or artist is not set...\n\r"
|
|
86
|
+
next
|
|
87
|
+
end
|
|
88
|
+
puts "Fetching lyrics for #{artist} - #{title}"
|
|
89
|
+
# Either no tag is set, the mp3 file has no USLT tag or we override anyway
|
|
90
|
+
if !mp3.hastag2? || (mp3.hastag2? && !mp3.tag2.key?('USLT')) || override
|
|
91
|
+
lyrics = nil
|
|
92
|
+
lyrics = LyricWiki.new.get_lyrics(artist, title) if wiki_to_use.nil? || wiki_to_use == 'lyricwiki'
|
|
93
|
+
if wiki_to_use.nil? || wiki_to_use == 'genius'
|
|
94
|
+
lyrics = Genius.new.get_lyrics(artist, title) if lyrics.nil?
|
|
95
|
+
end
|
|
96
|
+
if wiki_to_use.nil? || wiki_to_use == 'metrolyrics'
|
|
97
|
+
lyrics = MetroLyrics.new.get_lyrics(artist, title) if lyrics.nil?
|
|
98
|
+
end
|
|
99
|
+
if wiki_to_use.nil? || wiki_to_use == 'azlyrics'
|
|
100
|
+
lyrics = AZLyrics.new.get_lyrics(artist, title) if lyrics.nil?
|
|
101
|
+
end
|
|
102
|
+
if lyrics.nil?
|
|
103
|
+
puts "Did not find any lyrics\n\r"
|
|
104
|
+
else
|
|
105
|
+
puts "Lyrics found\n\r"
|
|
106
|
+
wiki.set_lyrics(mp3, lyrics)
|
|
107
|
+
end
|
|
108
|
+
else
|
|
109
|
+
puts "Skipping #{artist} - #{title} because lyrics are already set"
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './wiki'
|
|
4
|
+
|
|
5
|
+
# Fetches the lyrics from AZLyrics.com
|
|
6
|
+
# Lyrics are stored accessed via the URL schema https://www.azlyrics.com/lyrics/ARTIST/SONG.html
|
|
7
|
+
# They are inside /html/body/div[2]/div/div[2]/div[5], sadly no class to access.
|
|
8
|
+
# There are hidden comments, which need to be removed.
|
|
9
|
+
class AZLyrics < Wiki
|
|
10
|
+
def get_lyrics(artist, song, limit = 10)
|
|
11
|
+
artist = artist.delete(' ').parameterize
|
|
12
|
+
song = song.delete(' ').parameterize
|
|
13
|
+
|
|
14
|
+
res = fetch("https://www.azlyrics.com/lyrics/#{artist.downcase}/#{song.downcase}.html", limit)
|
|
15
|
+
return nil unless res.is_a? Net::HTTPSuccess
|
|
16
|
+
|
|
17
|
+
lyrics = Nokogiri::HTML(res.body).xpath('/html/body/div[2]/div/div[2]/div[5]')
|
|
18
|
+
prettify_lyrics(lyrics)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prettify_lyrics(lyrics)
|
|
22
|
+
lyrics.search('.//comment()').remove
|
|
23
|
+
lyrics.inner_html.gsub('<br>', "\r").delete("\n").sub("\r\r", '')
|
|
24
|
+
end
|
|
25
|
+
end
|
data/lib/wiki/genius.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './wiki'
|
|
4
|
+
|
|
5
|
+
# Fetches the lyrics from Genius (formerly known as Rap Genius)
|
|
6
|
+
# Lyrics are stored accessed via the URL schema https://genius.com/ARTIST-SONG-lyrics
|
|
7
|
+
# They are inside //div[@class="lyrics"]//p[1], a lyrics element with the class "lyrics"
|
|
8
|
+
# It seems that this element was added by Angular.js
|
|
9
|
+
# Inside the p in the lyrics div they are in a tags
|
|
10
|
+
class Genius < Wiki
|
|
11
|
+
def get_lyrics(artist, song, limit = 10)
|
|
12
|
+
artist = artist.tr(' ', '-').parameterize
|
|
13
|
+
song = song.tr(' ', '-').parameterize
|
|
14
|
+
|
|
15
|
+
res = fetch("https://genius.com/#{artist.downcase}-#{song.downcase}-lyrics", limit)
|
|
16
|
+
return nil unless res.is_a? Net::HTTPSuccess
|
|
17
|
+
|
|
18
|
+
lyrics = Nokogiri::HTML(res.body).xpath('//div[@class="lyrics"]//p[1]')
|
|
19
|
+
lyrics.inner_html.gsub('<br>', "\r").gsub(%r{</?[^>]+>}, '').delete("\n")
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './wiki'
|
|
4
|
+
|
|
5
|
+
# Fetches the lyrics from LyricWiki
|
|
6
|
+
# Lyrics are stored accessed via the URL schema https://lyrics.fandom.com/wiki/ARTIST:SONG
|
|
7
|
+
# They are inside //div[@class="lyricbox"], a div with the class "lyricbox"
|
|
8
|
+
# There are hidden comments and script tags, that needs to be removed.
|
|
9
|
+
class LyricWiki < Wiki
|
|
10
|
+
def get_lyrics(artist, song, limit = 10)
|
|
11
|
+
artist = artist.tr(' ', '_')
|
|
12
|
+
song = song.tr(' ', '_')
|
|
13
|
+
|
|
14
|
+
res = fetch("https://lyrics.fandom.com/wiki/#{artist}:#{song}", limit)
|
|
15
|
+
return nil unless res.is_a? Net::HTTPSuccess
|
|
16
|
+
|
|
17
|
+
lyrics = Nokogiri::HTML(res.body).xpath('//div[@class="lyricbox"]')
|
|
18
|
+
prettify_lyrics(lyrics)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def prettify_lyrics(lyrics)
|
|
22
|
+
lyrics.search('//script').remove
|
|
23
|
+
lyrics.search('.//comment()').remove
|
|
24
|
+
lyrics.inner_html.gsub('<br>', "\r").gsub(%r{</?[^>]+>}, '').delete("\n")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative './wiki'
|
|
4
|
+
|
|
5
|
+
# Fetches the lyrics from MetroLyrics
|
|
6
|
+
# Lyrics are stored accessed via the URL schema https://www.metrolyrics.com/SONG-lyrics-ARTIST
|
|
7
|
+
# They are inside //*[@id="lyrics-body-text"]
|
|
8
|
+
# There are hidden comments and script tags, that needs to be removed.
|
|
9
|
+
class MetroLyrics < Wiki
|
|
10
|
+
def get_lyrics(artist, song, limit = 10)
|
|
11
|
+
artist = artist.tr(' ', '-').parameterize
|
|
12
|
+
song = song.tr(' ', '-').parameterize
|
|
13
|
+
|
|
14
|
+
res = fetch("https://www.metrolyrics.com/#{song.downcase}-lyrics-#{artist.downcase}.html", limit)
|
|
15
|
+
return nil unless res.is_a? Net::HTTPSuccess
|
|
16
|
+
|
|
17
|
+
lyrics = Nokogiri::HTML(res.body).xpath('//*[@id="lyrics-body-text"]')
|
|
18
|
+
lyrics.search('.driver-photos').remove
|
|
19
|
+
lyrics.search('.driver-related').remove
|
|
20
|
+
prettify_lyrics(lyrics.inner_html)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def prettify_lyrics(lyrics)
|
|
24
|
+
lyrics = lyrics.gsub('<br>', "\r")
|
|
25
|
+
lyrics = lyrics.gsub("</p>\n<p class=\"verse\">", "\r")
|
|
26
|
+
lyrics = lyrics.gsub(%r{</?[^>]+>}, '')
|
|
27
|
+
lyrics = lyrics.delete("\t")
|
|
28
|
+
lyrics.delete("\n")
|
|
29
|
+
end
|
|
30
|
+
end
|
data/lib/wiki/wiki.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'active_support/inflector'
|
|
4
|
+
require 'net/http'
|
|
5
|
+
require 'nokogiri'
|
|
6
|
+
|
|
7
|
+
# Base class to fetch different lyrics sites
|
|
8
|
+
class Wiki
|
|
9
|
+
def fetch(uri_str, limit = 10)
|
|
10
|
+
raise ArgumentError, 'The wiki site is redirecting too much, aborting...' if limit.zero?
|
|
11
|
+
|
|
12
|
+
uri = prepare_url(uri_str)
|
|
13
|
+
response = Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
|
14
|
+
req = Net::HTTP::Get.new(uri.path)
|
|
15
|
+
begin
|
|
16
|
+
http.request(req)
|
|
17
|
+
rescue EOFError
|
|
18
|
+
fetch(uri_str, limit - 1)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
case response
|
|
22
|
+
when Net::HTTPRedirection
|
|
23
|
+
fetch(response['location'], limit - 1)
|
|
24
|
+
else
|
|
25
|
+
response
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def set_lyrics(mp3, lyrics)
|
|
30
|
+
mp3.tag2.USLT = lyrics
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def prepare_url(uri_str)
|
|
34
|
+
uri_str.gsub!('%EF%BB%BF', '') # fix BOM
|
|
35
|
+
URI.parse(uri_str)
|
|
36
|
+
end
|
|
37
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mp3lyrics
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Tim Brust
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2010-04-28 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: CLI for mp3 lyrics fetching. Uses ruby-mp3info and fetches different
|
|
14
|
+
lyric wikis
|
|
15
|
+
email: github@timbrust.de
|
|
16
|
+
executables:
|
|
17
|
+
- mp3lyrics
|
|
18
|
+
extensions: []
|
|
19
|
+
extra_rdoc_files: []
|
|
20
|
+
files:
|
|
21
|
+
- LICENSE
|
|
22
|
+
- README.md
|
|
23
|
+
- bin/mp3lyrics
|
|
24
|
+
- lib/mp3lyrics.rb
|
|
25
|
+
- lib/wiki/azlyrics.rb
|
|
26
|
+
- lib/wiki/genius.rb
|
|
27
|
+
- lib/wiki/lyricwiki.rb
|
|
28
|
+
- lib/wiki/metrolyrics.rb
|
|
29
|
+
- lib/wiki/wiki.rb
|
|
30
|
+
homepage: https://github.com/timbru31/
|
|
31
|
+
licenses:
|
|
32
|
+
- MIT
|
|
33
|
+
metadata: {}
|
|
34
|
+
post_install_message:
|
|
35
|
+
rdoc_options: []
|
|
36
|
+
require_paths:
|
|
37
|
+
- lib
|
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - ">="
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
48
|
+
requirements: []
|
|
49
|
+
rubygems_version: 3.0.6
|
|
50
|
+
signing_key:
|
|
51
|
+
specification_version: 4
|
|
52
|
+
summary: CLI for mp3 lyrics fetching
|
|
53
|
+
test_files: []
|