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.
- data/LICENSE +340 -0
- data/README +46 -0
- data/bin/lyrics-ebook +47 -0
- data/lib/eeepub/LICENSE +20 -0
- data/lib/eeepub/README.md +77 -0
- data/lib/eeepub/Rakefile +49 -0
- data/lib/eeepub/VERSION +1 -0
- data/lib/eeepub/examples/files/bar.html +42 -0
- data/lib/eeepub/examples/files/foo.html +42 -0
- data/lib/eeepub/examples/simple_epub.rb +25 -0
- data/lib/eeepub/lib/eeepub.rb +17 -0
- data/lib/eeepub/lib/eeepub/container_item.rb +108 -0
- data/lib/eeepub/lib/eeepub/easy.rb +100 -0
- data/lib/eeepub/lib/eeepub/maker.rb +127 -0
- data/lib/eeepub/lib/eeepub/ncx.rb +68 -0
- data/lib/eeepub/lib/eeepub/ocf.rb +112 -0
- data/lib/eeepub/lib/eeepub/opf.rb +148 -0
- data/lib/eeepub/spec/eeepub/easy_spec.rb +66 -0
- data/lib/eeepub/spec/eeepub/maker_spec.rb +124 -0
- data/lib/eeepub/spec/eeepub/ncx_spec.rb +80 -0
- data/lib/eeepub/spec/eeepub/ocf_spec.rb +43 -0
- data/lib/eeepub/spec/eeepub/opf_spec.rb +262 -0
- data/lib/eeepub/spec/eeepub_spec.rb +4 -0
- data/lib/eeepub/spec/spec_helper.rb +12 -0
- data/lib/lyrics_ebook.rb +71 -0
- data/lib/lyrics_ebook/cache2html.rb +33 -0
- data/lib/lyrics_ebook/cache_manager.rb +77 -0
- data/lib/lyrics_ebook/lyric.rb +32 -0
- data/lib/lyrics_ebook/lyric_download.rb +50 -0
- data/lib/lyrics_ebook/lyrics2html.rb +106 -0
- data/lib/lyrics_ebook/mini_lyrics_parser.rb +26 -0
- data/lib/lyrics_ebook/mp3_parser.rb +37 -0
- data/lib/wiki_lyrics/amarok/COPYING +340 -0
- data/lib/wiki_lyrics/amarok/README +51 -0
- data/lib/wiki_lyrics/amarok/amarok.rb +355 -0
- data/lib/wiki_lyrics/amarok/pluginadapter.rb +113 -0
- data/lib/wiki_lyrics/amarok/plugins.rb +95 -0
- data/lib/wiki_lyrics/amarok/wikilyrics.rb +578 -0
- data/lib/wiki_lyrics/amarok/wikilyrics.spec +4 -0
- data/lib/wiki_lyrics/amarok/wikipluginadapter.rb +392 -0
- data/lib/wiki_lyrics/cli/optionsparser.rb +228 -0
- data/lib/wiki_lyrics/cli/pluginadapter.rb +56 -0
- data/lib/wiki_lyrics/cli/plugins.rb +79 -0
- data/lib/wiki_lyrics/cli/wikilyrics.rb +178 -0
- data/lib/wiki_lyrics/cli/wikipluginadapter.rb +140 -0
- data/lib/wiki_lyrics/docs/COPYING +340 -0
- data/lib/wiki_lyrics/docs/ChangeLog +293 -0
- data/lib/wiki_lyrics/docs/HOWTO.pdf +0 -0
- data/lib/wiki_lyrics/docs/HOWTO.tex +151 -0
- data/lib/wiki_lyrics/docs/HOWTO.txt +139 -0
- data/lib/wiki_lyrics/docs/README +45 -0
- data/lib/wiki_lyrics/docs/TODO +12 -0
- data/lib/wiki_lyrics/gui/gui-gtk.rb +945 -0
- data/lib/wiki_lyrics/gui/gui-qt3.rb +785 -0
- data/lib/wiki_lyrics/gui/gui-qt4.rb +845 -0
- data/lib/wiki_lyrics/gui/gui-tk.rb +1104 -0
- data/lib/wiki_lyrics/gui/gui.rb +268 -0
- data/lib/wiki_lyrics/gui/test.rb +74 -0
- data/lib/wiki_lyrics/i18n/README +1 -0
- data/lib/wiki_lyrics/i18n/en.rb +181 -0
- data/lib/wiki_lyrics/i18n/es.rb +181 -0
- data/lib/wiki_lyrics/i18n/i18n.rb +126 -0
- data/lib/wiki_lyrics/i18n/sk.rb +174 -0
- data/lib/wiki_lyrics/itrans/COPYRIGHT +31 -0
- data/lib/wiki_lyrics/itrans/itrans +0 -0
- data/lib/wiki_lyrics/itrans/itrans.txt +8 -0
- data/lib/wiki_lyrics/itrans/lyric.txt +23 -0
- data/lib/wiki_lyrics/itrans/udvng.ifm +206 -0
- data/lib/wiki_lyrics/lyrics.rb +567 -0
- data/lib/wiki_lyrics/lyrics_AZLyrics.rb +113 -0
- data/lib/wiki_lyrics/lyrics_DarkLyrics.rb +124 -0
- data/lib/wiki_lyrics/lyrics_Giitaayan.rb +124 -0
- data/lib/wiki_lyrics/lyrics_Jamendo.rb +166 -0
- data/lib/wiki_lyrics/lyrics_LeosLyrics.rb +142 -0
- data/lib/wiki_lyrics/lyrics_LoudSongs.rb +135 -0
- data/lib/wiki_lyrics/lyrics_LyricWiki.rb +329 -0
- data/lib/wiki_lyrics/lyrics_LyricsDownload.rb +118 -0
- data/lib/wiki_lyrics/lyrics_LyricsMania.rb +141 -0
- data/lib/wiki_lyrics/lyrics_Lyriki.rb +287 -0
- data/lib/wiki_lyrics/lyrics_SeekLyrics.rb +108 -0
- data/lib/wiki_lyrics/lyrics_Sing365.rb +103 -0
- data/lib/wiki_lyrics/lyrics_TerraLetras.rb +126 -0
- data/lib/wiki_lyrics/mediawikilyrics.rb +1464 -0
- data/lib/wiki_lyrics/tests/plugin_tests.rb +161 -0
- data/lib/wiki_lyrics/tests/tests.rb +74 -0
- data/lib/wiki_lyrics/utils/formdata.rb +56 -0
- data/lib/wiki_lyrics/utils/htmlentities.rb +291 -0
- data/lib/wiki_lyrics/utils/http.rb +198 -0
- data/lib/wiki_lyrics/utils/itrans.rb +160 -0
- data/lib/wiki_lyrics/utils/kde.rb +88 -0
- data/lib/wiki_lyrics/utils/logger.rb +123 -0
- data/lib/wiki_lyrics/utils/strings.rb +378 -0
- data/lib/wiki_lyrics/utils/xmlhash.rb +111 -0
- data/lib/wiki_lyrics/wikilyrics.kdevelop +152 -0
- data/lib/wiki_lyrics/wikilyrics.kdevses +18 -0
- data/lib/wiki_lyrics/win/gtk_fix.bat +3 -0
- data/lib/wiki_lyrics/win/tk_fix.bat +3 -0
- data/lib/wiki_lyrics/win/wikilyrics.bat +4 -0
- data/lib/wiki_lyrics/win/win_fix.rb +52 -0
- data/templates/art_.erb.xhtml +29 -0
- data/templates/artists.erb.xhtml +19 -0
- data/templates/cover.erb.xhtml +22 -0
- data/test/cache_manager_test.rb +73 -0
- data/test/data/artist name/title name.lyric +6 -0
- data/test/lyric_test.rb +41 -0
- metadata +194 -0
|
@@ -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
|