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,4 @@
1
+ name = Wiki-Lyrics
2
+ type = lyrics
3
+
4
+ [Lyrics]
@@ -0,0 +1,392 @@
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
+ require File.expand_path( File.dirname( __FILE__ ) + "/../utils/strings" )
20
+ require File.expand_path( File.dirname( __FILE__ ) + "/../utils/xmlhash" )
21
+ require File.expand_path( File.dirname( __FILE__ ) + "/../i18n/i18n" )
22
+ require File.expand_path( File.dirname( __FILE__ ) + "/../gui/gui" )
23
+ require File.expand_path( File.dirname( __FILE__ ) + "/pluginadapter" )
24
+ require File.expand_path( File.dirname( __FILE__ ) + "/plugins" )
25
+ require File.expand_path( File.dirname( __FILE__ ) + "/amarok" )
26
+
27
+ require "uri"
28
+
29
+ module WikiPluginAdapter
30
+
31
+ # Hack to make module methods become class methods when the module gets included
32
+ def WikiPluginAdapter.included( including )
33
+ if including.is_a?( Class )
34
+ including.extend( ClassMethods ) # adds class methods
35
+ else # including.is_a?( Module )
36
+ including::ClassMethods.append_class_methods( self )
37
+ end
38
+ end
39
+
40
+ # Methods under this module will became class methods when the module gets included
41
+ # Note: don't use def self.<method name> but just <method name>
42
+ module ClassMethods
43
+ def ClassMethods.append_class_methods( mod )
44
+ include mod::ClassMethods
45
+ end
46
+ end
47
+
48
+ include PluginAdapter
49
+
50
+ @@MENU_ENTRY_ALBUM = I18n.get( "amarok.wikiplugin.checkalbum" )
51
+ @@MENU_ENTRY_SONG = I18n.get( "amarok.wikiplugin.checksong" )
52
+ @@MENU_UPLOAD_COVER = I18n.get( "amarok.wikiplugin.uploadcover" )
53
+ @@MENU_SUBMIT_CONTENT = I18n.get( "amarok.wikiplugin.submitcontent" )
54
+
55
+
56
+ def check_submit_conditions()
57
+
58
+ if @wpa_submit
59
+ login( @wpa_username, @wpa_password, false )
60
+ else
61
+ logout()
62
+ end
63
+
64
+ if ! logged_in?
65
+ @wpa_submit = false
66
+ end
67
+
68
+ if ! @wpa_submit || ! @wpa_review
69
+ @wpa_prompt_no_lyrics = false
70
+ @wpa_prompt_autogen = false
71
+ end
72
+
73
+ end
74
+
75
+ def submit?()
76
+ return @wpa_submit
77
+ end
78
+
79
+ def read_config( config_file )
80
+
81
+ values = {
82
+ "#{plugin_name}_submit" => nil,
83
+ "#{plugin_name}_review" => nil,
84
+ "#{plugin_name}_prompt_autogen" => nil,
85
+ "#{plugin_name}_prompt_no_lyrics" => nil,
86
+ "#{plugin_name}_username" => nil,
87
+ "#{plugin_name}_password" => nil,
88
+ "#{plugin_name}_cookie" => nil,
89
+ "#{plugin_name}_last_auth_check" => nil,
90
+ "#{plugin_name}_authorized" => nil,
91
+ }
92
+
93
+ XMLHash.read( config_file, values )
94
+
95
+ @wpa_review = values["#{plugin_name}_review"] != "false"
96
+ @wpa_submit = values["#{plugin_name}_submit"] == "true"
97
+ @wpa_prompt_autogen = values["#{plugin_name}_prompt_autogen"] == "true"
98
+ @wpa_prompt_no_lyrics = values["#{plugin_name}_prompt_no_lyrics"] == "true"
99
+ @wpa_username = Strings.descramble( values["#{plugin_name}_username"] )
100
+ @wpa_password = Strings.descramble( values["#{plugin_name}_password"] )
101
+
102
+ if @wpa_submit
103
+ restore_session_params(
104
+ @wpa_username,
105
+ @wpa_password,
106
+ values["#{plugin_name}_cookie"],
107
+ values["#{plugin_name}_last_auth_check"].to_i(),
108
+ values["#{plugin_name}_authorized"] == "true"
109
+ )
110
+ end
111
+
112
+ check_submit_conditions()
113
+
114
+ end
115
+
116
+ def write_config( config_file )
117
+
118
+ if @wpa_submit
119
+ username, password, cookie, last_auth_check, authorized = get_session_params()
120
+ else
121
+ cookie, last_auth_check, authorized = nil, nil, nil
122
+ end
123
+
124
+ values = {
125
+ "#{plugin_name}_submit" => @wpa_submit,
126
+ "#{plugin_name}_review" => @wpa_review,
127
+ "#{plugin_name}_prompt_autogen" => @wpa_prompt_autogen,
128
+ "#{plugin_name}_prompt_no_lyrics" => @wpa_prompt_no_lyrics,
129
+ "#{plugin_name}_username" => Strings.scramble( @wpa_username ),
130
+ "#{plugin_name}_password" => Strings.scramble( @wpa_password ),
131
+ "#{plugin_name}_cookie" => cookie,
132
+ "#{plugin_name}_last_auth_check" => last_auth_check,
133
+ "#{plugin_name}_authorized" => authorized,
134
+ }
135
+
136
+ XMLHash.write( config_file, values )
137
+
138
+ end
139
+
140
+ def configure()
141
+
142
+ values = {
143
+ "site_name" => site_name(),
144
+ "review" => @wpa_review,
145
+ "submit" => @wpa_submit,
146
+ "prompt_autogen" => @wpa_prompt_autogen,
147
+ "prompt_no_lyrics" => @wpa_prompt_no_lyrics,
148
+ "username" => @wpa_username,
149
+ "password" => @wpa_password
150
+ }
151
+
152
+ if GUI.show_wiki_plugin_dialog( values )
153
+ @wpa_review = values["review"].to_s() != "false"
154
+ @wpa_submit = values["submit"].to_s() == "true"
155
+ @wpa_prompt_autogen = values["prompt_autogen"].to_s() == "true"
156
+ @wpa_prompt_no_lyrics = values["prompt_no_lyrics"].to_s() == "true"
157
+ @wpa_username = values["username"]
158
+ @wpa_password = values["password"]
159
+ end
160
+
161
+ check_submit_conditions()
162
+
163
+ if @wpa_submit
164
+ add_custom_menu_item( @@MENU_UPLOAD_COVER )
165
+ add_custom_menu_item( @@MENU_ENTRY_ALBUM )
166
+ add_custom_menu_item( @@MENU_ENTRY_SONG )
167
+ else
168
+ remove_custom_menu_item( @@MENU_UPLOAD_COVER )
169
+ remove_custom_menu_item( @@MENU_ENTRY_ALBUM )
170
+ remove_custom_menu_item( @@MENU_ENTRY_SONG )
171
+ end
172
+
173
+ add_custom_checkeable_menu_item( @@MENU_SUBMIT_CONTENT, @wpa_submit )
174
+
175
+ end
176
+
177
+ def on_start()
178
+ if @wpa_submit
179
+ add_custom_menu_item( @@MENU_UPLOAD_COVER )
180
+ add_custom_menu_item( @@MENU_ENTRY_ALBUM )
181
+ add_custom_menu_item( @@MENU_ENTRY_SONG )
182
+ end
183
+ add_custom_checkeable_menu_item( @@MENU_SUBMIT_CONTENT, @wpa_submit )
184
+ end
185
+
186
+ def on_quit()
187
+ remove_custom_menu_item( @@MENU_UPLOAD_COVER )
188
+ remove_custom_menu_item( @@MENU_ENTRY_ALBUM )
189
+ remove_custom_menu_item( @@MENU_ENTRY_SONG )
190
+ remove_custom_checkeable_menu_item( @@MENU_SUBMIT_CONTENT )
191
+ end
192
+
193
+ def on_custom_menu_item_selected( menu, item, urls )
194
+ return if menu != plugin_name()
195
+ if item == @@MENU_UPLOAD_COVER
196
+ url = URI.parse( urls[0] )
197
+ upload_album_cover( url.scheme == "file" ? URI.decode( url.path ) : nil)
198
+ elsif item == @@MENU_ENTRY_ALBUM
199
+ url = URI.parse( urls[0] )
200
+ return if url.scheme != "file"
201
+ check_album_page( URI.decode( url.path ) )
202
+ elsif item == @@MENU_ENTRY_SONG
203
+ urls.each() do |url|
204
+ # TODO add skip dialog, show remaining
205
+ url = URI.parse( url )
206
+ return if url.scheme != "file"
207
+ check_song_page( URI.decode( url.path ) )
208
+ end
209
+ elsif /\] #{@@MENU_SUBMIT_CONTENT}$/.match( item )
210
+ if ! @wpa_submit && Strings.empty?( @wpa_username ) # there's not username to login with
211
+ @wpa_submit = true
212
+ configure()
213
+ return
214
+ end
215
+ @wpa_submit = ! @wpa_submit
216
+ check_submit_conditions()
217
+ if @wpa_submit
218
+ add_custom_menu_item( @@MENU_UPLOAD_COVER )
219
+ add_custom_menu_item( @@MENU_ENTRY_ALBUM )
220
+ add_custom_menu_item( @@MENU_ENTRY_SONG )
221
+ else
222
+ remove_custom_menu_item( @@MENU_UPLOAD_COVER )
223
+ remove_custom_menu_item( @@MENU_ENTRY_ALBUM )
224
+ remove_custom_menu_item( @@MENU_ENTRY_SONG )
225
+ end
226
+ add_custom_checkeable_menu_item( @@MENU_SUBMIT_CONTENT, @wpa_submit )
227
+ end
228
+
229
+ end
230
+
231
+ def check_album_page( file )
232
+ album_data = Amarok.query_album_data( file )
233
+ if album_data.empty? || album_data["tracks"].empty? # can't even attempt to search the album...
234
+ notify( I18n.get( "amarok.wikiplugin.checkalbum.noinfofound" ) )
235
+ else
236
+ begin
237
+ tracks = []
238
+ album_data["tracks"].each() do |track|
239
+ tracks << MediaWikiLyrics::TrackData.new( track["artist"], track["title"], track["length"] )
240
+ end
241
+ submit_album_page(
242
+ MediaWikiLyrics::AlbumData.new( tracks, album_data["album"], album_data["year"] ),
243
+ album_data["image_path"],
244
+ false, # is user allowed to overwrite existing pages?
245
+ false, # do we know the page doesn't exists?
246
+ @wpa_review, # should we show the review contents dialog?
247
+ false # should user be forced to review content? (true causes the operation to abort if he doesn't)
248
+ )
249
+ rescue TimeoutError
250
+ notify( I18n.get( "amarok.application.search.plugintimeout", plugin_name(), site_host() ) )
251
+ end
252
+ end
253
+ end
254
+
255
+
256
+ def upload_album_cover( file )
257
+
258
+ album_data = Amarok.query_album_data( file )
259
+ if album_data.empty?
260
+ album_data["artist"] = album_data["album"] = album_data["year"] = album_data["image_path"] = ""
261
+ end
262
+ album_data["site_name"] = site_name()
263
+
264
+ if GUI.show_upload_cover_dialog( album_data )
265
+
266
+ album_data["year"] = album_data["year"].to_s()
267
+ if Strings.empty?( album_data["artist"] ) || Strings.empty?( album_data["album"] ) || Strings.empty?( album_data["year"] )
268
+ notify( I18n.get( "amarok.wikiplugin.uploadcover.invalidalbumparams" ) )
269
+ elsif Strings.empty?( album_data["image_path"] )
270
+ notify( I18n.get( "amarok.wikiplugin.uploadcover.noimagepath" ) )
271
+ else
272
+ notify( I18n.get( "amarok.wikiplugin.uploadcover.searching", album_data["album"], album_data["artist"] ) )
273
+ begin
274
+ if ! find_album_art_name( album_data["artist"], album_data["album"], album_data["year"] )
275
+ upload_cover_image( album_data["image_path"], album_data["artist"], album_data["album"], album_data["year"])
276
+ else
277
+ notify( I18n.get( "amarok.wikiplugin.uploadcover.found" ) )
278
+ end
279
+ rescue TimeoutError
280
+ notify( I18n.get( "amarok.application.search.plugintimeout", plugin_name(), site_host() ) )
281
+ end
282
+ end
283
+ end
284
+
285
+ end
286
+
287
+ def wiki_process_response( response, response_plugin, wiki_searched )
288
+
289
+ return if ! submit?() || ! authorized?
290
+
291
+ lyrics_found_on_site = response.lyrics && response_plugin == self
292
+ lyrics_autogenerated = lyrics_found_on_site && ! response.custom_data["reviewed"]
293
+
294
+ return if lyrics_found_on_site && ! lyrics_autogenerated # we have nothing to do
295
+ return if (! @wpa_prompt_autogen && lyrics_autogenerated) || (! @wpa_prompt_no_lyrics && ! response.lyrics)
296
+
297
+ begin
298
+
299
+ song_data = MediaWikiLyrics::SongData.new(
300
+ response.artist ? response.artist : response.request.artist,
301
+ response.title ? response.title : response.request.title,
302
+ response.lyrics,
303
+ response.album ? response.album : response.request.album,
304
+ response.year ? response.year : response.request.year,
305
+ response.custom_data["credits"],
306
+ response.custom_data["lyricist"]
307
+ )
308
+
309
+ url, submitted_data = submit_song_page(
310
+ song_data,
311
+ lyrics_autogenerated ? response.url : nil, # are we editing an existing page or creating a new one?
312
+ song_data.artist == response.request.artist && song_data.title == response.request.title &&
313
+ wiki_searched && ! lyrics_found_on_site, # do we KNOW FOR SURE the page doesn't exists?
314
+ @wpa_review || lyrics_autogenerated, # should we show the review contents dialog?
315
+ lyrics_autogenerated # should user be forced to review contents? (true causes the operation to abort otherwise)
316
+ )
317
+
318
+ # transfer summited data to response
319
+ if submitted_data
320
+ response.artist = submitted_data["artist"] if ! Strings.empty?( submitted_data["artist"] )
321
+ response.title = submitted_data["title"] if ! Strings.empty?( submitted_data["title"] )
322
+ response.album = submitted_data["album"] if ! Strings.empty?( submitted_data["album"] )
323
+ response.year = submitted_data["year"] if ! Strings.empty?( submitted_data["year"] )
324
+ response.lyrics = submitted_data["lyrics"] if ! Strings.empty?( submitted_data["lyrics"] )
325
+ custom_data = {}
326
+ custom_data.merge( response.custom_data )
327
+ custom_data["credits"] = submitted_data["credits"] if ! Strings.empty?( submitted_data["credits"] )
328
+ custom_data["lyricst"] = submitted_data["lyricst"] if ! Strings.empty?( submitted_data["lyricst"] )
329
+ response.custom_data = custom_data
330
+ end
331
+
332
+ rescue TimeoutError
333
+ notify( I18n.get( "amarok.application.search.plugintimeout", plugin_name(), site_host() ) )
334
+ end
335
+
336
+ end
337
+
338
+ def check_song_page( file )
339
+
340
+ song_data = Amarok.query_song_data( file )
341
+
342
+ if song_data.empty?
343
+ notify( I18n.get( "amarok.wikiplugin.checksong.noinfofound" ) )
344
+ return
345
+ end
346
+
347
+ request = Lyrics::Request.new( song_data["artist"], song_data["title"], song_data["album"], song_data["year"] )
348
+
349
+ notify( I18n.get( "wiki.submitsong.searchingpage", request.title, request.artist ) )
350
+
351
+ response = self.lyrics_full_search( request )
352
+ response_plugin = self
353
+
354
+ if response.lyrics
355
+ if ! response.custom_data["reviewed"]
356
+ notify( I18n.get( "wiki.submitsong.pagefound.autogenerated", request.title, request.artist ) )
357
+ return if ! @wpa_prompt_autogen # autogen lyrics found but user won't review them, nothing to do for us
358
+ else
359
+ notify( I18n.get( "wiki.submitsong.pagefound", request.title, request.artist ) )
360
+ return # reviewed lyrics found, nothing to do for us
361
+ end
362
+ else
363
+ notify( I18n.get( "wiki.submitsong.nopagefound", request.title, request.artist ) )
364
+ end
365
+
366
+ if ! response.lyrics
367
+ # if the lyrics weren't found on the site, first we try to find them in Amarok database
368
+ response.lyrics = Amarok.query_song_lyrics( file )
369
+ response_plugin = nil
370
+ # if we didn't found them there, we try the other selected sites
371
+ if ! response.lyrics
372
+ used_plugins = Plugins.used_plugins().clone()
373
+ used_plugins.delete( self )
374
+ used_plugins.each() do |plugin|
375
+ begin
376
+ response = plugin.lyrics_full_search( request )
377
+ if request.lyrics
378
+ response_plugin = plugin
379
+ break
380
+ end
381
+ rescue TimeoutError
382
+ notify( I18n.get("amarok.application.search.plugintimeout", plugin.plugin_name(), plugin.site_host()) )
383
+ end
384
+ end
385
+ end
386
+ end
387
+
388
+ wiki_process_response( response, response_plugin, true )
389
+
390
+ end
391
+
392
+ end
@@ -0,0 +1,228 @@
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
+ require File.expand_path( File.dirname( __FILE__ ) + "/../i18n/i18n" )
20
+ require File.expand_path( File.dirname( __FILE__ ) + "/plugins" )
21
+ require File.expand_path( File.dirname( __FILE__ ) + "/../mediawikilyrics" )
22
+
23
+ require "optparse"
24
+ require "ostruct"
25
+ require "uri"
26
+
27
+ WIKILYRICS_VERSION = "Wiki-Lyrics v#{MediaWikiLyrics.version()}"
28
+ TOOLKITS_DEFAULT = ["qt3", "qt4", "gtk", "tk"]
29
+
30
+ module OptionsParser
31
+
32
+ @@max_chunksize = 80
33
+ begin
34
+ require "curses"
35
+ @@max_chunksize = Curses::Window.new( 0, 0, 0, 0 ).maxx() - 38
36
+ Curses::close_screen()
37
+ rescue Exception
38
+ @@max_chunksize = 80
39
+ end
40
+
41
+ def self.get_text_chunk( text, start_idx )
42
+
43
+ # find first non empty character in chunk:
44
+ while ( start_idx < (text.size-1) && "\n ".index( text[start_idx] ) )
45
+ start_idx += 1
46
+ end
47
+
48
+ # no more chunks left
49
+ return nil if start_idx >= text.size
50
+
51
+ # buscar el ultimo " " o el primer "\n "
52
+ end_idx = nil
53
+ idx = start_idx
54
+ while ( idx < text.size && idx < start_idx + @@max_chunksize + 1 )
55
+ if text[idx] == "\n"[0]
56
+ end_idx = idx
57
+ break
58
+ elsif text[idx] == " "[0]
59
+ end_idx = idx
60
+ end
61
+ idx += 1
62
+ end
63
+ end_idx = idx if ! end_idx || idx == text.size
64
+ return text.slice( start_idx..end_idx-1 ), end_idx
65
+
66
+ end
67
+
68
+ def self.split( text )
69
+ ret = []
70
+ start_idx = 0
71
+ while ( (chunk, start_idx = get_text_chunk( text, start_idx )) && chunk != nil )
72
+ ret << chunk
73
+ end
74
+ return ret
75
+ end
76
+
77
+ def self.parse( args )
78
+
79
+ opts = OpenStruct.new()
80
+ opts.cleanup = true
81
+ opts.feat_fix = true
82
+ opts.meta = true
83
+ opts.sites = ["Lyriki", "LyricWiki"]
84
+ opts.submit = nil
85
+ opts.review = true
86
+ opts.prompt_autogen = false
87
+ opts.prompt_no_lyrics = false
88
+ opts.proxy = nil
89
+ opts.toolkits = TOOLKITS_DEFAULT
90
+
91
+ parser = OptionParser.new() do |parser|
92
+ parser.banner = I18n.get( "cli.usage", "wikilyrics.rb" )
93
+ parser.separator I18n.get( "cli.description" )
94
+
95
+ parser.separator ""
96
+ parser.separator I18n.get( "cli.options" )
97
+ parser.on( "-a", "--artist [ARTIST]", *split( I18n.get( "cli.options.artist", "batch-file" ) ) ) do |artist|
98
+ opts.artist = artist
99
+ end
100
+ parser.on( "-t", "--title [TITLE]", *split( I18n.get( "cli.options.title", "batch-file" ) ) ) do |title|
101
+ opts.title = title
102
+ end
103
+ parser.on( "-l", "--album [ALBUM]", *split( I18n.get( "cli.options.album" ) ) ) { |album| opts.album = album }
104
+ parser.on( "-y", "--year [YEAR]", *split( I18n.get( "cli.options.year" ) ) ) { |year| opts.year = year }
105
+ parser.on( "-f", "--[no-]featfix", *split( I18n.get( "cli.options.featfix", I18n.get( "cli.values.true" ) ) ) ) do |feat_fix|
106
+ opts.feat_fix = feat_fix
107
+ end
108
+
109
+ parser.separator ""
110
+ parser.on( "-b", "--batch-file [FILE]", *split( I18n.get( "cli.options.batchfile" ) ) ) do |batch_file|
111
+ opts.batch_file = batch_file
112
+ end
113
+
114
+ parser.separator ""
115
+ parser.on( "-c", "--[no-]cleanup", *split( I18n.get( "cli.options.cleanup", I18n.get( "cli.values.true" ) ) ) ) do |cleanup|
116
+ opts.cleanup = cleanup
117
+ end
118
+ parser.separator ""
119
+ parser.on( "--sites [SITE1,SITE2...]", Array, *split( I18n.get( "cli.options.sites", opts.sites.join( "," ), "sites-list" ) ) ) { |sites| opts.sites = sites }
120
+ parser.on( "--sites-list", *split( I18n.get( "cli.options.sites.list" ) ) ) do
121
+ puts I18n.get( "cli.options.sites.list.available" )
122
+ Plugins.load_plugins( Plugins.find_plugins() )
123
+ plugins = Plugins.all_plugins().sort { |a,b| a.class.name <=> b.class.name }
124
+ plugins.each() { |plugin| puts " - #{plugin.class.name.slice(12..-1)} (#{plugin.site_host})" }
125
+ exit
126
+ end
127
+
128
+ parser.separator ""
129
+ parser.on( "-s", "--submit [Lyriki|LyricWiki]", *split( I18n.get( "cli.options.submit", "username", "password" ) ) ) do |submit|
130
+ opts.submit = submit
131
+ end
132
+ parser.on( "-u", "--username [USERNAME]", *split( I18n.get( "cli.options.username", "submit" ) ) ) do |username|
133
+ opts.username = username
134
+ end
135
+ parser.on( "-p", "--password [PASSWORD]", *split( I18n.get( "cli.options.password", "submit" ) ) ) do |password|
136
+ opts.password = password
137
+ end
138
+ parser.on( "--persist [SESSIONFILE]", *split( I18n.get( "cli.options.persist", "username", "password" ) ) ) do |file|
139
+ opts.session_file = file
140
+ end
141
+
142
+ parser.on( "-r", "--[no-]review", *split( I18n.get( "cli.options.prompt.review", I18n.get( "cli.values.true" ), "submit" ) ) ) { |review| opts.review = review }
143
+ parser.on( "-g", "--[no-]autogen", *split( I18n.get( "cli.options.prompt.autogen", I18n.get( "cli.values.false" ), "review" ) ) ) { |autogen| opts.prompt_autogen = autogen }
144
+ parser.on( "-n", "--[no-]new", *split( I18n.get( "cli.options.prompt.nolyrics", I18n.get( "cli.values.false" ), "review" ) ) ) { |prompt_no_lyrics| opts.prompt_no_lyrics = prompt_no_lyrics }
145
+
146
+ parser.separator ""
147
+ parser.on( "-x", "--proxy [PROXY]", *split( I18n.get( "cli.options.proxy" ) ) ) { |proxy| opts.proxy = proxy }
148
+
149
+ parser.separator ""
150
+ parser.on( "-k", "--toolkits [TK1,TK2...]", Array, *split( I18n.get( "cli.options.toolkits", TOOLKITS_DEFAULT.join( "," ) ) ) ) { |toolkits| opts.toolkits = toolkits ? toolkits : [] }
151
+
152
+ parser.separator ""
153
+ parser.on_tail( "-h", "--help", *split( I18n.get( "cli.options.help" ) ) ) { puts parser; exit }
154
+ parser.on_tail( "-v", "--version", *split( I18n.get( "cli.options.version" ) ) ) { puts "#{WIKILYRICS_VERSION}"; exit }
155
+ end
156
+
157
+ begin
158
+
159
+ parser.parse!( args )
160
+
161
+ raise ArgumentError, I18n.get( "cli.error.missingoption", "--artist" ) if ! opts.artist && ! opts.batch_file
162
+ raise ArgumentError, I18n.get( "cli.error.missingoption", "--title" ) if ! opts.title && ! opts.batch_file
163
+
164
+ raise ArgumentError, I18n.get( "cli.error.missingoption", "--username" ) if opts.submit && ! opts.username
165
+ raise ArgumentError, I18n.get( "cli.error.missingoption", "--password" ) if opts.submit && ! opts.password
166
+
167
+ if opts.batch_file && (opts.artist || opts.title || opts.album || opts.year)
168
+ raise ArgumentError, I18n.get( "cli.error.incompatibleoptions", "-b", "-a/-t/-l/-y" )
169
+ end
170
+
171
+ if opts.prompt_autogen && ( ! opts.submit || ! opts.review )
172
+ raise ArgumentError, I18n.get( "cli.error.missingdependency", "-g", "-r" )
173
+ end
174
+
175
+ if opts.prompt_no_lyrics && ( ! opts.submit || ! opts.review )
176
+ raise ArgumentError, I18n.get( "cli.error.missingdependency", "-n", "-r" )
177
+ end
178
+
179
+ opts.toolkits.each() do |toolkit|
180
+ if ! TOOLKITS_DEFAULT.include?( toolkit )
181
+ raise ArgumentError, I18n.get( "cli.error.invalidoptionvalue", "toolkit", toolkit )
182
+ end
183
+ end
184
+
185
+ if opts.submit && opts.review && opts.toolkits.empty?
186
+ raise ArgumentError, I18n.get( "cli.error.notoolkit" )
187
+ end
188
+
189
+ if opts.submit
190
+ if ! ["Lyriki","LyrikiLocal","LyricWiki"].include?( opts.submit )
191
+ raise ArgumentError, I18n.get( "cli.error.invalidoptionvalue", "submit", opts.submit )
192
+ end
193
+ opts.sites = [] if ! opts.sites
194
+ opts.sites << opts.submit
195
+ end
196
+
197
+ if ! opts.sites || opts.sites.empty?
198
+ raise ArgumentError, I18n.get( "cli.error.nosite" )
199
+ else
200
+ found_plugins = Plugins.find_plugins()
201
+ opts.sites.uniq!()
202
+ opts.sites.each() do |site|
203
+ if ! found_plugins.include?( site )
204
+ raise ArgumentError, I18n.get( "cli.error.invalidoptionvalue", "site", site )
205
+ end
206
+ end
207
+ end
208
+
209
+ if opts.proxy
210
+ begin
211
+ # TODO is this correct?
212
+ opts.proxy = nil if URI.parse( opts.proxy ).to_s() != ""
213
+ rescue Exception
214
+ raise ArgumentError, I18n.get( "cli.error.invalidoptionvalue", "proxy", opts.proxy )
215
+ end
216
+ end
217
+
218
+ return opts
219
+
220
+ rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption, ArgumentError => ex
221
+ puts ex.is_a?( ArgumentError ) ? "error: #{ex}" : ex
222
+ puts parser
223
+ exit 1
224
+ end
225
+
226
+ end
227
+
228
+ end