mp3lyrics 0.1.2 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6977220f3ee03ab44d150bb7e8ae2e56b8847186f5d2b764a48726516a629119
4
- data.tar.gz: 9509ff32bc484dd7787b7455c2307dc3f011ee077bc92060cd5d52be7ac3f8f3
3
+ metadata.gz: 331cb5ff0fa84f9be3d6c0a675b50864d50eb56174f267b783a1054117a2a9f2
4
+ data.tar.gz: f745bbffb2ce1bc05bfa9876296e16b65d6e16e9194c2e12a7f17e6f558e1dd7
5
5
  SHA512:
6
- metadata.gz: 403c3c6eb70255696bb2f042c692b34ef5a7e86a1aaf63b95bd34d567d382ae656929c6020f6b15c23c30694af1c09c5d97a9ce2f0ab1ffb4926d7aebf7c6222
7
- data.tar.gz: 06b5ff82066b8d73e0c88ab46dec6d5fe6d88e7fd22875463712c42735bd78c959915646ca921304b28a191d6a0e7e754990bac5d93ee09788cec01e91d9c472
6
+ metadata.gz: 0edbea1fe6ef0c41653729948908d664dd54deaa5b6dfda866b2227a9e8ca54af86a622d5c849d93190c914428c6f1bdede7f7fcbc52ad568034652f5dad4533
7
+ data.tar.gz: 50e9ca90379f70263016d6b8a6ef9525170db56e17e881fe6b9e8357d72f646af415eb02d3162afd79050f374782760b6ad46a90e79de02e12680040c2e14934
data/CHANGELOG.md CHANGED
@@ -1,9 +1,9 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- # 0.1.2 (2021-01-09)
6
-
7
- ## Bug Fixes
8
-
9
- - Improves parsing certain titles that contain characters such as `'` or have a `(feat. XYZ)` in their title
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ # 0.1.2 (2021-01-09)
6
+
7
+ ## Bug Fixes
8
+
9
+ - Improves parsing certain titles that contain characters such as `'` or have a `(feat. XYZ)` in their title
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2021 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.
1
+ MIT License
2
+
3
+ Copyright (c) 2021 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 CHANGED
@@ -1,96 +1,96 @@
1
- # MP3Lyrics
2
-
3
- [![Ruby](https://github.com/timbru31/mp3lyrics/workflows/Ruby/badge.svg)](https://github.com/timbru31/mp3lyrics/actions?query=workflow%3ARuby)
4
-
5
- [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/timbru31/mp3lyrics)](https://codeclimate.com/github/timbru31/mp3lyrics)
6
- [![Code Climate](https://img.shields.io/codeclimate/maintainability/timbru31/mp3lyrics)](https://codeclimate.com/github/timbru31/mp3lyrics)
7
- [![Known Vulnerabilities](https://snyk.io/test/github/timbru31/mp3lyrics/badge.svg)](https://snyk.io/test/github/timbru31/mp3lyrics)
8
- [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=timbru31/mp3lyrics)](https://dependabot.com)
9
-
10
- [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)
11
-
12
- ### Still in Alpha, ugly and WIP :)
13
-
14
- ## Info
15
-
16
- MP3Lyrics is a tool written in Ruby (currently only CLI) to download song lyrics from [MetroLyrics](https://www.metrolyrics.com), [AZLyrics](https://www.azlyrics.com) and [Genius](https://genius.com).
17
- The lyrics are added to the mp3 file via the [USLT (Unsynchronised lyric/text transcription)](https://id3.org/id3v2.4.0-frames) tag (with the power of [ruby-mp3info](https://github.com/moumar/ruby-mp3info)).
18
-
19
- ## Motivation
20
-
21
- #### Why Ruby?
22
-
23
- Because I wanted to try another language than Java.
24
-
25
- #### Why are you not using the LyricWiki API?
26
-
27
- ~~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.~~
28
- They no longer offer an API since January 2016. The site has since been shut down as of October 2020.
29
-
30
- #### Why are you not using musiXmatch API?
31
-
32
- Simply because they charge me (the developer) for retrieving the lyrics.
33
-
34
- #### Why are you not using MetroLyrics API?
35
-
36
- I don't have an API key (yet).
37
-
38
- #### Why are you not using Genius API?
39
-
40
- They do not offer fetching lyrics via the API (yet).
41
-
42
- #### Why not iTunes Lyrics Adder, Lyrics for iTunes, iSongText, Get Lyrical, ...?
43
-
44
- 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.
45
-
46
- By dropping the need (and support) of iTunes running somewhere in the background, the tool is more lightweight.
47
-
48
- ## Dependencies
49
-
50
- 1. Bundler
51
- 2. Nokogiri for HTML parsing
52
- 3. mp3info as a MP3 library
53
- 4. require_all for easier requiring of the wiki_api folder
54
- 5. For testing purposes you should install rubocop, rake, minitest and optionally coverage reporters for CodeClimate
55
-
56
- ## Installation
57
-
58
- ```shell
59
- gem install mp3lyrics
60
- ```
61
-
62
- ## Usage
63
-
64
- ```shell
65
- mp3lyrics <dir> [-override true/false] [-use genius/metrolyrics/azlyrics]
66
- ```
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
- ### Development usage
73
-
74
- The same options as above apply, but the binary has to be invoked from
75
-
76
- ```shell
77
- ./lib/mp3lyrics.rb
78
- ```
79
-
80
- ## Tests
81
-
82
- To execute the tests run
83
-
84
- ```shell
85
- bundle exec rake
86
- ```
87
-
88
- ## Future plans // ToDo
89
-
90
- - ~~Add support to other lyrics sites when 404 is returned from LyricWiki~~
91
- - GUI for easier usage (maybe)
92
- - Add test cases, see [#1](https://github.com/timbru31/mp3lyrics/issues/1)
93
-
94
- ---
95
-
96
- Built by (c) Tim Brust and contributors. Released under the MIT license.
1
+ # MP3Lyrics
2
+
3
+ [![Ruby](https://github.com/timbru31/mp3lyrics/workflows/Ruby/badge.svg)](https://github.com/timbru31/mp3lyrics/actions?query=workflow%3ARuby)
4
+
5
+ [![Code Climate coverage](https://img.shields.io/codeclimate/coverage/timbru31/mp3lyrics)](https://codeclimate.com/github/timbru31/mp3lyrics)
6
+ [![Code Climate](https://img.shields.io/codeclimate/maintainability/timbru31/mp3lyrics)](https://codeclimate.com/github/timbru31/mp3lyrics)
7
+ [![Known Vulnerabilities](https://snyk.io/test/github/timbru31/mp3lyrics/badge.svg)](https://snyk.io/test/github/timbru31/mp3lyrics)
8
+ [![Dependabot Status](https://api.dependabot.com/badges/status?host=github&repo=timbru31/mp3lyrics)](https://dependabot.com)
9
+
10
+ [![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)
11
+
12
+ ### Still in Alpha, ugly and WIP :)
13
+
14
+ ## Info
15
+
16
+ MP3Lyrics is a tool written in Ruby (currently only CLI) to download song lyrics from [AZLyrics](https://www.azlyrics.com) or [Genius](https://genius.com).
17
+ The lyrics are added to the mp3 file via the [USLT (Unsynchronised lyric/text transcription)](https://id3.org/id3v2.4.0-frames) tag (with the power of [ruby-mp3info](https://github.com/moumar/ruby-mp3info)).
18
+
19
+ ## Motivation
20
+
21
+ #### Why Ruby?
22
+
23
+ Because I wanted to try another language than Java.
24
+
25
+ #### Why are you not using the LyricWiki API?
26
+
27
+ ~~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.~~
28
+ They no longer offer an API since January 2016. The site has since been shut down as of October 2020.
29
+
30
+ #### Why are you not using musiXmatch API?
31
+
32
+ Simply because they charge me (the developer) for retrieving the lyrics.
33
+
34
+ #### Why are you not using MetroLyrics API?
35
+
36
+ The site has been shut down as of July 2021.
37
+
38
+ #### Why are you not using Genius API?
39
+
40
+ They do not offer fetching lyrics via the API (yet).
41
+
42
+ #### Why not iTunes Lyrics Adder, Lyrics for iTunes, iSongText, Get Lyrical, ...?
43
+
44
+ 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.
45
+
46
+ By dropping the need (and support) of iTunes running somewhere in the background, the tool is more lightweight.
47
+
48
+ ## Dependencies
49
+
50
+ 1. Bundler
51
+ 2. Nokogiri for HTML parsing
52
+ 3. mp3info as a MP3 library
53
+ 4. require_all for easier requiring of the wiki_api folder
54
+ 5. For testing purposes you should install rubocop, rake, minitest and optionally coverage reporters for CodeClimate
55
+
56
+ ## Installation
57
+
58
+ ```shell
59
+ gem install mp3lyrics
60
+ ```
61
+
62
+ ## Usage
63
+
64
+ ```shell
65
+ mp3lyrics <dir> [-override true/false] [-use genius/azlyrics]
66
+ ```
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
+ ### Development usage
73
+
74
+ The same options as above apply, but the binary has to be invoked from
75
+
76
+ ```shell
77
+ ./lib/mp3lyrics.rb
78
+ ```
79
+
80
+ ## Tests
81
+
82
+ To execute the tests run
83
+
84
+ ```shell
85
+ bundle exec rake
86
+ ```
87
+
88
+ ## Future plans // ToDo
89
+
90
+ - ~~Add support to other lyrics sites when 404 is returned from LyricWiki~~
91
+ - GUI for easier usage (maybe)
92
+ - Add test cases, see [#1](https://github.com/timbru31/mp3lyrics/issues/1)
93
+
94
+ ---
95
+
96
+ Built by (c) Tim Brust and contributors. Released under the MIT license.
data/bin/mp3lyrics CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- require 'mp3lyrics'
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'mp3lyrics'
data/lib/mp3lyrics.rb CHANGED
@@ -1,106 +1,105 @@
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[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
- case ARGV[i]
36
- when '-override'
37
- if override_options.include?(to_b(ARGV[i + 1]))
38
- override = to_b(ARGV[i + 1])
39
- else
40
- # If the argument after the override flag is invalid
41
- puts usage_message(override_options, use_options)
42
- exit
43
- end
44
- when '-use'
45
- if use_options.include?(ARGV[i + 1])
46
- wiki_to_use = ARGV[i + 1]
47
- else
48
- # If the argument after the use flag is invalid
49
- puts usage_message(override_options, use_options)
50
- exit
51
- end
52
- else
53
- # If the argument is not a valid flag
54
- puts usage_message(override_options, use_options)
55
- exit
56
- end
57
- i += 2
58
- end
59
-
60
- puts "
61
- Welcome to
62
- __ __ _____ ____ _ _
63
- | \\\/ | __ \\___ \\| | (_)
64
- | \\ \/ | |__) |__) | | _ _ _ __ _ ___ ___
65
- | |\\/| | ___\/|__ <| | | | | | \'__| |\/ __\/ __|
66
- | | | | | ___) | |___| |_| | | | | (__\\__ \\
67
- |_| |_|_| |____\/|______\\__, |_| |_|\\___|___\/
68
- __\/ |
69
- |___\/
70
-
71
- The current working directory is #{dir}
72
- Overriding existing lyrics is #{override}"
73
- puts "Specific wiki to use is #{wiki_to_use}" unless wiki_to_use.nil?
74
- puts "\n\r"
75
-
76
- wiki = Wiki.new
77
- files = Dir.glob("#{dir}/**/*")
78
- files.each do |file|
79
- filename = File.extname(file)
80
- next unless filename == '.mp3'
81
-
82
- Mp3Info.open(file) do |mp3|
83
- artist = mp3.tag.artist || mp3.tag1.artist || mp3.tag2.artist
84
- title = mp3.tag.title || mp3.tag1.title || mp3.tag2.title
85
- if artist.nil? || title.nil?
86
- puts "Skipping song because title or artist is not set...\n\r"
87
- next
88
- end
89
- puts "Fetching lyrics for #{artist} - #{title}"
90
- # Either no tag is set, the mp3 file has no USLT tag or we override anyway
91
- if !mp3.hastag2? || (mp3.hastag2? && !mp3.tag2.key?('USLT')) || override
92
- lyrics = nil
93
- lyrics = Genius.new.get_lyrics(artist, title) if wiki_to_use.nil? || wiki_to_use == 'genius'
94
- lyrics = MetroLyrics.new.get_lyrics(artist, title) if (wiki_to_use.nil? || wiki_to_use == 'metrolyrics') && lyrics.nil?
95
- lyrics = AZLyrics.new.get_lyrics(artist, title) if (wiki_to_use.nil? || wiki_to_use == 'azlyrics') && lyrics.nil?
96
- if lyrics.nil?
97
- puts "Did not find any lyrics\n\r"
98
- else
99
- puts "Lyrics found\n\r"
100
- wiki.set_lyrics(mp3, lyrics)
101
- end
102
- else
103
- puts "Skipping #{artist} - #{title} because lyrics are already set"
104
- end
105
- end
106
- end
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[genius 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
+ case ARGV[i]
36
+ when '-override'
37
+ if override_options.include?(to_b(ARGV[i + 1]))
38
+ override = to_b(ARGV[i + 1])
39
+ else
40
+ # If the argument after the override flag is invalid
41
+ puts usage_message(override_options, use_options)
42
+ exit
43
+ end
44
+ when '-use'
45
+ if use_options.include?(ARGV[i + 1])
46
+ wiki_to_use = ARGV[i + 1]
47
+ else
48
+ # If the argument after the use flag is invalid
49
+ puts usage_message(override_options, use_options)
50
+ exit
51
+ end
52
+ else
53
+ # If the argument is not a valid flag
54
+ puts usage_message(override_options, use_options)
55
+ exit
56
+ end
57
+ i += 2
58
+ end
59
+
60
+ puts "
61
+ Welcome to
62
+ __ __ _____ ____ _ _
63
+ | \\\/ | __ \\___ \\| | (_)
64
+ | \\ \/ | |__) |__) | | _ _ _ __ _ ___ ___
65
+ | |\\/| | ___\/|__ <| | | | | | \'__| |\/ __\/ __|
66
+ | | | | | ___) | |___| |_| | | | | (__\\__ \\
67
+ |_| |_|_| |____\/|______\\__, |_| |_|\\___|___\/
68
+ __\/ |
69
+ |___\/
70
+
71
+ The current working directory is #{dir}
72
+ Overriding existing lyrics is #{override}"
73
+ puts "Specific wiki to use is #{wiki_to_use}" unless wiki_to_use.nil?
74
+ puts "\n\r"
75
+
76
+ wiki = Wiki.new
77
+ files = Dir.glob("#{dir}/**/*")
78
+ files.each do |file|
79
+ filename = File.extname(file)
80
+ next unless filename == '.mp3'
81
+
82
+ Mp3Info.open(file) do |mp3|
83
+ artist = mp3.tag.artist || mp3.tag1.artist || mp3.tag2.artist
84
+ title = mp3.tag.title || mp3.tag1.title || mp3.tag2.title
85
+ if artist.nil? || title.nil?
86
+ puts "Skipping song because title or artist is not set...\n\r"
87
+ next
88
+ end
89
+ puts "Fetching lyrics for #{artist} - #{title}"
90
+ # Either no tag is set, the mp3 file has no USLT tag or we override anyway
91
+ if !mp3.hastag2? || (mp3.hastag2? && !mp3.tag2.key?('USLT')) || override
92
+ lyrics = nil
93
+ lyrics = Genius.new.get_lyrics(artist, title) if wiki_to_use.nil? || wiki_to_use == 'genius'
94
+ lyrics = AZLyrics.new.get_lyrics(artist, title) if (wiki_to_use.nil? || wiki_to_use == 'azlyrics') && lyrics.nil?
95
+ if lyrics.nil?
96
+ puts "Did not find any lyrics\n\r"
97
+ else
98
+ puts "Lyrics found\n\r"
99
+ wiki.set_lyrics(mp3, lyrics)
100
+ end
101
+ else
102
+ puts "Skipping #{artist} - #{title} because lyrics are already set"
103
+ end
104
+ end
105
+ end
data/lib/wiki/azlyrics.rb CHANGED
@@ -1,25 +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(' ').gsub(/('|`|´|’|\?|\(|\))/, '').parameterize
12
- song = song.delete(' ').gsub(/('|`|´|’|\?|\(|\))/, '').gsub(/(?:\(?feat.*\)?)/, '').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
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(' ').gsub(/('|`|´|’|\?|\(|\))/, '').parameterize
12
+ song = song.delete(' ').gsub(/('|`|´|’|\?|\(|\))/, '').gsub(/(?:\(?feat.*\)?)/, '').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 CHANGED
@@ -1,19 +1,19 @@
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[starts-with(@class, "Lyrics__Container")]
8
- class Genius < Wiki
9
- def get_lyrics(artist, song, limit = 10)
10
- artist = artist.tr(' ', '-').gsub(/('|`|´|’)/, '').gsub(/(?:\(?feat.*\)?)/, '').parameterize
11
- song = song.tr(' ', '-').gsub(/('|`|´|’)/, '').gsub(/(?:\(?feat.*\)?)/, '').parameterize
12
-
13
- res = fetch("https://genius.com/#{artist.downcase}-#{song.downcase}-lyrics", limit)
14
- return nil unless res.is_a? Net::HTTPSuccess
15
-
16
- lyrics = Nokogiri::HTML(res.body).xpath("//div[starts-with(@class, 'lyrics') or starts-with(@class, 'Lyrics__Container')]")
17
- lyrics.inner_html.gsub('<br>', "\r").gsub(%r{</?[^>]+>}, '').delete("\n").strip
18
- end
19
- end
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[starts-with(@class, "Lyrics__Container")]
8
+ class Genius < Wiki
9
+ def get_lyrics(artist, song, limit = 10)
10
+ artist = artist.tr(' ', '-').gsub(/('|`|´|’)/, '').gsub(/(?:\(?feat.*\)?)/, '').parameterize
11
+ song = song.tr(' ', '-').gsub(/('|`|´|’)/, '').gsub(/(?:\(?feat.*\)?)/, '').parameterize
12
+
13
+ res = fetch("https://genius.com/#{artist.downcase}-#{song.downcase}-lyrics", limit)
14
+ return nil unless res.is_a? Net::HTTPSuccess
15
+
16
+ lyrics = Nokogiri::HTML(res.body).xpath("//div[starts-with(@class, 'lyrics') or starts-with(@class, 'Lyrics__Container')]")
17
+ lyrics.inner_html.gsub('<br>', "\r").gsub(%r{</?[^>]+>}, '').delete("\n").strip
18
+ end
19
+ end
data/lib/wiki/wiki.rb CHANGED
@@ -1,37 +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
- bom_fixed_uri = uri_str.gsub('%EF%BB%BF', '') # fix BOM
35
- URI.parse(bom_fixed_uri)
36
- end
37
- end
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
+ bom_fixed_uri = uri_str.gsub('%EF%BB%BF', '') # fix BOM
35
+ URI.parse(bom_fixed_uri)
36
+ end
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mp3lyrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Brust
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-01-09 00:00:00.000000000 Z
11
+ date: 2021-08-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: CLI for mp3 lyrics fetching. Uses ruby-mp3info and fetches different
14
14
  lyric wikis
@@ -25,7 +25,6 @@ files:
25
25
  - lib/mp3lyrics.rb
26
26
  - lib/wiki/azlyrics.rb
27
27
  - lib/wiki/genius.rb
28
- - lib/wiki/metrolyrics.rb
29
28
  - lib/wiki/wiki.rb
30
29
  homepage: https://github.com/timbru31/
31
30
  licenses:
@@ -34,7 +33,7 @@ metadata:
34
33
  bug_tracker_uri: https://github.com/timbru31/mp3lyrics/issues?q=is%3Aopen+is%3Aissue
35
34
  changelog_uri: https://github.com/timbru31/mp3lyrics/blob/master/CHANGELOG.md
36
35
  source_code_uri: https://github.com/timbru31/mp3lyrics/
37
- post_install_message:
36
+ post_install_message:
38
37
  rdoc_options: []
39
38
  require_paths:
40
39
  - lib
@@ -42,15 +41,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
41
  requirements:
43
42
  - - ">="
44
43
  - !ruby/object:Gem::Version
45
- version: 2.5.0
44
+ version: 2.6.0
46
45
  required_rubygems_version: !ruby/object:Gem::Requirement
47
46
  requirements:
48
47
  - - ">="
49
48
  - !ruby/object:Gem::Version
50
49
  version: '0'
51
50
  requirements: []
52
- rubygems_version: 3.1.2
53
- signing_key:
51
+ rubygems_version: 3.0.1
52
+ signing_key:
54
53
  specification_version: 4
55
54
  summary: CLI for mp3 lyrics fetching
56
55
  test_files: []
@@ -1,30 +0,0 @@
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(' ', '-').gsub(/(?:\(?feat.*\)?)/, '').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