lyrics-ebook 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,378 @@
|
|
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__ ) + "/htmlentities" )
|
20
|
+
|
21
|
+
require "cgi"
|
22
|
+
|
23
|
+
$KCODE="u" # unicode support
|
24
|
+
|
25
|
+
module Strings
|
26
|
+
|
27
|
+
@@word_separators = " \t\n()[],.;:-¿?¡!\"/\\"
|
28
|
+
|
29
|
+
def Strings.empty?( text )
|
30
|
+
text = text.to_s()
|
31
|
+
return text.empty? ? true : text.strip.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def Strings.shell_quote( text )
|
35
|
+
return "\"" + text.gsub( "\\", "\\\\\\" ).gsub( "\"", "\\\"" ).gsub( "`", "\\\\`" ) + "\""
|
36
|
+
end
|
37
|
+
|
38
|
+
def Strings.shell_unquote( text )
|
39
|
+
if text.slice( 0, 1 ) == "\""
|
40
|
+
return text.gsub( "\\`", "`" ).gsub( "\\\"", "\"" ).slice( 1..-2 )
|
41
|
+
else # if text.slice( 0, 1 ) == "'"
|
42
|
+
return text.slice( 1..-2 )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def Strings.shell_escape( text )
|
47
|
+
return text.gsub( "\\", "\\\\\\" ).gsub( "\"", "\\\"" ).gsub( "`", "\\\\`" ).gsub( %q/'/, %q/\\\'/ ).gsub( " ", "\\ " )
|
48
|
+
end
|
49
|
+
|
50
|
+
def Strings.shell_unescape( text )
|
51
|
+
return text.gsub( "\\ ", " " ).gsub( "\\'", "'" ).gsub( "\\`", "`" ).gsub( "\\\"", "\"" )
|
52
|
+
end
|
53
|
+
|
54
|
+
def Strings.sql_quote( text )
|
55
|
+
return "'" + Strings.sql_escape( text ) + "'"
|
56
|
+
end
|
57
|
+
|
58
|
+
def Strings.sql_unquote( text )
|
59
|
+
return Strings.sql_unescape( text.slice( 1..-2 ) )
|
60
|
+
end
|
61
|
+
|
62
|
+
def Strings.sql_escape( text )
|
63
|
+
return text.gsub( "'", "''" )
|
64
|
+
end
|
65
|
+
|
66
|
+
def Strings.sql_unescape( text )
|
67
|
+
return text.gsub( "''", "'" )
|
68
|
+
end
|
69
|
+
|
70
|
+
def Strings.random_token( length=10 )
|
71
|
+
chars = ( "a".."z" ).to_a() + ( "0".."9" ).to_a()
|
72
|
+
token = ""
|
73
|
+
1.upto( length ) { |i| token << chars[rand(chars.size-1)] }
|
74
|
+
return token
|
75
|
+
end
|
76
|
+
|
77
|
+
def Strings.remove_invalid_filename_chars( filename )
|
78
|
+
return Strings.remove_invalid_filename_chars!( String.new( filename ) )
|
79
|
+
end
|
80
|
+
|
81
|
+
def Strings.remove_invalid_filename_chars!( filename )
|
82
|
+
filename.tr_s!( "*?:|/\\<>", "" )
|
83
|
+
return filename
|
84
|
+
end
|
85
|
+
|
86
|
+
def Strings.remove_vocal_accents( text )
|
87
|
+
return Strings.remove_vocal_accents!( String.new( text ) )
|
88
|
+
end
|
89
|
+
|
90
|
+
def Strings.remove_vocal_accents!( text )
|
91
|
+
text.gsub!( /á|à|ä|â|å|ã/, "a" )
|
92
|
+
text.gsub!( /Á|À|Ä|Â|Å|Ã/, "A" )
|
93
|
+
text.gsub!( /é|è|ë|ê/, "e" )
|
94
|
+
text.gsub!( /É|È|Ë|Ê/, "E" )
|
95
|
+
text.gsub!( /í|ì|ï|î/, "i" )
|
96
|
+
text.gsub!( /Í|Ì|Ï|Î/, "I" )
|
97
|
+
text.gsub!( /ó|ò|ö|ô/, "o" )
|
98
|
+
text.gsub!( /Ó|Ò|Ö|Ô/, "O" )
|
99
|
+
text.gsub!( /ú|ù|ü|û/, "u" )
|
100
|
+
text.gsub!( /Ú|Ù|Ü|Û/, "U" )
|
101
|
+
return text
|
102
|
+
end
|
103
|
+
|
104
|
+
def Strings.google_search_quote( text )
|
105
|
+
text = text.gsub( "\"", "" )
|
106
|
+
text.gsub!( /^\ *the\ */i, "" )
|
107
|
+
return Strings.empty?( text) ? "" : "\"#{text}\""
|
108
|
+
end
|
109
|
+
|
110
|
+
def Strings.build_google_feeling_lucky_url( query, site=nil )
|
111
|
+
url = "http://www.google.com/search?q=#{CGI.escape( query )}"
|
112
|
+
url += "+site%3A#{site}" if site
|
113
|
+
return url + "&btnI"
|
114
|
+
end
|
115
|
+
|
116
|
+
def Strings.downcase( text )
|
117
|
+
begin
|
118
|
+
return text.to_s().unpack( "U*" ).collect() do |c|
|
119
|
+
if c >= 65 && c <= 90 # abcdefghijklmnopqrstuvwxyz
|
120
|
+
c + 32
|
121
|
+
elsif c >= 192 && c <= 222 # ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ
|
122
|
+
c + 32
|
123
|
+
else
|
124
|
+
c
|
125
|
+
end
|
126
|
+
end.pack( "U*" )
|
127
|
+
rescue Exception # fallback to normal operation on error
|
128
|
+
return text.downcase()
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def Strings.downcase!( text )
|
133
|
+
return text.replace( Strings.downcase( text ) )
|
134
|
+
end
|
135
|
+
|
136
|
+
def Strings.upcase( text )
|
137
|
+
begin
|
138
|
+
return text.to_s().unpack( "U*" ).collect() do |c|
|
139
|
+
if c >= 97 && c <= 122 # ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
140
|
+
c - 32
|
141
|
+
elsif c >= 224 && c <= 254 # àáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþ
|
142
|
+
c - 32
|
143
|
+
else
|
144
|
+
c
|
145
|
+
end
|
146
|
+
end.pack( "U*" )
|
147
|
+
rescue Exception # fallback to normal operation on error
|
148
|
+
return text.upcase()
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def Strings.upcase!( text )
|
153
|
+
return text.replace( Strings.upcase( text ) )
|
154
|
+
end
|
155
|
+
|
156
|
+
def Strings.capitalize( text, downcase=false, first_only=false )
|
157
|
+
text = downcase ? Strings.downcase( text ) : text.to_s()
|
158
|
+
if first_only
|
159
|
+
text.sub!( /^([0-9a-zA-Zàáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ])/ ) {|c| Strings.upcase( c ) }
|
160
|
+
else
|
161
|
+
text.sub!( /([0-9a-zA-Zàáâãäåæçèéêëìíîïðñòóôõö×øùúûüýþÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞ])/ ) {|c| Strings.upcase( c ) }
|
162
|
+
end
|
163
|
+
return text
|
164
|
+
end
|
165
|
+
|
166
|
+
def Strings.capitalize!( text, downcase=false, first_only=false )
|
167
|
+
return text.replace( Strings.capitalize( text, downcase, first_only ) )
|
168
|
+
end
|
169
|
+
|
170
|
+
def Strings.titlecase( text, correct_case=true, downcase=false )
|
171
|
+
text = Strings.capitalize( text, downcase )
|
172
|
+
word_start = true
|
173
|
+
text = text.unpack( "U*" ).collect() do |c|
|
174
|
+
if word_start
|
175
|
+
chr = [c].pack( "U*" )
|
176
|
+
if ! @@word_separators.include?( chr )
|
177
|
+
word_start = false
|
178
|
+
c = Strings.upcase( chr ).unpack( "U*" )[0]
|
179
|
+
end
|
180
|
+
else
|
181
|
+
chr = c < 256 ? c.chr() : [c].pack( "U*" )
|
182
|
+
word_start = true if @@word_separators.include?( chr )
|
183
|
+
end
|
184
|
+
c
|
185
|
+
end.pack( "U*" )
|
186
|
+
if correct_case
|
187
|
+
lc_words = [
|
188
|
+
"the", "a", "an", # articles
|
189
|
+
"and", "but", "or", "nor", # conjunctions
|
190
|
+
"'n'", "'n", "n'", # and contractions
|
191
|
+
"as", "at", "by", "for", "in", "of", "on", "to", # short prepositions
|
192
|
+
#"from", "into", "onto", "with", "over" # not so short prepositions
|
193
|
+
"feat", "vs", # special words
|
194
|
+
]
|
195
|
+
lc_words.each() do |lc_word|
|
196
|
+
text.gsub!( /\ #{lc_word}([ ,;:\.-?!\"\/\\\)])/i, " #{lc_word}\\1" )
|
197
|
+
end
|
198
|
+
end
|
199
|
+
return text
|
200
|
+
end
|
201
|
+
|
202
|
+
def Strings.titlecase!( text, correct_case=true, downcase=false )
|
203
|
+
return text.replace( Strings.titlecase( text, correct_case, downcase ) )
|
204
|
+
end
|
205
|
+
|
206
|
+
def Strings.normalize( token )
|
207
|
+
token = Strings.downcase( token )
|
208
|
+
token.tr_s!( " \n\r\t.;:()[]", " " )
|
209
|
+
token.strip!()
|
210
|
+
token.gsub!( /`|´|’/, "'" )
|
211
|
+
token.gsub!( /''|«|»/, "\"" )
|
212
|
+
token.gsub!( /[&+]/, "and" )
|
213
|
+
token.gsub!( /\ ('n'|'n|n') /, " and " )
|
214
|
+
token.gsub!( /^the /, "" )
|
215
|
+
token.gsub!( /, the$/, "" )
|
216
|
+
return token
|
217
|
+
end
|
218
|
+
|
219
|
+
def Strings.normalize!( token )
|
220
|
+
return token.replace( Strings.normalize( token ) )
|
221
|
+
end
|
222
|
+
|
223
|
+
def Strings.decode_htmlentities!( var )
|
224
|
+
if var.is_a?( String )
|
225
|
+
HTMLEntities.decode!( var )
|
226
|
+
elsif var.is_a?( Hash )
|
227
|
+
var.each() { |key, value| decode_htmlentities!( value ) }
|
228
|
+
end
|
229
|
+
return var
|
230
|
+
end
|
231
|
+
|
232
|
+
def Strings.decode_htmlentities( var )
|
233
|
+
if var.is_a?( String )
|
234
|
+
return HTMLEntities.decode( var )
|
235
|
+
elsif var.is_a?( Hash )
|
236
|
+
ret = {}
|
237
|
+
var.each() do |key, value|
|
238
|
+
ret[key] = decode_htmlentities( value )
|
239
|
+
end
|
240
|
+
return ret
|
241
|
+
else
|
242
|
+
return var
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def Strings.cleanup_lyrics( lyrics )
|
247
|
+
|
248
|
+
lyrics = HTMLEntities.decode( lyrics )
|
249
|
+
|
250
|
+
prev_line = ""
|
251
|
+
lines = []
|
252
|
+
|
253
|
+
lyrics.split( /\r\n|\n|\r/ ).each do |line|
|
254
|
+
|
255
|
+
# remove unnecesary spaces
|
256
|
+
line.tr_s!( "\t ", " " )
|
257
|
+
line.strip!()
|
258
|
+
|
259
|
+
# quotes and double quotes
|
260
|
+
line.gsub!( /`|´|’|‘|’|/, "'" )
|
261
|
+
line.gsub!( /''|"|«|»|„|”||/, "\"" )
|
262
|
+
|
263
|
+
# suspensive points
|
264
|
+
line.gsub!( /…+/, "..." )
|
265
|
+
line.gsub!( /[,;]?\.{2,}/, "..." )
|
266
|
+
|
267
|
+
# add space after "?", "!", ",", ";", ":", ".", ")" and "]" if not present
|
268
|
+
line.gsub!( /([^\.]?[\?!,;:\.\)\]])([^ "'<])/, "\\1 \\2" )
|
269
|
+
|
270
|
+
# remove spaces after "¿", "¡", "(" and ")"
|
271
|
+
line.gsub!( /([¿¡\(\[]) /, "\\1" )
|
272
|
+
|
273
|
+
# remove spaces before "?", "!", ",", ";", ":", ".", ")" and "]"
|
274
|
+
line.gsub!( /\ ([\?!,;:\.\)\]])/, "\\1" )
|
275
|
+
|
276
|
+
# remove space after ... at the beginning of sentence
|
277
|
+
line.gsub!( /^\.\.\. /, "..." )
|
278
|
+
|
279
|
+
# remove single points at end of sentence
|
280
|
+
line.gsub!( /([^\.])\.$/, "\\1" )
|
281
|
+
|
282
|
+
# remove commas and semicolons at end of sentence
|
283
|
+
line.gsub!( /[,;]$/, "" )
|
284
|
+
|
285
|
+
# fix english I pronoun capitalization
|
286
|
+
line.gsub!( /([ "'\(\[])i([\ '",;:\.\?!\]\)]|$)/, "\\1I\\2" )
|
287
|
+
|
288
|
+
# remove spaces after " or ' at the begin of sentence of before them when at the end
|
289
|
+
line.sub!( /^(["']) /, "\\1" )
|
290
|
+
line.sub!( /\ (["'])$/, "\\1" )
|
291
|
+
|
292
|
+
# capitalize first alfabet character of the line
|
293
|
+
Strings.capitalize!( line )
|
294
|
+
|
295
|
+
# no more than one empty line at the time
|
296
|
+
if ! line.empty? || ! prev_line.empty?
|
297
|
+
lines << line
|
298
|
+
prev_line = line
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
if lines.length > 0 && lines[lines.length-1].empty?
|
303
|
+
lines.delete_at( lines.length-1 )
|
304
|
+
end
|
305
|
+
|
306
|
+
return lines.join( "\n" )
|
307
|
+
end
|
308
|
+
|
309
|
+
def Strings.cleanup_lyrics!( lyrics )
|
310
|
+
return lyrics.replace( Strings.cleanup_lyrics( lyrics ) )
|
311
|
+
end
|
312
|
+
|
313
|
+
def Strings.cleanup_artist( artist, title )
|
314
|
+
artist = artist.strip()
|
315
|
+
if artist != ""
|
316
|
+
if (md = /[ \(\[](ft\.|ft |feat\.|feat |featuring ) *([^\)\]]+)[\)\]]? *$/i.match( title.to_s() ))
|
317
|
+
artist << " feat. " << md[2]
|
318
|
+
else
|
319
|
+
artist.gsub!( /[ \(\[](ft\.|ft |feat\.|feat |featuring ) *([^\)\]]+)[\)\]]? *$/i, " feat. \\2" )
|
320
|
+
end
|
321
|
+
end
|
322
|
+
return artist
|
323
|
+
end
|
324
|
+
|
325
|
+
def Strings.cleanup_title( title )
|
326
|
+
title = title.gsub( /[ \(\[](ft\.|ft |feat\.|feat |featuring ) *([^\)\]]+)[\)\]]? *$/i, "" )
|
327
|
+
title.strip!()
|
328
|
+
return title
|
329
|
+
end
|
330
|
+
|
331
|
+
def Strings.utf82latin1( text )
|
332
|
+
begin
|
333
|
+
return text.unpack( "U*" ).pack( "C*" )
|
334
|
+
rescue Exception
|
335
|
+
$stderr << "warning: conversion from UTF-8 to Latin1 failed\n"
|
336
|
+
return text
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def Strings.latin12utf8( text )
|
341
|
+
begin
|
342
|
+
return text.unpack( "C*" ).pack( "U*" )
|
343
|
+
rescue Exception
|
344
|
+
$stderr << "warning: conversion from Latin1 to UTF-8 failed\n"
|
345
|
+
return text
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def Strings.scramble( text )
|
350
|
+
text = text.to_s()
|
351
|
+
2.times() do
|
352
|
+
chars = text.unpack( "U*" ).reverse()
|
353
|
+
chars.size.times() { |idx| chars[idx] = (chars[idx] + idx + 1) }
|
354
|
+
text = chars.collect() { |c| c.to_s }.join( ":" )
|
355
|
+
end
|
356
|
+
return text
|
357
|
+
end
|
358
|
+
|
359
|
+
def Strings.scramble!( text )
|
360
|
+
return text.replace( Strings.scramble( text ) )
|
361
|
+
end
|
362
|
+
|
363
|
+
def Strings.descramble( text )
|
364
|
+
text = text.to_s()
|
365
|
+
2.times() do
|
366
|
+
chars = text.split( ":" ).collect() { |c| c.to_i }
|
367
|
+
chars.size.times() { |idx| chars[idx] = (chars[idx] - idx - 1) }
|
368
|
+
text = chars.reverse().pack( "U*" )
|
369
|
+
end
|
370
|
+
return text
|
371
|
+
end
|
372
|
+
|
373
|
+
def Strings.descramble!( text )
|
374
|
+
return text.replace( Strings.descramble( text ) )
|
375
|
+
end
|
376
|
+
|
377
|
+
end
|
378
|
+
|
@@ -0,0 +1,111 @@
|
|
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 "rexml/document"
|
20
|
+
|
21
|
+
module XMLHash
|
22
|
+
|
23
|
+
def XMLHash.write( file, hash )
|
24
|
+
|
25
|
+
begin
|
26
|
+
read_file = nil
|
27
|
+
read_file = file.is_a?( File ) ? file : File.new( file, "r" )
|
28
|
+
root = REXML::Document.new( read_file ).root
|
29
|
+
rescue Exception
|
30
|
+
root = REXML::Document.new( "<?xml version='1.0' encoding='UTF-8' ?>" ).add_element( "settings" )
|
31
|
+
ensure
|
32
|
+
read_file.close() if read_file
|
33
|
+
end
|
34
|
+
|
35
|
+
begin
|
36
|
+
write_file = nil
|
37
|
+
if ( file.is_a?( File ) )
|
38
|
+
file.reopen( file.path, "w+" )
|
39
|
+
write_file = file
|
40
|
+
else
|
41
|
+
write_file = File.new( file, "w+" )
|
42
|
+
end
|
43
|
+
hash.each do |key, value|
|
44
|
+
element = root.elements[key]
|
45
|
+
element = root.add_element( key ) if ! element
|
46
|
+
element.text = value.is_a?( Array ) ? value.join( "\n" ) : value.to_s()
|
47
|
+
element.add_attribute( "type", value.class.name.downcase )
|
48
|
+
end
|
49
|
+
root.parent.write( write_file )
|
50
|
+
write_file.flush()
|
51
|
+
return true
|
52
|
+
rescue Exception => e
|
53
|
+
puts e
|
54
|
+
puts e.backtrace
|
55
|
+
return false
|
56
|
+
ensure
|
57
|
+
write_file.close() if write_file != file
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def XMLHash.read( file, hash, only_hash_keys=true )
|
63
|
+
|
64
|
+
begin
|
65
|
+
read_file = nil
|
66
|
+
read_file = file.is_a?( File ) ? file : File.new( file, "r" )
|
67
|
+
elements = REXML::Document.new( read_file ).root.elements
|
68
|
+
return false if elements == nil
|
69
|
+
rescue Exception => e
|
70
|
+
return false
|
71
|
+
ensure
|
72
|
+
read_file.close() if read_file && read_file != file
|
73
|
+
end
|
74
|
+
|
75
|
+
requested_keys = hash.keys
|
76
|
+
|
77
|
+
keys = hash.keys
|
78
|
+
if ! only_hash_keys
|
79
|
+
elements.each() do |element|
|
80
|
+
key = element.name
|
81
|
+
keys << key if ! keys.include?( key )
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
read_keys = []
|
86
|
+
keys.each() do |key|
|
87
|
+
if elements[key]
|
88
|
+
value = elements[key].text.to_s()
|
89
|
+
type = elements[key].attribute( "type" ).to_s()
|
90
|
+
if type == "array"
|
91
|
+
hash[key] = value.split( "\n" )
|
92
|
+
elsif ( type == "fixnum" )
|
93
|
+
hash[key] = value.to_i()
|
94
|
+
elsif ( type == "float" )
|
95
|
+
hash[key] = value.to_f()
|
96
|
+
elsif ( type == "trueclass" )
|
97
|
+
hash[key] = true
|
98
|
+
elsif ( type == "falseclass" )
|
99
|
+
hash[key] = false
|
100
|
+
else
|
101
|
+
hash[key] = value
|
102
|
+
end
|
103
|
+
read_keys << key
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
return (requested_keys - read_keys).empty?
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|