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.
Files changed (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +45 -0
  6. data/VERSION +1 -0
  7. data/bin/lyrics +66 -0
  8. data/lib/lyrics.rb +4 -0
  9. data/lib/lyrics/cli/application.rb +99 -0
  10. data/lib/lyrics/cli/optionsparser.rb +228 -0
  11. data/lib/lyrics/cli/pluginadapter.rb +56 -0
  12. data/lib/lyrics/cli/plugins.rb +79 -0
  13. data/lib/lyrics/cli/wikipluginadapter.rb +139 -0
  14. data/lib/lyrics/i18n/README +1 -0
  15. data/lib/lyrics/i18n/en.rb +181 -0
  16. data/lib/lyrics/i18n/es.rb +181 -0
  17. data/lib/lyrics/i18n/i18n.rb +126 -0
  18. data/lib/lyrics/i18n/sk.rb +174 -0
  19. data/lib/lyrics/itrans/COPYRIGHT +31 -0
  20. data/lib/lyrics/itrans/itrans +0 -0
  21. data/lib/lyrics/itrans/itrans.txt +8 -0
  22. data/lib/lyrics/itrans/lyric.txt +23 -0
  23. data/lib/lyrics/itrans/udvng.ifm +206 -0
  24. data/lib/lyrics/lyrics.rb +567 -0
  25. data/lib/lyrics/lyrics_AZLyrics.rb +113 -0
  26. data/lib/lyrics/lyrics_DarkLyrics.rb +124 -0
  27. data/lib/lyrics/lyrics_Giitaayan.rb +124 -0
  28. data/lib/lyrics/lyrics_Jamendo.rb +166 -0
  29. data/lib/lyrics/lyrics_LeosLyrics.rb +142 -0
  30. data/lib/lyrics/lyrics_LoudSongs.rb +135 -0
  31. data/lib/lyrics/lyrics_LyricWiki.rb +328 -0
  32. data/lib/lyrics/lyrics_LyricsDownload.rb +118 -0
  33. data/lib/lyrics/lyrics_LyricsMania.rb +141 -0
  34. data/lib/lyrics/lyrics_Lyriki.rb +286 -0
  35. data/lib/lyrics/lyrics_SeekLyrics.rb +108 -0
  36. data/lib/lyrics/lyrics_Sing365.rb +103 -0
  37. data/lib/lyrics/lyrics_TerraLetras.rb +126 -0
  38. data/lib/lyrics/mediawikilyrics.rb +1417 -0
  39. data/lib/lyrics/utils/formdata.rb +56 -0
  40. data/lib/lyrics/utils/htmlentities.rb +291 -0
  41. data/lib/lyrics/utils/http.rb +198 -0
  42. data/lib/lyrics/utils/itrans.rb +160 -0
  43. data/lib/lyrics/utils/logger.rb +123 -0
  44. data/lib/lyrics/utils/strings.rb +378 -0
  45. data/lib/lyrics/utils/xmlhash.rb +111 -0
  46. data/lyrics.gemspec +98 -0
  47. data/spec/lyrics_spec.rb +7 -0
  48. data/spec/spec.opts +1 -0
  49. data/spec/spec_helper.rb +9 -0
  50. 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