lyrics 0.0.2
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/.document +5 -0
- data/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.rdoc +17 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/bin/lyrics +66 -0
- data/lib/lyrics.rb +4 -0
- data/lib/lyrics/cli/application.rb +99 -0
- data/lib/lyrics/cli/optionsparser.rb +228 -0
- data/lib/lyrics/cli/pluginadapter.rb +56 -0
- data/lib/lyrics/cli/plugins.rb +79 -0
- data/lib/lyrics/cli/wikipluginadapter.rb +139 -0
- data/lib/lyrics/i18n/README +1 -0
- data/lib/lyrics/i18n/en.rb +181 -0
- data/lib/lyrics/i18n/es.rb +181 -0
- data/lib/lyrics/i18n/i18n.rb +126 -0
- data/lib/lyrics/i18n/sk.rb +174 -0
- data/lib/lyrics/itrans/COPYRIGHT +31 -0
- data/lib/lyrics/itrans/itrans +0 -0
- data/lib/lyrics/itrans/itrans.txt +8 -0
- data/lib/lyrics/itrans/lyric.txt +23 -0
- data/lib/lyrics/itrans/udvng.ifm +206 -0
- data/lib/lyrics/lyrics.rb +567 -0
- data/lib/lyrics/lyrics_AZLyrics.rb +113 -0
- data/lib/lyrics/lyrics_DarkLyrics.rb +124 -0
- data/lib/lyrics/lyrics_Giitaayan.rb +124 -0
- data/lib/lyrics/lyrics_Jamendo.rb +166 -0
- data/lib/lyrics/lyrics_LeosLyrics.rb +142 -0
- data/lib/lyrics/lyrics_LoudSongs.rb +135 -0
- data/lib/lyrics/lyrics_LyricWiki.rb +328 -0
- data/lib/lyrics/lyrics_LyricsDownload.rb +118 -0
- data/lib/lyrics/lyrics_LyricsMania.rb +141 -0
- data/lib/lyrics/lyrics_Lyriki.rb +286 -0
- data/lib/lyrics/lyrics_SeekLyrics.rb +108 -0
- data/lib/lyrics/lyrics_Sing365.rb +103 -0
- data/lib/lyrics/lyrics_TerraLetras.rb +126 -0
- data/lib/lyrics/mediawikilyrics.rb +1417 -0
- data/lib/lyrics/utils/formdata.rb +56 -0
- data/lib/lyrics/utils/htmlentities.rb +291 -0
- data/lib/lyrics/utils/http.rb +198 -0
- data/lib/lyrics/utils/itrans.rb +160 -0
- data/lib/lyrics/utils/logger.rb +123 -0
- data/lib/lyrics/utils/strings.rb +378 -0
- data/lib/lyrics/utils/xmlhash.rb +111 -0
- data/lyrics.gemspec +98 -0
- data/spec/lyrics_spec.rb +7 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +9 -0
- metadata +137 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Copyright (C) 2006-2008 by Sergio Pistone
|
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the
|
|
16
|
+
# Free Software Foundation, Inc.,
|
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18
|
+
|
|
19
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
|
20
|
+
|
|
21
|
+
require "utils/strings"
|
|
22
|
+
require "utils/htmlentities"
|
|
23
|
+
require "lyrics"
|
|
24
|
+
|
|
25
|
+
require "cgi"
|
|
26
|
+
|
|
27
|
+
class LeosLyrics < Lyrics
|
|
28
|
+
|
|
29
|
+
def LeosLyrics.site_host()
|
|
30
|
+
return "www.leoslyrics.com"
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def LeosLyrics.site_name()
|
|
34
|
+
return "Leos Lyrics"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def LeosLyrics.lyrics_test_data()
|
|
38
|
+
return [
|
|
39
|
+
Request.new( "Cat Power", "Good Woman", "You Are Free" ),
|
|
40
|
+
Request.new( "Blur", "No Distance Left To Run", "13" ),
|
|
41
|
+
Request.new( "Massive Attack", "Angel", "Mezzanine" ),
|
|
42
|
+
Request.new( "Nirvana", "All Apologies", "In Utero" ),
|
|
43
|
+
# Request.new( "System Of A Down", "Chop Suey", "Toxicity" ),
|
|
44
|
+
# Request.new( "A Perfect Circle", "The Noose", "Thirteen Step" ),
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def LeosLyrics.build_song_add_url( request )
|
|
49
|
+
add_url = "http://#{site_host()}/submit.php?artist=#{CGI.escape( request.artist )}&song=#{CGI.escape( request.title )}"
|
|
50
|
+
add_url << "&album=#{CGI.escape( request.album )}" if request.album
|
|
51
|
+
return add_url
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def lyrics_page_valid?( request, page_body, page_url )
|
|
55
|
+
md = /<TITLE>([^<]+)-\s*([^<]+)\s*lyrics\s*<\/TITLE>/im.match( page_body )
|
|
56
|
+
return false if ! md
|
|
57
|
+
return Strings.normalize( request.artist ) == Strings.normalize( md[1] ) &&
|
|
58
|
+
Strings.normalize( request.title ) == Strings.normalize( md[2] )
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def parse_lyrics( response, page_body )
|
|
62
|
+
|
|
63
|
+
page_body = Strings.latin12utf8( page_body )
|
|
64
|
+
page_body.tr_s!( " \n\r\t", " " )
|
|
65
|
+
HTMLEntities.decode!( page_body )
|
|
66
|
+
|
|
67
|
+
if (md = /<TITLE> ?(.+) ?- ?(.+) ?lyrics ?<\/TITLE>/.match( page_body ))
|
|
68
|
+
response.artist, response.title = md[1].strip(), md[2].strip()
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if (md = /<font face="[^"]+" size=-1>(.+)<\/font>/.match( page_body ))
|
|
72
|
+
page_body = md[1]
|
|
73
|
+
page_body.gsub!( /<\/font>.*/, "" )
|
|
74
|
+
page_body.gsub!( /\ ?<br ?\/?> ?/i, "\n" )
|
|
75
|
+
page_body.gsub!( /\n{3,}/, "\n\n" )
|
|
76
|
+
response.lyrics = page_body
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# # site's search is currently disabled
|
|
82
|
+
# def build_suggestions_fetch_data( request )
|
|
83
|
+
# artist = CGI.escape( Strings.utf82latin1( request.artist ) )
|
|
84
|
+
# title = CGI.escape( Strings.utf82latin1( request.title ) )
|
|
85
|
+
# return FetchPageData.new( "http://#{site_host()}/advanced.php?artistmode=1&artist=#{artist}&songmode=1&song=#{title}&mode=0" )
|
|
86
|
+
# end
|
|
87
|
+
|
|
88
|
+
def build_suggestions_fetch_data( request )
|
|
89
|
+
artist = CGI.escape( Strings.utf82latin1( request.artist ) )
|
|
90
|
+
title = CGI.escape( Strings.utf82latin1( request.title ) )
|
|
91
|
+
return FetchPageData.new( "http://#{site_host()}/search.php?search=#{artist}+#{title}&sartist=1&ssongtitle=1" )
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# def suggestions_page_valid?( request, page_body, page_url )
|
|
95
|
+
# md = /<TITLE>\s*Leo's Lyrics Database\s*-\s*([^<]+)\s*lyrics\s*<\/TITLE>/im.match( page_body )
|
|
96
|
+
# return md ? Strings.normalize( request.artist ) == Strings.normalize( md[1] ) : false
|
|
97
|
+
# end
|
|
98
|
+
|
|
99
|
+
# def parse_suggestions( request, page_body, page_url )
|
|
100
|
+
#
|
|
101
|
+
# page_body = Strings.latin12utf8( page_body )
|
|
102
|
+
# page_body.tr_s!( " \n\r\t", " " )
|
|
103
|
+
# HTMLEntities.decode!( page_body )
|
|
104
|
+
#
|
|
105
|
+
# suggestions = []
|
|
106
|
+
#
|
|
107
|
+
# md = /<ul>(.*)<\/ul>/i.match( page_body )
|
|
108
|
+
# return suggestions if ! md
|
|
109
|
+
#
|
|
110
|
+
# md[1].split( "<li>" ).each do |entry|
|
|
111
|
+
# if (md = /<a href="(\/listlyrics.php;jsessionid=[^"]+)">([^<]+) Lyrics<\/a>/.match( entry ))
|
|
112
|
+
# suggestions << Suggestion.new( request.artist, md[2], "http://#{site_host()}#{md[1]}" )
|
|
113
|
+
# end
|
|
114
|
+
# end
|
|
115
|
+
#
|
|
116
|
+
# return suggestions
|
|
117
|
+
#
|
|
118
|
+
# end
|
|
119
|
+
|
|
120
|
+
def parse_suggestions( request, page_body, page_url )
|
|
121
|
+
|
|
122
|
+
page_body = Strings.latin12utf8( page_body )
|
|
123
|
+
page_body.tr_s!( " \n\r\t", " " )
|
|
124
|
+
HTMLEntities.decode!( page_body )
|
|
125
|
+
|
|
126
|
+
suggestions = []
|
|
127
|
+
|
|
128
|
+
return suggestions if ! page_body.sub!( /^.*<table border=0 width="100%">/, "" )
|
|
129
|
+
return suggestions if ! page_body.sub!( /<\/table>.*$/, "" )
|
|
130
|
+
|
|
131
|
+
page_body.split( /<tr> ?<td>/ ).each do |entry|
|
|
132
|
+
entry.gsub!( /\ *<\/?(td|b|font)[^>]*> */, "" )
|
|
133
|
+
if (md = /<a href="\/artists\/[^"]+">([^<]+)<\/a><a href="([^"]+)">([^<]+)<\/a>/.match( entry ))
|
|
134
|
+
suggestions << Suggestion.new( md[1], md[3], "http://#{site_host()}#{md[2]}" )
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
return suggestions
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Copyright (C) 2007 by Sergio Pistone
|
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the
|
|
16
|
+
# Free Software Foundation, Inc.,
|
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18
|
+
|
|
19
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
|
20
|
+
|
|
21
|
+
require "utils/strings"
|
|
22
|
+
require "utils/htmlentities"
|
|
23
|
+
require "utils/http"
|
|
24
|
+
require "lyrics"
|
|
25
|
+
|
|
26
|
+
class LoudSongs < Lyrics
|
|
27
|
+
|
|
28
|
+
def LoudSongs.site_host()
|
|
29
|
+
return "www.loudson.gs"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def LoudSongs.site_name()
|
|
33
|
+
return "LoudSongs"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def LoudSongs.lyrics_test_data()
|
|
37
|
+
return [
|
|
38
|
+
Request.new( "Radiohead", "Optimistic", "Kid A" ),
|
|
39
|
+
Request.new( "Nirvana", "About a Girl", "Bleach" ),
|
|
40
|
+
Request.new( "Placebo", "Taste in Men", "Black Market Music" ),
|
|
41
|
+
Request.new( "A Perfect Circle", "The Noose", "Thirteen Step" ),
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def LoudSongs.build_song_add_url( request )
|
|
46
|
+
return "http://#{site_host()}/add"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def LoudSongs.build_google_feeling_lucky_url( artist, title=nil )
|
|
50
|
+
query = Strings.google_search_quote( title ? artist : artist + " lyrics" )
|
|
51
|
+
query << " " << Strings.google_search_quote( title + " lyrics" ) if title
|
|
52
|
+
return Strings.build_google_feeling_lucky_url( query, site_host() )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def build_lyrics_fetch_data( request )
|
|
56
|
+
return FetchPageData.new( build_google_feeling_lucky_url( request.artist, request.title ) )
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def lyrics_page_valid?( request, page_body, page_url )
|
|
60
|
+
md = /<title>([^<]+) - [^<]+ - ([^<]+) lyrics<\/title>/i.match( page_body )
|
|
61
|
+
return false if ! md
|
|
62
|
+
return Strings.normalize( md[1] ) == Strings.normalize( request.artist ) &&
|
|
63
|
+
Strings.normalize( md[2] ) == Strings.normalize( request.title )
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def parse_lyrics( response, page_body )
|
|
67
|
+
|
|
68
|
+
page_body.tr_s!( " \n\r\t", " " )
|
|
69
|
+
|
|
70
|
+
if (md = /<h1>Lyrics for: ([^<]+) - ([^<]+)<\/h1> <h1>([0-9])+\) ([^<]+)<\/h1>/.match( page_body ))
|
|
71
|
+
response.artist = Strings.titlecase( md[1].strip() )
|
|
72
|
+
response.album = Strings.titlecase( md[2].strip() )
|
|
73
|
+
response.title = Strings.titlecase( md[4].strip() )
|
|
74
|
+
response.custom_data = { "track" => md[3] }
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
if (md = /<em>Release Year:<\/em> ?([0-9]{4}) ?<br \/>/.match( page_body ))
|
|
78
|
+
response.year = md[1]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
return if ! page_body.gsub!( /^.*<div class="middle_col_TracksLyrics ?">/i, "" )
|
|
82
|
+
return if ! page_body.gsub!( /<\/div>.*$/i, "" )
|
|
83
|
+
|
|
84
|
+
page_body.gsub!( /\ ?<br ?\/?> ?/i, "\n" )
|
|
85
|
+
|
|
86
|
+
response.lyrics = page_body
|
|
87
|
+
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def build_suggestions_fetch_data( request )
|
|
91
|
+
return FetchPageData.new( build_google_feeling_lucky_url( request.artist ) )
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def suggestions_page_valid?( request, page_body, page_url )
|
|
95
|
+
return page_url.index( "http://#{site_host()}/" ) == 0 # TODO
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def parse_suggestions( request, page_body, page_url )
|
|
99
|
+
|
|
100
|
+
page_body = Strings.latin12utf8( page_body )
|
|
101
|
+
page_body.tr_s!( " \n\r\t", " " )
|
|
102
|
+
|
|
103
|
+
suggestions = []
|
|
104
|
+
|
|
105
|
+
if page_url.count( "/" ) == 4 # ARTIST PAGE
|
|
106
|
+
|
|
107
|
+
return suggestions if ! page_body.sub!( /^.*<ul>/i, "" )
|
|
108
|
+
return suggestions if ! page_body.sub!( /<\/ul>.*$/i, "" )
|
|
109
|
+
|
|
110
|
+
page_body.split( /<\/li> ?<li>/ ).each() do |album_entry|
|
|
111
|
+
if (md = /<a href="([^"]+)">/.match( album_entry ))
|
|
112
|
+
suggestions << FetchPageData.new( md[1].downcase() )
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
else # page_url.count( "/" ) == 3 # ALBUM PAGE
|
|
117
|
+
|
|
118
|
+
return suggestions if ! page_body.sub!( /^.*<ul>/i, "" )
|
|
119
|
+
return suggestions if ! page_body.sub!( /<\/ul>.*$/i, "" )
|
|
120
|
+
|
|
121
|
+
HTMLEntities.decode!( page_body )
|
|
122
|
+
|
|
123
|
+
page_body.split( /<\/li> ?<li>/ ).each() do |song_entry|
|
|
124
|
+
if (md = /<a href="([^"]+)">[0-9]+. ([^<]+)<\/a>/.match( song_entry ))
|
|
125
|
+
suggestions << Suggestion.new( request.artist, md[2], md[1].downcase() )
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
return suggestions
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
# Copyright (C) 2006-2008 by Sergio Pistone
|
|
2
|
+
# sergio_pistone@yahoo.com.ar
|
|
3
|
+
#
|
|
4
|
+
# This program is free software; you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program; if not, write to the
|
|
16
|
+
# Free Software Foundation, Inc.,
|
|
17
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
18
|
+
|
|
19
|
+
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
|
|
20
|
+
|
|
21
|
+
require "utils/strings"
|
|
22
|
+
require "utils/http"
|
|
23
|
+
require "mediawikilyrics"
|
|
24
|
+
|
|
25
|
+
require "cgi"
|
|
26
|
+
require "uri"
|
|
27
|
+
|
|
28
|
+
class LyricWiki < MediaWikiLyrics
|
|
29
|
+
|
|
30
|
+
def LyricWiki.site_host()
|
|
31
|
+
return "lyricwiki.org"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def LyricWiki.site_name()
|
|
35
|
+
return "LyricWiki"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def LyricWiki.control_page()
|
|
39
|
+
return "LyricWiki:Wiki-Lyrics"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def parse_lyrics( response, page_body )
|
|
43
|
+
|
|
44
|
+
page_body.gsub!( /’|�/, "'" ) # replace bizarre characters with apostrophes
|
|
45
|
+
|
|
46
|
+
custom_data = {}
|
|
47
|
+
custom_data["reviewed"] = (/\[\[Category:[Rr]eview[_ ]Me\]\]/.match( page_body ) == nil)
|
|
48
|
+
|
|
49
|
+
# search album, year and artist information
|
|
50
|
+
if (md = /\{\{\s*[Ss]ong\s*\|.*$/.match( page_body ))
|
|
51
|
+
unnamed_params_names = { 1 => "album_and_year", 2 => "artist" }
|
|
52
|
+
template_data = parse_template( md[0] )
|
|
53
|
+
template_data["params"].each() do |key, value|
|
|
54
|
+
if (key = unnamed_params_names[key]) && value.is_a?( String )
|
|
55
|
+
custom_data[key] = value
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
if custom_data["reviewed"] && template_data["params"]["star"] == "Green"
|
|
59
|
+
custom_data["reviewed"] = false
|
|
60
|
+
end
|
|
61
|
+
elsif (md = /On (''')?\[\[[^\|]+\|([^\|]+)\]\](''')? by (''')?\[\[([^\]]+)\]\](''')?/.match( page_body ))
|
|
62
|
+
custom_data["album_and_year"] = md[2]
|
|
63
|
+
custom_data["artist"] = md[5]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
if custom_data.include?( "album_and_year" )
|
|
67
|
+
if (md = /^(.+) \(([\?0-9]{4,4})\)$/.match( custom_data["album_and_year"] ))
|
|
68
|
+
response.album = md[1]
|
|
69
|
+
response.year = md[2] if md[2].to_i() > 1900
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# search title information (and other information that hasn't been found yet)
|
|
74
|
+
if (md = /\{\{\s*[Ss]ongFooter\s*\|.*$/.match( page_body ))
|
|
75
|
+
template_data = parse_template( md[0] )
|
|
76
|
+
template_data["params"].each() do |key, value|
|
|
77
|
+
custom_data[key.to_s()] = value if value.is_a?( String )
|
|
78
|
+
end
|
|
79
|
+
elsif (md = /\[[^\s\]]+ ([^\]]+)\] on Amazon$/.match( page_body ))
|
|
80
|
+
custom_data["song"] = md[1].strip()
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
if (md = /\*?\s*Composer: *([^\n]+)/.match( page_body ))
|
|
84
|
+
custom_data["credits"] = md[1].strip()
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
if (md = /\*?\s*Lyrics by: *([^\n]+)/.match( page_body ))
|
|
88
|
+
custom_data["lyricist"] = md[1].strip()
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
response.artist = custom_data["artist"] if custom_data.include?( "artist" )
|
|
92
|
+
response.title = custom_data["song"] if custom_data.include?( "song" )
|
|
93
|
+
response.album = custom_data["album"] if custom_data.include?( "album" )
|
|
94
|
+
|
|
95
|
+
if (md = /<lyrics?>(.*)<\/lyrics?>/im.match( page_body ))
|
|
96
|
+
page_body = md[1]
|
|
97
|
+
if /\s*\{\{[Ii]nstrumental\}\}\s*/.match( page_body )
|
|
98
|
+
page_body = "<tt>(Instrumental)</tt>"
|
|
99
|
+
else
|
|
100
|
+
page_body.gsub!( /[ \t]*[\r\n][ \t]*/m, "\n" )
|
|
101
|
+
end
|
|
102
|
+
else
|
|
103
|
+
if /\s*\{\{[Ii]nstrumental\}\}\s*/.match( page_body )
|
|
104
|
+
page_body = "<tt>(Instrumental)</tt>"
|
|
105
|
+
else
|
|
106
|
+
page_body.gsub!( /\{\{.*\}\}\n?/, "" )
|
|
107
|
+
page_body.gsub!( /\[\[Category:.*\]\]\n?/, "" )
|
|
108
|
+
page_body.gsub!( /On '''\[\[.*?\n/i, "" )
|
|
109
|
+
page_body.gsub!( /By '''\[\[.*?\n/i, "" )
|
|
110
|
+
page_body.gsub!( /\ *== *Credits *==.*$/im, "" )
|
|
111
|
+
page_body.gsub!( /\ *== *(External *Links|Links) *==.*$/im, "" )
|
|
112
|
+
page_body = page_body.split( "\n" ).collect() do |line|
|
|
113
|
+
if line.index( /\s/ ) == 0
|
|
114
|
+
"\n" + line
|
|
115
|
+
else
|
|
116
|
+
line
|
|
117
|
+
end
|
|
118
|
+
end.join( "" )
|
|
119
|
+
page_body.gsub!( /\s*<br ?\/?>\s*/i, "\n" )
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
response.custom_data = custom_data
|
|
124
|
+
|
|
125
|
+
if ! Strings.empty?( page_body )
|
|
126
|
+
# expand ruby tags:
|
|
127
|
+
page_body.gsub!( /\{\{ruby\|([^\|]*)\|([^\}]*)\}\}/, "<ruby><rb>\1</rb><rp>(</rp><rt>\2</rt><rp>)</rp></ruby>" )
|
|
128
|
+
# take care of multiple lyrics tags:
|
|
129
|
+
page_body.gsub!( /(\{\|\s*\|-\s*\||\|\|)\s*==\s*([^=]+)\s*==/, "<br/><b>\2</b>" )
|
|
130
|
+
page_body.gsub!( /\s*==\s*([^=]+)\s*==/, "\n<br/><b>\\1</b>" )
|
|
131
|
+
page_body.gsub!( /<\/?lyric>/i, "" )
|
|
132
|
+
response.lyrics = page_body
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def LyricWiki.parse_search_results( page_body, content_matches=true )
|
|
138
|
+
|
|
139
|
+
results = []
|
|
140
|
+
return results if page_body == nil || ! content_matches
|
|
141
|
+
|
|
142
|
+
page_body.tr_s!( " \n\r\t", " " )
|
|
143
|
+
page_body.gsub!( /\ ?<\/?span[^>]*> ?/, "" )
|
|
144
|
+
|
|
145
|
+
return results if ! page_body.sub!( /^.*<h1 class="firstHeading">Search results<\/h1>/, "" )
|
|
146
|
+
|
|
147
|
+
return results if ! page_body.gsub!( /<form id="powersearch" method="get" action="[^"]+">.*$/, "" )
|
|
148
|
+
page_body.gsub!( /<\/[uo]l> ?<p( [^>]*|)>View \(previous .*$/, "" )
|
|
149
|
+
|
|
150
|
+
page_body.split( "<li>" ).each() do |entry|
|
|
151
|
+
if (md = /<a href="([^"]*index\.php\/|[^"]*index\.php\?title=|\/)([^"]*)" title="([^"]+)"/.match( entry ))
|
|
152
|
+
result = {
|
|
153
|
+
@@SEARCH_RESULT_URL => "http://#{site_host()}/index.php?title=#{md[2]}",
|
|
154
|
+
@@SEARCH_RESULT_TITLE => md[3]
|
|
155
|
+
}
|
|
156
|
+
results << result if ! content_matches || ! results.include?( result )
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
return results
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def LyricWiki.build_tracks( album_data )
|
|
164
|
+
ret = ""
|
|
165
|
+
tracks.each() do |track|
|
|
166
|
+
track_artist = cleanup_title_token( track.artist )
|
|
167
|
+
track_title = cleanup_title_token( track.title )
|
|
168
|
+
tc_track_title = Strings.titlecase( track_title )
|
|
169
|
+
# artist_param = (album_artist == "(Various Artists)" || album_artist == "Various Artists") ? "by" : "artist"
|
|
170
|
+
# ret += "# {{track|title=#{track_title}|#{artist_param}=#{track_artist}}}\n"
|
|
171
|
+
# ret += "# {{track|title=#{track_title}|#{artist_param}=#{track_artist}|display=#{tc_track_title}}}\n"
|
|
172
|
+
ret += "# '''[[#{track_artist}:#{track_title}|#{tc_track_title}]]'''\n"
|
|
173
|
+
end
|
|
174
|
+
return ret
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def LyricWiki.build_album_page( reviewed, artist, album, year, month, day, tracks, album_art )
|
|
178
|
+
|
|
179
|
+
raise ArgumentError if Strings.empty?( artist ) || Strings.empty?( album ) || Strings.empty?( tracks )
|
|
180
|
+
|
|
181
|
+
f_letter = get_first_letter( album )
|
|
182
|
+
|
|
183
|
+
contents = \
|
|
184
|
+
"{{Album\n" \
|
|
185
|
+
"|Artist = #{artist}\n" \
|
|
186
|
+
"|Album = #{album}\n" \
|
|
187
|
+
"|fLetter = #{f_letter}\n" \
|
|
188
|
+
"|Released = #{year}\n" \
|
|
189
|
+
"|Length = #{year}\n" \
|
|
190
|
+
"|Cover = #{album_art}\n" \
|
|
191
|
+
"|star = #{reviewed ? "Black" : "Green"}\n" \
|
|
192
|
+
"}}\n"
|
|
193
|
+
|
|
194
|
+
return \
|
|
195
|
+
"#{contents}\n" \
|
|
196
|
+
"#{tracks.strip()}\n" \
|
|
197
|
+
"\n" \
|
|
198
|
+
"{{AlbumFooter\n" \
|
|
199
|
+
"|artist=#{artist}\n" \
|
|
200
|
+
"|album=#{album}\n" \
|
|
201
|
+
"}}\n"
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def LyricWiki.build_song_page( reviewed, artist, title, album, year, credits, lyricist, lyrics )
|
|
205
|
+
|
|
206
|
+
raise ArgumentError if artist == nil || title == nil
|
|
207
|
+
|
|
208
|
+
f_letter = get_first_letter( title )
|
|
209
|
+
year = year.to_i() > 1900 ? year.to_s() : "????"
|
|
210
|
+
|
|
211
|
+
lyrics = lyrics.gsub(
|
|
212
|
+
/<ruby><rb>([^<]*)<\/rb><rp>\(<\/rp><rt>([^<]*)<\/rt><rp>\)<\/rp><\/ruby>/,
|
|
213
|
+
"{{ruby|\1|\2}}"
|
|
214
|
+
) if lyrics
|
|
215
|
+
|
|
216
|
+
song_album = Strings.empty?( album ) ? "" : "#{album} (#{year})"
|
|
217
|
+
song_star = reviewed ? "Black" : "Green"
|
|
218
|
+
|
|
219
|
+
song_credits = ""
|
|
220
|
+
song_credits << "==Credits==\n" if ! Strings.empty?( credits ) || ! Strings.empty?( lyricist )
|
|
221
|
+
song_credits << "*Composer: #{credits}\n" if ! Strings.empty?( credits )
|
|
222
|
+
song_credits << "*Lyrics by: #{lyricist}\n" if ! Strings.empty?( lyricist )
|
|
223
|
+
|
|
224
|
+
return \
|
|
225
|
+
"{{Song|#{song_album}|#{artist}|star=#{song_star}}\n\n" \
|
|
226
|
+
"<lyric>\n#{Strings.empty?( lyrics ) ? "{{instrumental}}" : lyrics}\n</lyric>\n\n" \
|
|
227
|
+
"#{song_credits}\n" \
|
|
228
|
+
"{{SongFooter\n" \
|
|
229
|
+
"|fLetter=#{f_letter}\n" \
|
|
230
|
+
"|artist=#{artist}\n" \
|
|
231
|
+
"|song=#{title}\n" \
|
|
232
|
+
"|album=#{album}\n" \
|
|
233
|
+
"|language=\n" \
|
|
234
|
+
"|iTunes=\n" \
|
|
235
|
+
"}}\n"
|
|
236
|
+
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def LyricWiki.build_album_art_name( artist, album, year, extension="jpg", cleanup=true )
|
|
240
|
+
if cleanup
|
|
241
|
+
artist = cleanup_title_token( artist )
|
|
242
|
+
album = cleanup_title_token( album )
|
|
243
|
+
end
|
|
244
|
+
album_art_name = "#{artist} - #{album}#{Strings.empty?( extension ) ? "" : ".#{extension.strip()}"}".gsub( " ", "_" )
|
|
245
|
+
return Strings.remove_invalid_filename_chars( album_art_name )
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def LyricWiki.build_album_art_description( artist, album, year, cleanup=true )
|
|
249
|
+
if cleanup
|
|
250
|
+
artist = cleanup_title_token( artist )
|
|
251
|
+
album = cleanup_title_token( album )
|
|
252
|
+
end
|
|
253
|
+
return \
|
|
254
|
+
"{{Albumcover/Upload|\n" \
|
|
255
|
+
"|artist = #{artist}\n" \
|
|
256
|
+
"|album = #{album}\n" \
|
|
257
|
+
"|year = #{year}\n" \
|
|
258
|
+
"}}\n"
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def LyricWiki.find_album_art_name( artist, album, year )
|
|
262
|
+
|
|
263
|
+
normalized_artist = cleanup_title_token( artist )
|
|
264
|
+
Strings.remove_invalid_filename_chars!( normalized_artist )
|
|
265
|
+
Strings.normalize!( normalized_artist )
|
|
266
|
+
normalized_artist.gsub!( " ", "" )
|
|
267
|
+
|
|
268
|
+
normalized_album = cleanup_title_token( album )
|
|
269
|
+
Strings.remove_invalid_filename_chars!( normalized_album )
|
|
270
|
+
Strings.normalize!( normalized_album )
|
|
271
|
+
normalized_album.gsub!( " ", "" )
|
|
272
|
+
|
|
273
|
+
artist = cleanup_title_token( artist )
|
|
274
|
+
Strings.remove_invalid_filename_chars!( artist )
|
|
275
|
+
search_url = "http://#{site_host()}/index.php?ns6=1&search=#{CGI.escape( artist )}&searchx=Search&limit=500"
|
|
276
|
+
response, search_url = HTTP.fetch_page_get( search_url )
|
|
277
|
+
|
|
278
|
+
return nil if response == nil || response.body() == nil
|
|
279
|
+
|
|
280
|
+
candidates = []
|
|
281
|
+
parse_search_results( response.body(), true ).each() do |result|
|
|
282
|
+
|
|
283
|
+
next if result["title"].index( "Image:" ) != 0
|
|
284
|
+
|
|
285
|
+
normalized_title = Strings.normalize( result["title"] )
|
|
286
|
+
normalized_title.gsub!( " ", "" )
|
|
287
|
+
|
|
288
|
+
matches = 0
|
|
289
|
+
idx1 = normalized_title.index( normalized_artist )
|
|
290
|
+
matches += 1 if idx1
|
|
291
|
+
idx1 = idx1 ? idx1 + normalized_artist.size : 0
|
|
292
|
+
idx2 = normalized_title.index( normalized_album, idx1 )
|
|
293
|
+
matches += 2 if idx2
|
|
294
|
+
|
|
295
|
+
candidates.insert( -1, [ matches, result["title"] ] ) if matches > 1
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
if candidates.size > 0
|
|
299
|
+
candidates.sort!() { |x,y| y[0] <=> x[0] }
|
|
300
|
+
return URI.decode( candidates[0][1].slice( "Image:".size..-1 ).gsub( " ", "_" ) )
|
|
301
|
+
else
|
|
302
|
+
return nil
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def LyricWiki.get_first_letter( title )
|
|
307
|
+
if title.index( /^[a-zA-Z]/ ) == 0
|
|
308
|
+
return title.slice( 0, 1 )
|
|
309
|
+
elsif title.index( /^[0-9]/ ) == 0
|
|
310
|
+
return "0-9"
|
|
311
|
+
else
|
|
312
|
+
return "Symbol"
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def LyricWiki.cleanup_title_token!( title, downcase=false )
|
|
317
|
+
title.gsub!( /\[[^\]\[]*\]/, "" )
|
|
318
|
+
title.gsub!( /[\[|\]].*$/, "" )
|
|
319
|
+
title.gsub!( /`|´|’/, "'" )
|
|
320
|
+
title.gsub!( /''|«|»/, "\"" )
|
|
321
|
+
title.squeeze!( " " )
|
|
322
|
+
title.strip!()
|
|
323
|
+
title.gsub!( "+", "and" )
|
|
324
|
+
Strings.titlecase!( title, false, downcase )
|
|
325
|
+
return title
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|