lyrics-ebook 0.1

Sign up to get free protection for your applications and to get access to all the features.
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,118 @@
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 "lyrics"
24
+
25
+ class LyricsDownload < Lyrics
26
+
27
+ @@white_chars = "'\"¿?¡!()[].,;:-/& "
28
+
29
+ def LyricsDownload.site_host()
30
+ return "www.lyricsdownload.com"
31
+ end
32
+
33
+ def LyricsDownload.site_name()
34
+ return "Lyrics Download"
35
+ end
36
+
37
+ def LyricsDownload.lyrics_test_data()
38
+ return [
39
+ Request.new( "Nirvana", "Smells Like Teen Spirit", "Nevermind" ),
40
+ Request.new( "Radiohead", "Optimistic", "Kid A" ),
41
+ Request.new( "Massive Attack", "Protection", "Protection" ),
42
+ Request.new( "Portishead", "Wandering Star", "Dummy" ),
43
+ ]
44
+ end
45
+
46
+ def cleanup_artist( artist )
47
+ artist = artist.gsub( /^the /i, "" )
48
+ Strings.remove_vocal_accents!( artist )
49
+ artist.gsub!( "&", "and" )
50
+ artist.tr!( @@white_chars, " " )
51
+ artist.strip!()
52
+ artist.tr!( " ", "-" )
53
+ return artist
54
+ end
55
+
56
+ def cleanup_title( title )
57
+ title = Strings.remove_vocal_accents( title )
58
+ title.gsub!( "&", "and" )
59
+ title.tr!( @@white_chars, " " )
60
+ title.strip!()
61
+ title.tr!( " ", "-" )
62
+ return title
63
+ end
64
+
65
+ def build_lyrics_fetch_data( request )
66
+ artist = cleanup_title( request.artist )
67
+ title = cleanup_title( request.title )
68
+ return FetchPageData.new( "http://#{site_host()}/#{artist}-#{title}-lyrics.html" )
69
+ end
70
+
71
+ def parse_lyrics( response, page_body )
72
+
73
+ page_body = Strings.latin12utf8( page_body )
74
+ page_body.tr_s!( " \n\r\t", " " )
75
+ page_body.tr_s!( "’", "'" )
76
+ # page_body.tr_s!( "‘", "'" )
77
+
78
+ if (md = /<title>([^<]+) - ([^<]+) LYRICS ?<\/title>/i.match( page_body ))
79
+ response.artist, response.title = md[1].strip(), md[2].strip()
80
+ end
81
+
82
+ return if ! page_body.gsub!( /^.*<div class="KonaBody" ><div id="div_customCSS">/, "" )
83
+ return if ! page_body.gsub!( /<\/div> ?<\/div>.*$/, "" )
84
+
85
+ page_body.gsub!( /\ ?<br ?\/?> ?/i, "\n" )
86
+ page_body.strip!()
87
+
88
+ response.lyrics = page_body
89
+
90
+ end
91
+
92
+ def build_suggestions_fetch_data( request )
93
+ artist = cleanup_artist( request.artist )
94
+ return FetchPageData.new( "http://#{site_host()}/#{artist}-lyrics.html" )
95
+ end
96
+
97
+ def parse_suggestions( request, page_body, page_url )
98
+
99
+ page_body = Strings.latin12utf8( page_body )
100
+ page_body.tr_s!( " \n\r\t", " " )
101
+ page_body.tr_s!( "’", "'" )
102
+
103
+ suggestions = []
104
+
105
+ return suggestions if ! page_body.sub!( /^.*Lyrics list aplhabetically:<\/font><\/td>/, "" )
106
+ return suggestions if ! page_body.sub!( /<\/ul> ?<\/td> ?<\/tr> ?<\/table> ?<center><div>.*$/, "" )
107
+
108
+ page_body.split( "</li>" ).each() do |entry|
109
+ if (md = /<a class="txt_1" href="([^"]+)"><font size=2>([^<]+) Lyrics<\/font><\/a>/.match( entry ))
110
+ suggestions << Suggestion.new( request.artist, md[2], "http://#{site_host()}/#{md[1]}" )
111
+ end
112
+ end
113
+
114
+ return suggestions
115
+
116
+ end
117
+
118
+ end
@@ -0,0 +1,141 @@
1
+ # Copyright (C) 2007-2008 by
2
+ # Davide Lo Re <boyska@gmail.com>
3
+ # Sergio Pistone <sergio_pistone@yahoo.com.ar>
4
+ #
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation; either version 2 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program; if not, write to the
17
+ # Free Software Foundation, Inc.,
18
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+
20
+ $LOAD_PATH << File.expand_path(File.dirname(__FILE__))
21
+
22
+ require "utils/strings"
23
+ require "lyrics"
24
+
25
+ require "cgi"
26
+
27
+ class LyricsMania < Lyrics
28
+
29
+ def LyricsMania.site_host()
30
+ return "www.lyricsmania.com"
31
+ end
32
+
33
+ def LyricsMania.site_name()
34
+ return "LyricsMania"
35
+ end
36
+
37
+ def LyricsMania.lyrics_test_data()
38
+ return [
39
+ Request.new( "Nirvana", "Lounge Act", "Nevermind" ),
40
+ Request.new( "Radiohead", "Idioteque", "Kid A" ),
41
+ Request.new( "Pearl Jam", "Porch", "Ten" ),
42
+ Request.new( "The Smashing Pumpkins", "Mayonaise", "Siamese Dream" ),
43
+ ]
44
+ end
45
+
46
+ def LyricsMania.build_song_add_url( request )
47
+ return "http://#{site_host()}/add.html"
48
+ end
49
+
50
+ def LyricsMania.build_google_feeling_lucky_url( artist, title=nil )
51
+ query = Strings.google_search_quote( artist )
52
+ query << " " << Strings.google_search_quote( title + " lyrics" ) if title
53
+ return Strings.build_google_feeling_lucky_url( query, site_host() )
54
+ end
55
+
56
+ def build_lyrics_fetch_data( request )
57
+ return FetchPageData.new( build_google_feeling_lucky_url( request.artist, request.title ) )
58
+ end
59
+
60
+ def lyrics_page_valid?( request, page_body, page_url )
61
+ md = /<title>([^<]+) Lyrics<\/title>/i.match( page_body )
62
+ return false if ! md
63
+ page_title = Strings.normalize( md[1] )
64
+ return page_title.index( Strings.normalize( request.artist ) ) &&
65
+ page_title.index( Strings.normalize( request.title ) )
66
+ end
67
+
68
+ def parse_lyrics( response, page_body )
69
+
70
+ page_body = Strings.latin12utf8( page_body )
71
+ page_body.tr_s!( " \n\r\t", " " )
72
+
73
+ return if ! page_body.sub!( /^.* lyrics<\/h3>/, "" ) # metadata
74
+
75
+ metadata = {}
76
+ ["artist", "album"].each() do |key|
77
+ if (md =/#{key}: <b><a href=[^>]+>([^<]+)<\/a><\/b>/i.match( page_body ))
78
+ metadata[key.downcase()] = md[1].strip().sub( /\ *lyrics$/, "" )
79
+ end
80
+ end
81
+ ["year", "title"].each() do |key|
82
+ if (md =/#{key}: ([^<]+)<(br|\/td)>/i.match( page_body ))
83
+ metadata[key.downcase()] = md[1].strip()
84
+ end
85
+ end
86
+
87
+ response.artist = metadata["artist"] if metadata.include?( "artist" )
88
+ response.title = metadata["title"] if metadata.include?( "title" )
89
+ response.album = metadata["album"] if metadata.include?( "album" )
90
+ response.year = metadata["year"] if metadata.include?( "year" )
91
+
92
+ md = /<\/span> ?<\/center>(.*)<center> ?<span style/.match( page_body )
93
+ return if ! md
94
+
95
+ page_body = md[1]
96
+ page_body.sub!( /&#91;.+ Lyrics on http:\/\/#{site_host()}\/ &#93;/, "" )
97
+ page_body.sub!( /^.*<\/a>/, "" ) # additional (optional) crap at the beginning
98
+ page_body.gsub!( /<u>&lt;a[^<]+&lt;\/a&gt;<\/u>/, "" ) # yet more crap
99
+ page_body.gsub!( /\ ?<br ?\/?> ?/i, "\n" )
100
+ page_body.sub!( /^\ ?<strong>Lyrics to [^<]+<\/strong> :<\/?br> */i, "" )
101
+
102
+ page_body.strip!()
103
+
104
+ response.lyrics = page_body
105
+
106
+ end
107
+
108
+ def build_suggestions_fetch_data( request )
109
+ return FetchPageData.new( build_google_feeling_lucky_url( request.artist ) )
110
+ end
111
+
112
+ def suggestions_page_valid?( request, page_body, page_url )
113
+ md = /<title>([^<]+) Lyrics<\/title>/i.match( page_body )
114
+ return md ? Strings.normalize( md[1] ).index( Strings.normalize( request.artist ) ) : nil
115
+ end
116
+
117
+ # returns an array of maps with following keys: url, artist, title
118
+ def parse_suggestions( request, page_body, page_url )
119
+
120
+ page_body = Strings.latin12utf8( page_body )
121
+ page_body.tr_s!( " \n\r\t", " " )
122
+
123
+ suggestions = []
124
+
125
+ # remove table with other artists at the bottom
126
+ return suggestions if ! page_body.sub!( /(.*)<table.*/, "\\1" )
127
+
128
+ md = /<table width=100%>(.*)<\/table>/.match( page_body )
129
+ return suggestions if ! md
130
+
131
+ md[1].split( /<a href=/ ).each() do |entry|
132
+ if (md = /"(\/lyrics\/[^"]+)" title="[^"]+"> ?([^>]+) lyrics<\/a><br>/.match( entry ))
133
+ suggestions << Suggestion.new( request.artist, md[2], "http://#{site_host()}#{md[1]}" )
134
+ end
135
+ end
136
+
137
+ return suggestions
138
+
139
+ end
140
+
141
+ end
@@ -0,0 +1,287 @@
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 "uri"
27
+ require "cgi"
28
+
29
+ class Lyriki < MediaWikiLyrics
30
+
31
+ def Lyriki.site_host()
32
+ return "www.lyriki.com"
33
+ end
34
+
35
+ def Lyriki.site_name()
36
+ return "Lyriki"
37
+ end
38
+
39
+ def Lyriki.control_page()
40
+ return "Lyriki:Wiki-Lyrics"
41
+ end
42
+
43
+ def parse_lyrics( response, page_body )
44
+
45
+ custom_data = {}
46
+
47
+ if (md = /\{\{\s*[Ss]ong\s*\|.*$/m.match( page_body ))
48
+
49
+ template_data = parse_template( md[0] )
50
+ template_data["params"].each() do |key, value|
51
+ custom_data[key.to_s()] = value
52
+ if value.is_a?( String )
53
+ value.gsub!( /<br ?\/?>/i, "; " ) if key != "song"
54
+ value.gsub!( /<\/?[^>]+\/?>/, " " )
55
+ value.tr_s!( " \n\r\t", " " )
56
+ value.strip!()
57
+ end
58
+ end
59
+
60
+ response.title = custom_data["song"] if custom_data.include?( "song" )
61
+
62
+ if custom_data["artist"].is_a?( String )
63
+ response.artist = custom_data["artist"]
64
+ elsif custom_data["artists"].is_a?( Array )
65
+ artist = ""
66
+ custom_data["artists"].each() do |token|
67
+ if token.is_a?( String )
68
+ artist << token.gsub( /\[\[|\]\]/, "" )
69
+ elsif token.is_a?( Hash ) && token["name"].downcase() == "song artist" && token["params"][1]
70
+ artist << token["params"][1]
71
+ end
72
+ end
73
+ artist.gsub!( /\s*<br *\/?>\s*/i, " " )
74
+ response.artist = artist
75
+ elsif custom_data["artists"].is_a?( String ) # this case is DEPRECATED by Lyriki guides
76
+ response.artist = custom_data["artists"].gsub( /\[\[|\]\]/, "" )
77
+ end
78
+
79
+ if custom_data["album"].is_a?( String )
80
+ response.album, response.year = custom_data["album"], custom_data["year"]
81
+ elsif custom_data["albums"].is_a?( Array )
82
+ custom_data["albums"].each() do |token|
83
+ if token.is_a?( String )
84
+ if (md = /([^:]+):(.+) \(([0-9]{4,4})\)/.match( token ))
85
+ response.album, response.year = md[2], md[3]
86
+ break
87
+ end
88
+ elsif token.is_a?( Hash )
89
+ if token["name"].downcase() == "song album" && token["params"][2] && token["params"][3]
90
+ response.album, response.year = token["params"][2], token["params"][3]
91
+ break
92
+ end
93
+ end
94
+ end
95
+ end
96
+
97
+ end
98
+
99
+ custom_data["reviewed"] = (/\{\{[Aa]utoGenerated\}\}/.match( page_body ) == nil)
100
+
101
+ if (md = /<lyrics>(.*)<\/lyrics>/im.match( page_body ))
102
+ page_body = md[1]
103
+ page_body.gsub!( /[ \t]*[\r\n][ \t]*/m, "\n" )
104
+ else
105
+ page_body.gsub!( /\{\{.*\}\}\n?/, "" )
106
+ page_body.gsub!( /\[\[Category:.*\]\]\n?/, "" )
107
+ page_body.gsub!( /\ *== *(External *Links|Links) *==.*$/im, "" )
108
+ page_body = page_body.split( "\n" ).collect() do |line|
109
+ if line.index( /\s/ ) == 0
110
+ "\n" + line
111
+ else
112
+ line
113
+ end
114
+ end.join( "" )
115
+ page_body.gsub!( /\s*<br ?\/?>\s*/i, "\n" )
116
+ end
117
+
118
+ response.lyrics = page_body if ! Strings.empty?( page_body )
119
+ response.custom_data = custom_data
120
+
121
+ end
122
+
123
+ def Lyriki.build_tracks( album_data )
124
+ ret = ""
125
+ album_data.tracks.each() do |track|
126
+ track_length = track.length > 0 ?
127
+ "|#{track.length / 60}:#{track.length % 60 < 10 ? "0#{track.length % 60}" : track.length % 60}" :
128
+ ""
129
+ track_artist = cleanup_title_token( track.artist )
130
+ track_title = cleanup_title_token( track.title )
131
+ if album_data.various_artists?
132
+ ret += "# {{song link va|#{track_artist}|#{track_title}#{track_length}}}\n"
133
+ else
134
+ ret += "# {{song link|#{track_artist}|#{track_title}#{track_length}}}\n"
135
+ end
136
+ end
137
+ return ret
138
+ end
139
+
140
+ def Lyriki.build_album_page( reviewed, artist, album, year, month, day, tracks, album_art )
141
+
142
+ raise ArgumentError if Strings.empty?( artist ) || Strings.empty?( album ) || Strings.empty?( tracks )
143
+
144
+ s_name = get_sort_name( album )
145
+ s_letter = get_sort_letter( album )
146
+
147
+ album_art = nil if ! year || album_art == build_album_art_name( artist, album, year, "jpg", false )
148
+
149
+ contents = \
150
+ "#{reviewed ? "" : "{{autoGenerated}}\n"}" \
151
+ "{{Album\n" \
152
+ "| album = #{album}\n" \
153
+ "| artist = #{artist}\n" \
154
+ "| released = #{build_date( year, month, day )}\n" \
155
+ "#{album_art ? "| image = #{album_art}\n" : ""}" \
156
+ "| tracks =\n"
157
+
158
+ return \
159
+ "#{contents}" \
160
+ "#{tracks.strip()}\n" \
161
+ "}}\n" \
162
+ "\n" \
163
+ "{{C:Album|#{s_letter}|#{s_name}}}"
164
+ end
165
+
166
+ def Lyriki.build_song_page( reviewed, artist, title, album, year, credits, lyricist, lyrics )
167
+
168
+ raise ArgumentError if artist == nil || title == nil
169
+
170
+ s_name = get_sort_name( title )
171
+ s_letter = get_sort_letter( title )
172
+ year = year.to_i() <= 1900 ? "" : year.to_s()
173
+
174
+ song_page = reviewed ? "": "{{autoGenerated}}\n"
175
+
176
+ if (md = /^([^\s].*)\s+feat\.\s+([^\s].*)$/i.match( artist.strip() ))
177
+ artist, fartist = md[1].strip(), md[2]
178
+ song_page <<
179
+ "{{Song\n" \
180
+ "| song = #{title}\n" \
181
+ "| artists = {{song artist|#{artist}}}<br />feat. {{song artist|#{fartist}}}\n" \
182
+ "| albums = {{song album|#{artist}|#{album}|#{year}}}\n" \
183
+ "| credits = #{credits.to_s().split( "; " ).join( "<br />" )}\n" \
184
+ "| lyricist = #{lyricist.to_s().split( "; " ).join( "<br />" )}\n" \
185
+ "}}\n" \
186
+ else
187
+ song_page <<
188
+ "{{Song\n" \
189
+ "| song = #{title}\n" \
190
+ "| artist = #{artist}\n" \
191
+ "| album = #{album}\n" \
192
+ "| year = #{year}\n" \
193
+ "| credits = #{credits.to_s().split( "; " ).join( "<br />" )}\n" \
194
+ "| lyricist = #{lyricist.to_s().split( "; " ).join( "<br />" )}\n" \
195
+ "}}\n" \
196
+ end
197
+
198
+ return song_page <<
199
+ "\n" \
200
+ "<lyrics>#{Strings.empty?( lyrics ) ? "<tt>(Instrumental)</tt>" : lyrics}</lyrics>\n" \
201
+ "\n" \
202
+ "{{C:Song|#{s_letter}|#{s_name}}}"
203
+ end
204
+
205
+ def Lyriki.build_album_art_name( artist, album, year, extension="jpg", cleanup=true )
206
+ if cleanup
207
+ artist = cleanup_title_token( artist )
208
+ album = cleanup_title_token( album )
209
+ end
210
+ album_art_name = "AlbumArt-#{artist}-#{album}_(#{year})#{Strings.empty?( extension ) ? "" : ".#{extension.strip()}"}".gsub( " ", "_" )
211
+ return Strings.remove_invalid_filename_chars( album_art_name )
212
+ end
213
+
214
+ def Lyriki.build_album_art_description( artist, album, year, cleanup=true )
215
+ if cleanup
216
+ artist = cleanup_title_token( artist )
217
+ album = cleanup_title_token( album )
218
+ end
219
+ return "#{artist}:#{album} (#{year})"
220
+ end
221
+
222
+ def Lyriki.find_album_art_name( artist, album, year )
223
+
224
+ normalized_artist = cleanup_title_token( artist )
225
+ Strings.remove_invalid_filename_chars!( normalized_artist )
226
+ Strings.normalize!( normalized_artist )
227
+ normalized_artist.gsub!( " ", "" )
228
+
229
+ normalized_album = cleanup_title_token( album )
230
+ Strings.remove_invalid_filename_chars!( normalized_album )
231
+ Strings.normalize!( normalized_album )
232
+ normalized_album.gsub!( " ", "" )
233
+
234
+ year = year.to_s().strip()
235
+
236
+ artist = cleanup_title_token( artist )
237
+ Strings.remove_invalid_filename_chars!( artist )
238
+ search_url = "http://#{site_host()}/index.php?ns6=1&search=#{CGI.escape( artist )}&searchx=Search&limit=500"
239
+ response, search_url = HTTP.fetch_page_get( search_url )
240
+
241
+ return nil if response == nil || response.body() == nil
242
+
243
+ candidates = []
244
+ parse_search_results( response.body(), true ).each() do |result|
245
+
246
+ next if result[@@SEARCH_RESULT_TITLE].index( "Image:" ) != 0
247
+
248
+ normalized_title = Strings.normalize( result[@@SEARCH_RESULT_TITLE] )
249
+ normalized_title.gsub!( " ", "" )
250
+
251
+ matches = 0
252
+ idx1 = normalized_title.index( "albumart" )
253
+ matches += 1 if idx1
254
+ idx1 = idx1 ? idx1 + "albumart".size : 0
255
+ idx2 = normalized_title.index( normalized_artist, idx1 )
256
+ matches += 4 if idx2
257
+ idx2 = idx2 ? idx2 + normalized_artist.size : idx1
258
+ idx3 = normalized_title.index( normalized_album, idx2 )
259
+ next if idx3 == nil
260
+ idx3 = idx3 ? idx3 + normalized_album.size : idx2
261
+ idx3 = normalized_title.index( year, idx3 )
262
+ matches += 2 if idx3
263
+
264
+ candidates.insert( -1, [ matches, result[@@SEARCH_RESULT_TITLE] ] )
265
+ end
266
+
267
+ if candidates.size > 0
268
+ candidates.sort!() { |x,y| y[0] <=> x[0] }
269
+ return URI.decode( candidates[0][1].slice( "Image:".size..-1 ).gsub( " ", "_" ) )
270
+ else
271
+ return nil
272
+ end
273
+ end
274
+
275
+ def Lyriki.cleanup_title_token!( title, downcase=false )
276
+ title.gsub!( /\[[^\]\[]*\]/, "" )
277
+ title.gsub!( /[\[|\]].*$/, "" )
278
+ title.gsub!( /`|´|’/, "'" )
279
+ title.gsub!( /''|«|»/, "\"" )
280
+ title.squeeze!( " " )
281
+ title.strip!()
282
+ title.gsub!( "+", "and" )
283
+ Strings.titlecase!( title, true, downcase )
284
+ return title
285
+ end
286
+
287
+ end