lyrics 0.0.2

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 (50) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +17 -0
  5. data/Rakefile +45 -0
  6. data/VERSION +1 -0
  7. data/bin/lyrics +66 -0
  8. data/lib/lyrics.rb +4 -0
  9. data/lib/lyrics/cli/application.rb +99 -0
  10. data/lib/lyrics/cli/optionsparser.rb +228 -0
  11. data/lib/lyrics/cli/pluginadapter.rb +56 -0
  12. data/lib/lyrics/cli/plugins.rb +79 -0
  13. data/lib/lyrics/cli/wikipluginadapter.rb +139 -0
  14. data/lib/lyrics/i18n/README +1 -0
  15. data/lib/lyrics/i18n/en.rb +181 -0
  16. data/lib/lyrics/i18n/es.rb +181 -0
  17. data/lib/lyrics/i18n/i18n.rb +126 -0
  18. data/lib/lyrics/i18n/sk.rb +174 -0
  19. data/lib/lyrics/itrans/COPYRIGHT +31 -0
  20. data/lib/lyrics/itrans/itrans +0 -0
  21. data/lib/lyrics/itrans/itrans.txt +8 -0
  22. data/lib/lyrics/itrans/lyric.txt +23 -0
  23. data/lib/lyrics/itrans/udvng.ifm +206 -0
  24. data/lib/lyrics/lyrics.rb +567 -0
  25. data/lib/lyrics/lyrics_AZLyrics.rb +113 -0
  26. data/lib/lyrics/lyrics_DarkLyrics.rb +124 -0
  27. data/lib/lyrics/lyrics_Giitaayan.rb +124 -0
  28. data/lib/lyrics/lyrics_Jamendo.rb +166 -0
  29. data/lib/lyrics/lyrics_LeosLyrics.rb +142 -0
  30. data/lib/lyrics/lyrics_LoudSongs.rb +135 -0
  31. data/lib/lyrics/lyrics_LyricWiki.rb +328 -0
  32. data/lib/lyrics/lyrics_LyricsDownload.rb +118 -0
  33. data/lib/lyrics/lyrics_LyricsMania.rb +141 -0
  34. data/lib/lyrics/lyrics_Lyriki.rb +286 -0
  35. data/lib/lyrics/lyrics_SeekLyrics.rb +108 -0
  36. data/lib/lyrics/lyrics_Sing365.rb +103 -0
  37. data/lib/lyrics/lyrics_TerraLetras.rb +126 -0
  38. data/lib/lyrics/mediawikilyrics.rb +1417 -0
  39. data/lib/lyrics/utils/formdata.rb +56 -0
  40. data/lib/lyrics/utils/htmlentities.rb +291 -0
  41. data/lib/lyrics/utils/http.rb +198 -0
  42. data/lib/lyrics/utils/itrans.rb +160 -0
  43. data/lib/lyrics/utils/logger.rb +123 -0
  44. data/lib/lyrics/utils/strings.rb +378 -0
  45. data/lib/lyrics/utils/xmlhash.rb +111 -0
  46. data/lyrics.gemspec +98 -0
  47. data/spec/lyrics_spec.rb +7 -0
  48. data/spec/spec.opts +1 -0
  49. data/spec/spec_helper.rb +9 -0
  50. metadata +137 -0
