lyrics-ebook 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. data/LICENSE +340 -0
  2. data/README +46 -0
  3. data/bin/lyrics-ebook +47 -0
  4. data/lib/eeepub/LICENSE +20 -0
  5. data/lib/eeepub/README.md +77 -0
  6. data/lib/eeepub/Rakefile +49 -0
  7. data/lib/eeepub/VERSION +1 -0
  8. data/lib/eeepub/examples/files/bar.html +42 -0
  9. data/lib/eeepub/examples/files/foo.html +42 -0
  10. data/lib/eeepub/examples/simple_epub.rb +25 -0
  11. data/lib/eeepub/lib/eeepub.rb +17 -0
  12. data/lib/eeepub/lib/eeepub/container_item.rb +108 -0
  13. data/lib/eeepub/lib/eeepub/easy.rb +100 -0
  14. data/lib/eeepub/lib/eeepub/maker.rb +127 -0
  15. data/lib/eeepub/lib/eeepub/ncx.rb +68 -0
  16. data/lib/eeepub/lib/eeepub/ocf.rb +112 -0
  17. data/lib/eeepub/lib/eeepub/opf.rb +148 -0
  18. data/lib/eeepub/spec/eeepub/easy_spec.rb +66 -0
  19. data/lib/eeepub/spec/eeepub/maker_spec.rb +124 -0
  20. data/lib/eeepub/spec/eeepub/ncx_spec.rb +80 -0
  21. data/lib/eeepub/spec/eeepub/ocf_spec.rb +43 -0
  22. data/lib/eeepub/spec/eeepub/opf_spec.rb +262 -0
  23. data/lib/eeepub/spec/eeepub_spec.rb +4 -0
  24. data/lib/eeepub/spec/spec_helper.rb +12 -0
  25. data/lib/lyrics_ebook.rb +71 -0
  26. data/lib/lyrics_ebook/cache2html.rb +33 -0
  27. data/lib/lyrics_ebook/cache_manager.rb +77 -0
  28. data/lib/lyrics_ebook/lyric.rb +32 -0
  29. data/lib/lyrics_ebook/lyric_download.rb +50 -0
  30. data/lib/lyrics_ebook/lyrics2html.rb +106 -0
  31. data/lib/lyrics_ebook/mini_lyrics_parser.rb +26 -0
  32. data/lib/lyrics_ebook/mp3_parser.rb +37 -0
  33. data/lib/wiki_lyrics/amarok/COPYING +340 -0
  34. data/lib/wiki_lyrics/amarok/README +51 -0
  35. data/lib/wiki_lyrics/amarok/amarok.rb +355 -0
  36. data/lib/wiki_lyrics/amarok/pluginadapter.rb +113 -0
  37. data/lib/wiki_lyrics/amarok/plugins.rb +95 -0
  38. data/lib/wiki_lyrics/amarok/wikilyrics.rb +578 -0
  39. data/lib/wiki_lyrics/amarok/wikilyrics.spec +4 -0
  40. data/lib/wiki_lyrics/amarok/wikipluginadapter.rb +392 -0
  41. data/lib/wiki_lyrics/cli/optionsparser.rb +228 -0
  42. data/lib/wiki_lyrics/cli/pluginadapter.rb +56 -0
  43. data/lib/wiki_lyrics/cli/plugins.rb +79 -0
  44. data/lib/wiki_lyrics/cli/wikilyrics.rb +178 -0
  45. data/lib/wiki_lyrics/cli/wikipluginadapter.rb +140 -0
  46. data/lib/wiki_lyrics/docs/COPYING +340 -0
  47. data/lib/wiki_lyrics/docs/ChangeLog +293 -0
  48. data/lib/wiki_lyrics/docs/HOWTO.pdf +0 -0
  49. data/lib/wiki_lyrics/docs/HOWTO.tex +151 -0
  50. data/lib/wiki_lyrics/docs/HOWTO.txt +139 -0
  51. data/lib/wiki_lyrics/docs/README +45 -0
  52. data/lib/wiki_lyrics/docs/TODO +12 -0
  53. data/lib/wiki_lyrics/gui/gui-gtk.rb +945 -0
  54. data/lib/wiki_lyrics/gui/gui-qt3.rb +785 -0
  55. data/lib/wiki_lyrics/gui/gui-qt4.rb +845 -0
  56. data/lib/wiki_lyrics/gui/gui-tk.rb +1104 -0
  57. data/lib/wiki_lyrics/gui/gui.rb +268 -0
  58. data/lib/wiki_lyrics/gui/test.rb +74 -0
  59. data/lib/wiki_lyrics/i18n/README +1 -0
  60. data/lib/wiki_lyrics/i18n/en.rb +181 -0
  61. data/lib/wiki_lyrics/i18n/es.rb +181 -0
  62. data/lib/wiki_lyrics/i18n/i18n.rb +126 -0
  63. data/lib/wiki_lyrics/i18n/sk.rb +174 -0
  64. data/lib/wiki_lyrics/itrans/COPYRIGHT +31 -0
  65. data/lib/wiki_lyrics/itrans/itrans +0 -0
  66. data/lib/wiki_lyrics/itrans/itrans.txt +8 -0
  67. data/lib/wiki_lyrics/itrans/lyric.txt +23 -0
  68. data/lib/wiki_lyrics/itrans/udvng.ifm +206 -0
  69. data/lib/wiki_lyrics/lyrics.rb +567 -0
  70. data/lib/wiki_lyrics/lyrics_AZLyrics.rb +113 -0
  71. data/lib/wiki_lyrics/lyrics_DarkLyrics.rb +124 -0
  72. data/lib/wiki_lyrics/lyrics_Giitaayan.rb +124 -0
  73. data/lib/wiki_lyrics/lyrics_Jamendo.rb +166 -0
  74. data/lib/wiki_lyrics/lyrics_LeosLyrics.rb +142 -0
  75. data/lib/wiki_lyrics/lyrics_LoudSongs.rb +135 -0
  76. data/lib/wiki_lyrics/lyrics_LyricWiki.rb +329 -0
  77. data/lib/wiki_lyrics/lyrics_LyricsDownload.rb +118 -0
  78. data/lib/wiki_lyrics/lyrics_LyricsMania.rb +141 -0
  79. data/lib/wiki_lyrics/lyrics_Lyriki.rb +287 -0
  80. data/lib/wiki_lyrics/lyrics_SeekLyrics.rb +108 -0
  81. data/lib/wiki_lyrics/lyrics_Sing365.rb +103 -0
  82. data/lib/wiki_lyrics/lyrics_TerraLetras.rb +126 -0
  83. data/lib/wiki_lyrics/mediawikilyrics.rb +1464 -0
  84. data/lib/wiki_lyrics/tests/plugin_tests.rb +161 -0
  85. data/lib/wiki_lyrics/tests/tests.rb +74 -0
  86. data/lib/wiki_lyrics/utils/formdata.rb +56 -0
  87. data/lib/wiki_lyrics/utils/htmlentities.rb +291 -0
  88. data/lib/wiki_lyrics/utils/http.rb +198 -0
  89. data/lib/wiki_lyrics/utils/itrans.rb +160 -0
  90. data/lib/wiki_lyrics/utils/kde.rb +88 -0
  91. data/lib/wiki_lyrics/utils/logger.rb +123 -0
  92. data/lib/wiki_lyrics/utils/strings.rb +378 -0
  93. data/lib/wiki_lyrics/utils/xmlhash.rb +111 -0
  94. data/lib/wiki_lyrics/wikilyrics.kdevelop +152 -0
  95. data/lib/wiki_lyrics/wikilyrics.kdevses +18 -0
  96. data/lib/wiki_lyrics/win/gtk_fix.bat +3 -0
  97. data/lib/wiki_lyrics/win/tk_fix.bat +3 -0
  98. data/lib/wiki_lyrics/win/wikilyrics.bat +4 -0
  99. data/lib/wiki_lyrics/win/win_fix.rb +52 -0
  100. data/templates/art_.erb.xhtml +29 -0
  101. data/templates/artists.erb.xhtml +19 -0
  102. data/templates/cover.erb.xhtml +22 -0
  103. data/test/cache_manager_test.rb +73 -0
  104. data/test/data/artist name/title name.lyric +6 -0
  105. data/test/lyric_test.rb +41 -0
  106. metadata +194 -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,329 @@
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 "gui/gui"
24
+ require "mediawikilyrics"
25
+
26
+ require "cgi"
27
+ require "uri"
28
+
29
+ class LyricWiki < MediaWikiLyrics
30
+
31
+ def LyricWiki.site_host()
32
+ return "lyricwiki.org"
33
+ end
34
+
35
+ def LyricWiki.site_name()
36
+ return "LyricWiki"
37
+ end
38
+
39
+ def LyricWiki.control_page()
40
+ return "LyricWiki:Wiki-Lyrics"
41
+ end
42
+
43
+ def parse_lyrics( response, page_body )
44
+
45
+ page_body.gsub!( /’|�/, "'" ) # replace bizarre characters with apostrophes
46
+
47
+ custom_data = {}
48
+ custom_data["reviewed"] = (/\[\[Category:[Rr]eview[_ ]Me\]\]/.match( page_body ) == nil)
49
+
50
+ # search album, year and artist information
51
+ if (md = /\{\{\s*[Ss]ong\s*\|.*$/.match( page_body ))
52
+ unnamed_params_names = { 1 => "album_and_year", 2 => "artist" }
53
+ template_data = parse_template( md[0] )
54
+ template_data["params"].each() do |key, value|
55
+ if (key = unnamed_params_names[key]) && value.is_a?( String )
56
+ custom_data[key] = value
57
+ end
58
+ end
59
+ if custom_data["reviewed"] && template_data["params"]["star"] == "Green"
60
+ custom_data["reviewed"] = false
61
+ end
62
+ elsif (md = /On (''')?\[\[[^\|]+\|([^\|]+)\]\](''')? by (''')?\[\[([^\]]+)\]\](''')?/.match( page_body ))
63
+ custom_data["album_and_year"] = md[2]
64
+ custom_data["artist"] = md[5]
65
+ end
66
+
67
+ if custom_data.include?( "album_and_year" )
68
+ if (md = /^(.+) \(([\?0-9]{4,4})\)$/.match( custom_data["album_and_year"] ))
69
+ response.album = md[1]
70
+ response.year = md[2] if md[2].to_i() > 1900
71
+ end
72
+ end
73
+
74
+ # search title information (and other information that hasn't been found yet)
75
+ if (md = /\{\{\s*[Ss]ongFooter\s*\|.*$/.match( page_body ))
76
+ template_data = parse_template( md[0] )
77
+ template_data["params"].each() do |key, value|
78
+ custom_data[key.to_s()] = value if value.is_a?( String )
79
+ end
80
+ elsif (md = /\[[^\s\]]+ ([^\]]+)\] on Amazon$/.match( page_body ))
81
+ custom_data["song"] = md[1].strip()
82
+ end
83
+
84
+ if (md = /\*?\s*Composer: *([^\n]+)/.match( page_body ))
85
+ custom_data["credits"] = md[1].strip()
86
+ end
87
+
88
+ if (md = /\*?\s*Lyrics by: *([^\n]+)/.match( page_body ))
89
+ custom_data["lyricist"] = md[1].strip()
90
+ end
91
+
92
+ response.artist = custom_data["artist"] if custom_data.include?( "artist" )
93
+ response.title = custom_data["song"] if custom_data.include?( "song" )
94
+ response.album = custom_data["album"] if custom_data.include?( "album" )
95
+
96
+ if (md = /<lyrics?>(.*)<\/lyrics?>/im.match( page_body ))
97
+ page_body = md[1]
98
+ if /\s*\{\{[Ii]nstrumental\}\}\s*/.match( page_body )
99
+ page_body = "<tt>(Instrumental)</tt>"
100
+ else
101
+ page_body.gsub!( /[ \t]*[\r\n][ \t]*/m, "\n" )
102
+ end
103
+ else
104
+ if /\s*\{\{[Ii]nstrumental\}\}\s*/.match( page_body )
105
+ page_body = "<tt>(Instrumental)</tt>"
106
+ else
107
+ page_body.gsub!( /\{\{.*\}\}\n?/, "" )
108
+ page_body.gsub!( /\[\[Category:.*\]\]\n?/, "" )
109
+ page_body.gsub!( /On '''\[\[.*?\n/i, "" )
110
+ page_body.gsub!( /By '''\[\[.*?\n/i, "" )
111
+ page_body.gsub!( /\ *== *Credits *==.*$/im, "" )
112
+ page_body.gsub!( /\ *== *(External *Links|Links) *==.*$/im, "" )
113
+ page_body = page_body.split( "\n" ).collect() do |line|
114
+ if line.index( /\s/ ) == 0
115
+ "\n" + line
116
+ else
117
+ line
118
+ end
119
+ end.join( "" )
120
+ page_body.gsub!( /\s*<br ?\/?>\s*/i, "\n" )
121
+ end
122
+ end
123
+
124
+ response.custom_data = custom_data
125
+
126
+ if ! Strings.empty?( page_body )
127
+ # expand ruby tags:
128
+ page_body.gsub!( /\{\{ruby\|([^\|]*)\|([^\}]*)\}\}/, "<ruby><rb>\1</rb><rp>(</rp><rt>\2</rt><rp>)</rp></ruby>" )
129
+ # take care of multiple lyrics tags:
130
+ page_body.gsub!( /(\{\|\s*\|-\s*\||\|\|)\s*==\s*([^=]+)\s*==/, "<br/><b>\2</b>" )
131
+ page_body.gsub!( /\s*==\s*([^=]+)\s*==/, "\n<br/><b>\\1</b>" )
132
+ page_body.gsub!( /<\/?lyric>/i, "" )
133
+ response.lyrics = page_body
134
+ end
135
+
136
+ end
137
+
138
+ def LyricWiki.parse_search_results( page_body, content_matches=true )
139
+
140
+ results = []
141
+ return results if page_body == nil || ! content_matches
142
+
143
+ page_body.tr_s!( " \n\r\t", " " )
144
+ page_body.gsub!( /\ ?<\/?span[^>]*> ?/, "" )
145
+
146
+ return results if ! page_body.sub!( /^.*<h1 class="firstHeading">Search results<\/h1>/, "" )
147
+
148
+ return results if ! page_body.gsub!( /<form id="powersearch" method="get" action="[^"]+">.*$/, "" )
149
+ page_body.gsub!( /<\/[uo]l> ?<p( [^>]*|)>View \(previous .*$/, "" )
150
+
151
+ page_body.split( "<li>" ).each() do |entry|
152
+ if (md = /<a href="([^"]*index\.php\/|[^"]*index\.php\?title=|\/)([^"]*)" title="([^"]+)"/.match( entry ))
153
+ result = {
154
+ @@SEARCH_RESULT_URL => "http://#{site_host()}/index.php?title=#{md[2]}",
155
+ @@SEARCH_RESULT_TITLE => md[3]
156
+ }
157
+ results << result if ! content_matches || ! results.include?( result )
158
+ end
159
+ end
160
+
161
+ return results
162
+ end
163
+
164
+ def LyricWiki.build_tracks( album_data )
165
+ ret = ""
166
+ tracks.each() do |track|
167
+ track_artist = cleanup_title_token( track.artist )
168
+ track_title = cleanup_title_token( track.title )
169
+ tc_track_title = Strings.titlecase( track_title )
170
+ # artist_param = (album_artist == "(Various Artists)" || album_artist == "Various Artists") ? "by" : "artist"
171
+ # ret += "# {{track|title=#{track_title}|#{artist_param}=#{track_artist}}}\n"
172
+ # ret += "# {{track|title=#{track_title}|#{artist_param}=#{track_artist}|display=#{tc_track_title}}}\n"
173
+ ret += "# '''[[#{track_artist}:#{track_title}|#{tc_track_title}]]'''\n"
174
+ end
175
+ return ret
176
+ end
177
+
178
+ def LyricWiki.build_album_page( reviewed, artist, album, year, month, day, tracks, album_art )
179
+
180
+ raise ArgumentError if Strings.empty?( artist ) || Strings.empty?( album ) || Strings.empty?( tracks )
181
+
182
+ f_letter = get_first_letter( album )
183
+
184
+ contents = \
185
+ "{{Album\n" \
186
+ "|Artist = #{artist}\n" \
187
+ "|Album = #{album}\n" \
188
+ "|fLetter = #{f_letter}\n" \
189
+ "|Released = #{year}\n" \
190
+ "|Length = #{year}\n" \
191
+ "|Cover = #{album_art}\n" \
192
+ "|star = #{reviewed ? "Black" : "Green"}\n" \
193
+ "}}\n"
194
+
195
+ return \
196
+ "#{contents}\n" \
197
+ "#{tracks.strip()}\n" \
198
+ "\n" \
199
+ "{{AlbumFooter\n" \
200
+ "|artist=#{artist}\n" \
201
+ "|album=#{album}\n" \
202
+ "}}\n"
203
+ end
204
+
205
+ def LyricWiki.build_song_page( reviewed, artist, title, album, year, credits, lyricist, lyrics )
206
+
207
+ raise ArgumentError if artist == nil || title == nil
208
+
209
+ f_letter = get_first_letter( title )
210
+ year = year.to_i() > 1900 ? year.to_s() : "????"
211
+
212
+ lyrics = lyrics.gsub(
213
+ /<ruby><rb>([^<]*)<\/rb><rp>\(<\/rp><rt>([^<]*)<\/rt><rp>\)<\/rp><\/ruby>/,
214
+ "{{ruby|\1|\2}}"
215
+ ) if lyrics
216
+
217
+ song_album = Strings.empty?( album ) ? "" : "#{album} (#{year})"
218
+ song_star = reviewed ? "Black" : "Green"
219
+
220
+ song_credits = ""
221
+ song_credits << "==Credits==\n" if ! Strings.empty?( credits ) || ! Strings.empty?( lyricist )
222
+ song_credits << "*Composer: #{credits}\n" if ! Strings.empty?( credits )
223
+ song_credits << "*Lyrics by: #{lyricist}\n" if ! Strings.empty?( lyricist )
224
+
225
+ return \
226
+ "{{Song|#{song_album}|#{artist}|star=#{song_star}}\n\n" \
227
+ "<lyric>\n#{Strings.empty?( lyrics ) ? "{{instrumental}}" : lyrics}\n</lyric>\n\n" \
228
+ "#{song_credits}\n" \
229
+ "{{SongFooter\n" \
230
+ "|fLetter=#{f_letter}\n" \
231
+ "|artist=#{artist}\n" \
232
+ "|song=#{title}\n" \
233
+ "|album=#{album}\n" \
234
+ "|language=\n" \
235
+ "|iTunes=\n" \
236
+ "}}\n"
237
+
238
+ end
239
+
240
+ def LyricWiki.build_album_art_name( artist, album, year, extension="jpg", cleanup=true )
241
+ if cleanup
242
+ artist = cleanup_title_token( artist )
243
+ album = cleanup_title_token( album )
244
+ end
245
+ album_art_name = "#{artist} - #{album}#{Strings.empty?( extension ) ? "" : ".#{extension.strip()}"}".gsub( " ", "_" )
246
+ return Strings.remove_invalid_filename_chars( album_art_name )
247
+ end
248
+
249
+ def LyricWiki.build_album_art_description( artist, album, year, cleanup=true )
250
+ if cleanup
251
+ artist = cleanup_title_token( artist )
252
+ album = cleanup_title_token( album )
253
+ end
254
+ return \
255
+ "{{Albumcover/Upload|\n" \
256
+ "|artist = #{artist}\n" \
257
+ "|album = #{album}\n" \
258
+ "|year = #{year}\n" \
259
+ "}}\n"
260
+ end
261
+
262
+ def LyricWiki.find_album_art_name( artist, album, year )
263
+
264
+ normalized_artist = cleanup_title_token( artist )
265
+ Strings.remove_invalid_filename_chars!( normalized_artist )
266
+ Strings.normalize!( normalized_artist )
267
+ normalized_artist.gsub!( " ", "" )
268
+
269
+ normalized_album = cleanup_title_token( album )
270
+ Strings.remove_invalid_filename_chars!( normalized_album )
271
+ Strings.normalize!( normalized_album )
272
+ normalized_album.gsub!( " ", "" )
273
+
274
+ artist = cleanup_title_token( artist )
275
+ Strings.remove_invalid_filename_chars!( artist )
276
+ search_url = "http://#{site_host()}/index.php?ns6=1&search=#{CGI.escape( artist )}&searchx=Search&limit=500"
277
+ response, search_url = HTTP.fetch_page_get( search_url )
278
+
279
+ return nil if response == nil || response.body() == nil
280
+
281
+ candidates = []
282
+ parse_search_results( response.body(), true ).each() do |result|
283
+
284
+ next if result["title"].index( "Image:" ) != 0
285
+
286
+ normalized_title = Strings.normalize( result["title"] )
287
+ normalized_title.gsub!( " ", "" )
288
+
289
+ matches = 0
290
+ idx1 = normalized_title.index( normalized_artist )
291
+ matches += 1 if idx1
292
+ idx1 = idx1 ? idx1 + normalized_artist.size : 0
293
+ idx2 = normalized_title.index( normalized_album, idx1 )
294
+ matches += 2 if idx2
295
+
296
+ candidates.insert( -1, [ matches, result["title"] ] ) if matches > 1
297
+ end
298
+
299
+ if candidates.size > 0
300
+ candidates.sort!() { |x,y| y[0] <=> x[0] }
301
+ return URI.decode( candidates[0][1].slice( "Image:".size..-1 ).gsub( " ", "_" ) )
302
+ else
303
+ return nil
304
+ end
305
+ end
306
+
307
+ def LyricWiki.get_first_letter( title )
308
+ if title.index( /^[a-zA-Z]/ ) == 0
309
+ return title.slice( 0, 1 )
310
+ elsif title.index( /^[0-9]/ ) == 0
311
+ return "0-9"
312
+ else
313
+ return "Symbol"
314
+ end
315
+ end
316
+
317
+ def LyricWiki.cleanup_title_token!( title, downcase=false )
318
+ title.gsub!( /\[[^\]\[]*\]/, "" )
319
+ title.gsub!( /[\[|\]].*$/, "" )
320
+ title.gsub!( /`|´|’/, "'" )
321
+ title.gsub!( /''|«|»/, "\"" )
322
+ title.squeeze!( " " )
323
+ title.strip!()
324
+ title.gsub!( "+", "and" )
325
+ Strings.titlecase!( title, false, downcase )
326
+ return title
327
+ end
328
+
329
+ end