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,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