@@ -0,0 +1,56 @@
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 "cgi"
20
+
21
+ module PluginAdapter
22
+
23
+ # Hack to make module methods become class methods when the module gets included
24
+ def PluginAdapter.included( including )
25
+ if including.is_a?( Class )
26
+ including.extend( ClassMethods ) # adds class methods
27
+ else # if including.is_a?( Module )
28
+ including::ClassMethods.append_class_methods( self )
29
+ end
30
+ end
31
+
32
+ # Methods under this module will became class methods when the module gets included
33
+ # Note: don't use def self.<method name> but just <method name>
34
+ module ClassMethods
35
+ def ClassMethods.append_class_methods( mod )
36
+ include mod::ClassMethods
37
+ end
38
+
39
+ def plugin_name()
40
+ return site_name()
41
+ end
42
+
43
+ def notify( message )
44
+ puts plugin_name() + ": " + message.gsub( /\/?<[^>]+>/, "" )
45
+ end
46
+ end
47
+
48
+ def plugin_name()
49
+ return self.class.plugin_name()
50
+ end
51
+
52
+ def notify( message )
53
+ self.class.notify( message )
54
+ end
55
+
56
+ end
@@ -0,0 +1,79 @@
1
+ # Copyright (C) 2007 by Sergio Pistone
2
+ # sergio_pistone@yahoo.com.ar
3
+ #
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program; if not, write to the
16
+ # Free Software Foundation, Inc.,
17
+ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
+
19
+ require File.expand_path( File.dirname( __FILE__ ) + "/../mediawikilyrics" )
20
+ require File.expand_path( File.dirname( __FILE__ ) + "/pluginadapter" )
21
+ require File.expand_path( File.dirname( __FILE__ ) + "/wikipluginadapter" )
22
+
23
+ module Plugins
24
+
25
+ @@ALL = []
26
+ @@WIKI = []
27
+
28
+ def Plugins.find_plugins()
29
+ plugins = {}
30
+ Dir.new( File.expand_path( File.dirname( __FILE__ ) + "/.." ) ).each() do |filename|
31
+ filename = File.expand_path( File.dirname( __FILE__ ) + "/../" + filename )
32
+ if File.file?( filename ) && (md = /\/lyrics_([A-Za-z_0-9]*)\.rb$/.match( filename ))
33
+ plugins[md[1]] = filename
34
+ end
35
+ end
36
+ return plugins
37
+ end
38
+
39
+ def Plugins.load_plugins( plugins )
40
+ plugins.each() do |classname, filename|
41
+ require( filename ? filename : File.expand_path( File.dirname( __FILE__ ) + "/../lyrics_#{classname}.rb" ) )
42
+ classobj = eval( classname )
43
+ if classobj.ancestors().include?( MediaWikiLyrics )
44
+ eval( "class CLI#{classname} < #{classname}\ninclude WikiPluginAdapter\nend" ) # FIXME: refactor
45
+ plugin = eval( "CLI#{classname}.new()" )
46
+ @@WIKI << plugin
47
+ else
48
+ eval( "class CLI#{classname} < #{classname}\ninclude PluginAdapter\nend" ) # FIXME: refactor
49
+ plugin = eval( "CLI#{classname}.new()" )
50
+ end
51
+ @@ALL << plugin
52
+ end
53
+ end
54
+
55
+
56
+ def Plugins.all_plugins()
57
+ return @@ALL
58
+ end
59
+
60
+ def Plugins.all_names()
61
+ return @@ALL.collect(){ |plugin| plugin.plugin_name() }
62
+ end
63
+
64
+ def Plugins.wiki_plugins()
65
+ return @@WIKI
66
+ end
67
+
68
+ def Plugins.wiki_names()
69
+ return @@WIKI.collect(){ |plugin| plugin.plugin_name() }
70
+ end
71
+
72
+ def Plugins.plugin_by_name( name )
73
+ @@ALL.each() do |plugin|
74
+ return plugin if plugin.plugin_name() == name
75
+ end
76
+ return nil
77
+ end
78
+
79
+ end
@@ -0,0 +1,139 @@
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__ ) + "/../i18n/i18n" )
21
+ require File.expand_path( File.dirname( __FILE__ ) + "/pluginadapter" )
22
+ require File.expand_path( File.dirname( __FILE__ ) + "/plugins" )
23
+
24
+ require "md5"
25
+ require "uri"
26
+
27
+ module WikiPluginAdapter
28
+
29
+ # Hack to make module methods become class methods when the module gets included
30
+ def WikiPluginAdapter.included( including )
31
+ if including.is_a?( Class )
32
+ including.extend( ClassMethods ) # adds class methods
33
+ else # including.is_a?( Module )
34
+ including::ClassMethods.append_class_methods( self )
35
+ end
36
+ end
37
+
38
+ # Methods under this module will became class methods when the module gets included
39
+ # Note: don't use def self.<method name> but just <method name>
40
+ module ClassMethods
41
+ def ClassMethods.append_class_methods( mod )
42
+ include mod::ClassMethods
43
+ end
44
+ end
45
+
46
+ include PluginAdapter
47
+
48
+ def submit?()
49
+ return @wpa_submit
50
+ end
51
+
52
+ def check_submit_conditions()
53
+ if @wpa_submit
54
+ login( @wpa_username, @wpa_password, false )
55
+ else
56
+ logout()
57
+ end
58
+
59
+ if ! logged_in?
60
+ @wpa_submit = false
61
+ end
62
+
63
+ if ! @wpa_submit || ! @wpa_review
64
+ @wpa_prompt_no_lyrics = false
65
+ @wpa_prompt_autogen = false
66
+ end
67
+ end
68
+
69
+ def set_submit_settings( username, password, review, prompt_autogen, prompt_no_lyrics )
70
+ @wpa_submit = true
71
+ @wpa_review = review
72
+ @wpa_prompt_autogen = prompt_autogen
73
+ @wpa_prompt_no_lyrics = prompt_no_lyrics
74
+ @wpa_username = username
75
+ @wpa_password = password
76
+ if ! @wpa_submit || ! @wpa_review
77
+ @wpa_prompt_no_lyrics = false
78
+ @wpa_prompt_autogen = false
79
+ end
80
+ end
81
+
82
+ # returns true if the review contents page is shown to the user (which can only happen when there was something to submit)
83
+ def wiki_process_response( response, response_plugin, wiki_searched )
84
+
85
+ return false if ! submit?() || ! authorized?
86
+
87
+ lyrics_found_on_site = response.lyrics && response_plugin == self
88
+ lyrics_autogenerated = lyrics_found_on_site && ! response.custom_data["reviewed"]
89
+
90
+ return false if lyrics_found_on_site && ! lyrics_autogenerated # we have nothing to do
91
+ return false if (! @wpa_prompt_autogen && lyrics_autogenerated) || (! @wpa_prompt_no_lyrics && ! response.lyrics)
92
+
93
+ begin
94
+
95
+ check_submit_conditions()
96
+
97
+ song_data = MediaWikiLyrics::SongData.new(
98
+ response.artist ? response.artist : response.request.artist,
99
+ response.title ? response.title : response.request.title,
100
+ response.lyrics,
101
+ response.album ? response.album : response.request.album,
102
+ response.year ? response.year : response.request.year,
103
+ response.custom_data["credits"],
104
+ response.custom_data["lyricist"]
105
+ )
106
+
107
+ submitted_url, submitted_data = submit_song_page(
108
+ song_data,
109
+ lyrics_autogenerated ? response.url : nil, # are we editing an existing page or creating a new one?
110
+ song_data.artist == response.request.artist && song_data.title == response.request.title &&
111
+ wiki_searched && ! lyrics_found_on_site, # do we KNOW FOR SURE the page doesn't exists?
112
+ @wpa_review || lyrics_autogenerated, # should we show the review contents dialog?
113
+ lyrics_autogenerated # should user be forced to review contents? (true causes the operation to abort otherwise)
114
+ )
115
+
116
+ # transfer summited data to response
117
+ if submitted_data
118
+ response.artist = submitted_data["artist"] if ! Strings.empty?( submitted_data["artist"] )
119
+ response.title = submitted_data["title"] if ! Strings.empty?( submitted_data["title"] )
120
+ response.album = submitted_data["album"] if ! Strings.empty?( submitted_data["album"] )
121
+ response.year = submitted_data["year"] if ! Strings.empty?( submitted_data["year"] )
122
+ response.lyrics = submitted_data["lyrics"] if ! Strings.empty?( submitted_data["lyrics"] )
123
+ custom_data = {}
124
+ custom_data.merge( response.custom_data )
125
+ custom_data["credits"] = submitted_data["credits"] if ! Strings.empty?( submitted_data["credits"] )
126
+ custom_data["lyricst"] = submitted_data["lyricst"] if ! Strings.empty?( submitted_data["lyricst"] )
127
+ response.custom_data = custom_data
128
+ end
129
+
130
+ return (@wpa_review || lyrics_autogenerated) && submitted_data
131
+
132
+ rescue TimeoutError
133
+ notify( I18n.get( "cli.application.plugintimeout", plugin_name(), site_host() ) )
134
+ return false
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -0,0 +1 @@
1
+ IMPORTANT: save all language files with UTF-8 encoding
@@ -0,0 +1,181 @@
1
+ cli.usage = Usage: %1 [OPTIONS]
2
+ cli.description = Fetch lyrics from various sites and/or submit lyrics to Lyriki and LyricWiki.
3
+ cli.values.true = true
4
+ cli.values.false = false
5
+ cli.options = Options:
6
+ cli.options.artist = Song artist (mandatory unless %1 specified).
7
+ cli.options.title = Song title (mandatory unless %1 specified).
8
+ cli.options.album = Song album.
9
+ cli.options.year = Song album year.
10
+ cli.options.featfix = Fix artist/title when the later has "feat. ARTIST" (%1 by default).
11
+ cli.options.batchfile = Batch process file (expects artist;title;album;year entries in each line).
12
+ cli.options.cleanup = Cleanup fetched lyrics (%1 by default).
13
+ cli.options.sites = Sites to search lyrics for, order included (%1 by default; see %2).
14
+ cli.options.sites.list = List available sites.
15
+ cli.options.sites.list.available = Available sites:
16
+ cli.options.submit = Wiki site to submit content to (needs %1 and %2).
17
+ cli.options.username = Username to login with (mandatory when %1 specified).
18
+ cli.options.password = Password to login with (mandatory when %1 specified).
19
+ cli.options.persist = Restore/save session from/to file (needs %1 and %2).
20
+ cli.options.prompt.review = Prompt for review before submitting content (%1 by default, needs %2).
21
+ cli.options.prompt.autogen = Prompt for review of autogenerated pages (%1 by default, needs %2).
22
+ cli.options.prompt.nolyrics = Prompt for submission even when no lyrics to submit where found (%1 by default, needs %2).
23
+ cli.options.proxy = Proxy server URL.
24
+ cli.options.toolkits = GUI toolkits priority. Loading falls back to the next toolkit when one fails; an empty list will cause no dialog to be shown and lyrics to be dumped to stdout (defaults to %1).
25
+ cli.options.help = Show this message and exit.
26
+ cli.options.version = Show version and exit.
27
+ cli.error.missingoption = missing %1
28
+ cli.error.missingdependency = %1 requires %1
29
+ cli.error.incompatibleoptions = %1 is incompatible with %2
30
+ cli.error.invalidoptionvalue = invalid %1 value: %2
31
+ cli.error.nosite = must provide at least one site
32
+ cli.error.notoolkit = must provide at least one toolkit to use review mode
33
+
34
+ cli.application.searchinglyrics = searching lyrics for %1 by %2...
35
+ cli.application.lyricsfound = lyrics for %1 by %2 found at %3
36
+ cli.application.nolyricsfound = no lyrics found for %1 by %2
37
+ cli.application.plugintimeout = %1 request has timed out, site %2 is probably down
38
+ cli.application.batchmode = operating in batch mode
39
+ cli.application.processedcount = %1 files processed
40
+
41
+ amarok.application.error.connectionrefused = Can't connect to the Internet (check your proxy settings)
42
+ amarok.application.error.connectiondown = The connection is down, exiting
43
+ amarok.application.error.notoolkit = Sorry...\nYou need one of QtRuby, RubyGTK or TkRuby to run this program
44
+ amarok.application.error.nopluginsselected = No sites to search lyrics for specified
45
+ amarok.application.search.current = Search current song lyrics
46
+ amarok.application.search.current.nosongplaying = no song currently playing
47
+ amarok.application.search.selected = Search selected song lyrics
48
+ amarok.application.search.noinfofound = no song info found in Amarok database
49
+ amarok.application.search.nolyricsfound = no lyrics found for <b>%1</b> by <b>%2</b>
50
+ amarok.application.search.plugintimeout = %1 request has timed out! Site %2 is probably down
51
+ amarok.application.clearlyricscache = Clear lyrics cache
52
+ amarok.application.clearlyricscache.confirm = Are you sure you want to clear the lyrics cache?
53
+ amarok.application.clearlyricscache.done = lyrics cache cleared
54
+
55
+ amarok.wikiplugin.checksong = Check/Submit song page
56
+ amarok.wikiplugin.checksong.noinfofound = no song info found in Amarok database
57
+ amarok.wikiplugin.checkalbum = Check/Submit album page
58
+ amarok.wikiplugin.checkalbum.noinfofound = no album info found in Amarok database
59
+ amarok.wikiplugin.uploadcover = Upload album cover
60
+ amarok.wikiplugin.uploadcover.invalidalbumparams = invalid album params received
61
+ amarok.wikiplugin.uploadcover.noimagepath = no cover image received
62
+ amarok.wikiplugin.uploadcover.searching = searching album cover for <b>%1</b> by <b>%2</b>...
63
+ amarok.wikiplugin.uploadcover.found = album cover found (no need to upload)
64
+ amarok.wikiplugin.submitcontent = Submit contents
65
+
66
+ gui.common.cut = Cut
67
+ gui.common.copy = Copy
68
+ gui.common.paste = Paste
69
+ gui.common.delete = Delete
70
+ gui.common.selectall = Select All
71
+ gui.common.undo = Undo
72
+ gui.common.redo = Redo
73
+
74
+ gui.common.accept = Accept
75
+ gui.common.cancel = Cancel
76
+ gui.common.submit = Submit
77
+ gui.common.load = Load
78
+ gui.common.fix = Fix
79
+ gui.common.url = URL
80
+ gui.common.artist = Artist
81
+ gui.common.song = Song
82
+ gui.common.album = Album
83
+ gui.common.year = Year
84
+ gui.common.month = Month
85
+ gui.common.day = Day
86
+ gui.common.released = Released
87
+ gui.common.credits = Credits
88
+ gui.common.lyricist = Lyricist
89
+ gui.common.image = Image
90
+ gui.common.reviewed = I have reviewed the contents of this form
91
+
92
+ gui.searchlyrics.title = Search lyrics
93
+ gui.searchlyrics.search = Search Settings
94
+
95
+ gui.lyrics.title = Lyrics to %1 by %2
96
+
97
+ gui.pluginsmanager.title = %1 script configuration
98
+ gui.pluginsmanager.sites = Sites
99
+ gui.pluginsmanager.sites.inuse = Currently used
100
+ gui.pluginsmanager.sites.available = Available
101
+ gui.pluginsmanager.sites.moveup = Move Up
102
+ gui.pluginsmanager.sites.movedown = Move Down
103
+ gui.pluginsmanager.sites.add = << Add
104
+ gui.pluginsmanager.sites.remove = >> Remove
105
+ gui.pluginsmanager.misc = Miscellaneous
106
+ gui.pluginsmanager.misc.cleanup = Clean up retrieved lyrics
107
+ gui.pluginsmanager.misc.singlethreaded = Avoid using multiple threads to save battery (needs restart)
108
+ gui.pluginsmanager.misc.writelog = Write log to %1
109
+
110
+ gui.wikiplugin.title = Configure %1 settings
111
+ gui.wikiplugin.general = General Settings
112
+ gui.wikiplugin.general.submit = Submit contents to %1
113
+ gui.wikiplugin.general.review = Prompt for review before submitting contents
114
+ gui.wikiplugin.general.autogen = Review song pages marked as auto-generated
115
+ gui.wikiplugin.general.nolyrics = Show submit dialog even if no lyrics were found
116
+ gui.wikiplugin.login = Login Settings
117
+ gui.wikiplugin.login.username = Username
118
+ gui.wikiplugin.login.password = Password
119
+
120
+ gui.submitsong.title.submit = %1 - Submit song page
121
+ gui.submitsong.title.edit = %1 - Review song page
122
+ gui.submitsong.instrumental = Song is instrumental
123
+
124
+ gui.submitalbum.title = %1 - Submit album page
125
+ gui.submitalbum.coverfound = (cover found, no need to upload)
126
+
127
+ gui.uploadcover.title = %1 - Upload album cover
128
+ gui.uploadcover.imagepath = Path
129
+ gui.uploadcover.browseimage.title = Select album cover image path
130
+ gui.uploadcover.browseimage.images = Images
131
+ gui.uploadcover.browseimage.allfiles = All Files
132
+
133
+ gui.fixpages.success = Submitted page %1
134
+ gui.fixpages.error = Error submitting page %1
135
+
136
+ wiki.control.versionblocked = <b>Version %1 has been blocked</b> from submitting content. Please, update to the last version.
137
+ wiki.control.userblocked = <b>User %1 has been blocked</b> from submitting content. Please, check your user page.
138
+ wiki.control.updated = A new version of the script has been released. <b>Please, update to version %1</b>.
139
+
140
+ wiki.login.attempt = starting session for user <b>%1</b>...
141
+ wiki.login.success = session started successfully for user <b>%1</b>
142
+ wiki.login.error = error starting session for user <b>%1</b>
143
+ wiki.logout = session finished for user <b>%1</b>
144
+
145
+ wiki.session.save.success = session saved for user <b>%1</b>
146
+ wiki.session.save.error.notloggedin = can't save session before logging in
147
+ wiki.session.save.error = there was an error saving the session for user <b>%1</b>
148
+ wiki.session.restore.success = session restored for user <b>%1</b>
149
+ wiki.session.restore.error = there was an error restoring the session for user <b>%1</b>
150
+ wiki.session.restore.notfound = no saved session found
151
+
152
+ wiki.submitsong.searchingpage = searching song page for <b>%1</b> by <b>%2</b>...
153
+ wiki.submitsong.pagefound = song page found for <b>%1</b> by <b>%2</b>
154
+ wiki.submitsong.pagefound.autogenerated = auto-generated song page found for <b>%1</b> by <b>%2</b>
155
+ wiki.submitsong.nopagefound = no song page found for <b>%1</b> by <b>%2</b>
156
+ wiki.submitsong.cancelled = song page submission cancelled by user
157
+ wiki.submitsong.mustreviewcontent = contents were not reviewed, submission cancelled
158
+ wiki.submitsong.success = successfully submitted song page for <b>%1</b> by <b>%2</b>
159
+ wiki.submitsong.error.invalidsong = invalid song title received
160
+ wiki.submitsong.error.invalidartist = invalid album artist received
161
+ wiki.submitsong.error.nolyrics = no lyrics to submit received
162
+ wiki.submitsong.error = there was an error submitting the song page for <b>%1</b> by <b>%2</b>
163
+
164
+ wiki.submitalbum.searchingpage = searching album page for <b>%1</b> by <b>%2</b>...
165
+ wiki.submitalbum.pagefound = found album page for <b>%1</b> by <b>%2</b>
166
+ wiki.submitalbum.nopagefound = no album page found for <b>%1</b> by <b>%2</b>
167
+ wiki.submitalbum.cancelled = album page submission cancelled by user
168
+ wiki.submitalbum.mustreviewcontent = contents were not reviewed, submission cancelled
169
+ wiki.submitalbum.success = successfully submitted album page for <b>%1</b> by <b>%2</b>
170
+ wiki.submitalbum.error.invalidyear = invalid album year received
171
+ wiki.submitalbum.error.invalidalbum = invalid album name received
172
+ wiki.submitalbum.error.invalidartist = invalid album artist received
173
+ wiki.submitalbum.error = there was an error submitting the album page for <b>%1</b> by <b>%2</b>
174
+
175
+ wiki.submitredirect.success = submitted redirect page to %1
176
+ wiki.submitredirect.error = there was an error submitting the redirect page to %1
177
+
178
+ wiki.uploadcover.uploading = uploading album cover for <b>%1</b> by <b>%2</b>
179
+ wiki.uploadcover.success = successfully uploaded album cover for <b>%1</b> by <b>%2</b>
180
+ wiki.uploadcover.error.convert = there was an error converting the album cover to JPEG format
181
+ wiki.uploadcover.error = there was an error uploading the album cover for <b>%1</b> by <b>%2</b>