catori 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. data/VERSION +1 -0
  2. data/bin/catori +9 -0
  3. data/changelog.txt +3 -0
  4. data/construir +3 -0
  5. data/crear_vista.sql +8 -0
  6. data/ext/audiofile/MANIFEST +8 -0
  7. data/ext/audiofile/README +11 -0
  8. data/ext/audiofile/audiofile.c +833 -0
  9. data/ext/audiofile/audiofile.rd +265 -0
  10. data/ext/audiofile/depend +0 -0
  11. data/ext/audiofile/extconf.rb +8 -0
  12. data/ext/audiofile/fail.rb +22 -0
  13. data/ext/audiofile/mkmf.log +34 -0
  14. data/ext/audiofile/test.rb +229 -0
  15. data/ext/flac/extconf.rb +5 -0
  16. data/ext/flac/flac.c +75 -0
  17. data/ext/flac/mkmf.log +12 -0
  18. data/ext/flac/test.rb +3 -0
  19. data/ext/mahoro-0.1/INSTALL +9 -0
  20. data/ext/mahoro-0.1/extconf.rb +7 -0
  21. data/ext/mahoro-0.1/mahoro.c +187 -0
  22. data/ext/mahoro-0.1/mkmf.log +24 -0
  23. data/ext/mahoro-0.1/test.rb +41 -0
  24. data/ext/mpc/extconf.rb +5 -0
  25. data/ext/mpc/id3tag.c +245 -0
  26. data/ext/mpc/id3tag.h +5 -0
  27. data/ext/mpc/mkmf.log +12 -0
  28. data/ext/mpc/mpc.c +56 -0
  29. data/ext/mpc/mpp.h +194 -0
  30. data/ext/mpc/mppdec.h +1171 -0
  31. data/ext/mpc/test.rb +3 -0
  32. data/ext/rmac/extconf.rb +7 -0
  33. data/ext/rmac/mkmf.log +22 -0
  34. data/ext/rmac/rmac.cpp +162 -0
  35. data/ext/vorbisfile/ChangeLog +11 -0
  36. data/ext/vorbisfile/README +33 -0
  37. data/ext/vorbisfile/configure +2 -0
  38. data/ext/vorbisfile/extconf.rb +9 -0
  39. data/ext/vorbisfile/mkmf.log +68 -0
  40. data/ext/vorbisfile/test.rb +78 -0
  41. data/ext/vorbisfile/vorbisfile.c +482 -0
  42. data/instalar.txt +19 -0
  43. data/install.rb +11 -0
  44. data/lib/audioinfo.rb +321 -0
  45. data/lib/catori.rb +131 -0
  46. data/lib/catori/Catalogador.rb +71 -0
  47. data/lib/catori/Db.rb +81 -0
  48. data/lib/catori/Gui.rb +52 -0
  49. data/lib/catori/Installer.rb +16 -0
  50. data/lib/catori/Query.rb +82 -0
  51. data/lib/catori/XML.rb +42 -0
  52. data/lib/catori/catori_gui.glade +340 -0
  53. data/lib/catori/catori_gui.glade.bak +340 -0
  54. data/lib/catori/catori_gui.gladep +8 -0
  55. data/lib/catori/catori_gui.gladep.bak +8 -0
  56. data/lib/catori/taglib.rb +227 -0
  57. data/lib/pixmaps/album.png +0 -0
  58. data/lib/pixmaps/artist.png +0 -0
  59. data/lib/pixmaps/cdr.png +0 -0
  60. data/lib/pixmaps/song.png +0 -0
  61. data/lib/taglib.rb +230 -0
  62. data/sql/catori_mysql.sql +68 -0
  63. data/sql/catori_pg.sql +65 -0
  64. data/tests/saw.ape +0 -0
  65. data/tests/saw.flac +0 -0
  66. data/tests/saw.mp3 +0 -0
  67. data/tests/saw.mpc +0 -0
  68. data/tests/saw.ogg +0 -0
  69. data/tests/saw.wav +0 -0
  70. data/tests/test_audioinfo.rb +43 -0
  71. metadata +217 -0
@@ -0,0 +1,19 @@
1
+ Primero, mis disculpas por el procedimiento chapucero, pero como ustedes son mas inteligentes que yo, lo mas probable es que encuentren alguna forma de instalarlo de forma mas racional.
2
+
3
+ Lo primero es conseguir ruby-gem, desde su distro favorita.
4
+ Despues, desde la linea de comandos como root deben hacer:
5
+
6
+ # gem install catori-0.2.5.gem
7
+
8
+ Una vez compiladas las extensiones (espero), deben crear una base de datos en su servidor Mysql y hacer, ahora como usuarios normales
9
+
10
+ $ catori --install --user USER --password PW --database DB
11
+
12
+ Con eso deberia estar lista la estructura basica.
13
+
14
+ Para ver las funcionalidades del programa, se puede hacer
15
+
16
+ $ catori
17
+
18
+ Viendose en ese momento glorioso el use clasico.
19
+
@@ -0,0 +1,11 @@
1
+ #!/bin/env ruby
2
+
3
+ base=File.dirname(__FILE__)
4
+ Dir["./ext/*/extconf.rb"].each {|ext|
5
+ dir=File.dirname(ext)
6
+ puts "Building #{dir}"
7
+
8
+ Dir.chdir(dir) do
9
+ `ruby extconf.rb && make && mv *.so ../../lib`
10
+ end
11
+ }
@@ -0,0 +1,321 @@
1
+ # AudioInfo: entrega informaci�n sobre distintos archivos de audio
2
+ # Por el momento, puede manejar
3
+ # * flac
4
+ # * ogg
5
+ # * mp3.
6
+ # * shn
7
+ # * ape
8
+ # * soportados por audiofile : wav, aiff, snd, au
9
+
10
+ #require "rubygems"
11
+ gem "ruby-mp3info", ">=0.5.1"
12
+ require "mp3info"
13
+ require "iconv"
14
+ require "taglib"
15
+ require "rmac"
16
+ require "vorbisfile"
17
+ require "flac"
18
+ require "audiofile"
19
+ require "mpc"
20
+
21
+ class String
22
+ def encoding
23
+ cuenta=0
24
+ ascii=true
25
+ self.each_byte{|byte|
26
+ if cuenta>0
27
+ if (byte >> 6) != 0b10
28
+ return "iso8859"
29
+ else
30
+ cuenta-=1
31
+ end
32
+ else
33
+ next if(byte<128)
34
+ ascii=false
35
+ if (byte >> 5) == 0b110
36
+ cuenta=1
37
+ elsif (byte >> 4) == 0b1110
38
+ cuenta=2
39
+ elsif (byte >> 3) == 0b11110
40
+ cuenta=3
41
+ else
42
+ return "iso8859"
43
+ end
44
+ end
45
+ }
46
+ ascii ? "ascii":"utf8"
47
+ end
48
+ def to_utf8
49
+ (self.encoding=='iso8859') ? Iconv.new("utf-8","iso-8859-1").iconv(self.to_s) : self
50
+ end
51
+ end
52
+
53
+ module AudioInfo
54
+ SUPPORT=%w{flac ogg mp3 wav aiff au snd shn ape mpc}
55
+ # entrega un objeto AudioInfo::Tipo
56
+ def self.infoFile(sFile)
57
+ # primero, identificar el tipo de archivo
58
+ return false if !File.stat(sFile).file?
59
+ return false if !(tipo=determinarTipoFile(sFile)) and !(tipo=determinarTipoExtension(sFile))
60
+ # ok, existe. Ahora, obtengo la informaci�n sobre �l de la manera 'legal'
61
+ begin
62
+ oInfoTags=self.const_get(tipo.capitalize.intern).new(sFile)
63
+ rescue StandardError => ex
64
+ print "Error in file #{sFile} "+ex
65
+ print ex.backtrace
66
+ return false
67
+ end
68
+ # Si falta alg�n dato, lo trato de obtener del nombre del archivo
69
+ if oInfoTags.incompleto?
70
+ # ahora verifico que esten todos los datos en orden.
71
+ oNombre=AudioInfo::FileName.new(sFile)
72
+ oInfoTags.merge(oNombre)
73
+ # si todav�a falta algo, lo arreglo
74
+ oInfoTags.album='Desconocido' if oInfoTags.album.nil?
75
+ oInfoTags.artist='Desconocido' if oInfoTags.artist.nil?
76
+ end
77
+ # Si no, busco por el nombre
78
+ return oInfoTags
79
+ end
80
+ # Determina el tipo de archivo, a partir del comando file
81
+ def self.determinarTipoFile(sFile)
82
+ sTipo=`file -L -b \"#{sFile}\"`
83
+ if sTipo=~/^FLAC/
84
+ return 'flac'
85
+ elsif sTipo=~/^MP3/
86
+ return 'mp3'
87
+ elsif sTipo=~/Ogg.*Vorbis audio/
88
+ return 'ogg'
89
+ end
90
+ false
91
+ end
92
+ # Determina el tipo de archivo, a partir de su extensi�n
93
+ def self.determinarTipoExtension(sFile)
94
+ sSupport=SUPPORT.join('|')
95
+ if sFile=~/\.(#{sSupport})$/i
96
+ return $1.downcase
97
+ else
98
+ return false
99
+ end
100
+ end
101
+ # Recolección de información, a partir del tipo de archivo
102
+ class Tipo
103
+ attr_accessor :title, :artist, :tracknumber, :album, :year, :sample_rate, :bps, :time, :bits_per_sample, :channels
104
+ attr_reader :sFile, :size
105
+ TAGS=['title','artist','tracknumber','album','year']
106
+ private
107
+ # Aqu� se ingresan las operaciones para procesar la informaci�n
108
+ def parse
109
+ end
110
+ public
111
+ # * sFile: Nombre del archivo
112
+ def initialize(sFile)
113
+ @sFile=sFile
114
+ @size=File.stat(@sFile).size
115
+ parse
116
+ #@sFile=@sFile.to_utf8
117
+ end
118
+ # entrega los kbps para el archivo
119
+ def kbps
120
+ @bps/1024.to_f
121
+ end
122
+ # arregla aquellos valores de tag con formatos especiales
123
+ def arreglarValor(tag,valor)
124
+ valor.gsub!('_',' ')
125
+ case tag
126
+ when 'tracknumber'
127
+ if valor=~/(\d+)\/\d+/
128
+ valor=$1
129
+ elsif valor=~/\[(\d+)\]/
130
+ valor=$1
131
+ elsif valor=~/^(\d+)/
132
+ valor=$1
133
+ end
134
+ valor=nil if valor !~ /\d+/
135
+ when 'year'
136
+ if valor=~/(\d+)[-\/:](\d+)[-\/:](\d+)/
137
+ valor=$3 if $3.length==4
138
+ valor=$1 if $1.length==4
139
+ elsif valor=~/(\d+)\/(\d+)/
140
+ valor=$1
141
+ elsif valor=~/(\d+)/
142
+ valor=$1
143
+ else
144
+ valor=""
145
+ end
146
+ end
147
+ valor.to_utf8 if valor.respond_to?('to_utf8')
148
+ end
149
+ def arreglarValoresEstandar(aInfo)
150
+ aInfo.each { |tagprop,tagself|
151
+ valor=yield(tagprop)
152
+ valor=arreglarValor(tagself,valor.to_s)
153
+ self.send(tagself+"=",valor) unless (valor.nil? or valor=="")
154
+ }
155
+ end
156
+
157
+ # retorna true si falta alguno de los tag basicos, definidos en TAGS
158
+ def incompleto?
159
+ TAGS.detect {|tag| send(tag).nil?}
160
+ end
161
+ # recoje los valores de otro AudioInfo::Tipo y los une a los propios
162
+ def merge(oInfo)
163
+ raise "No es Tipo" if !oInfo.kind_of? AudioInfo::Tipo
164
+ TAGS.each {|tag|
165
+ tag_1=send(tag)
166
+ tag_2=oInfo.send(tag)
167
+ #instance_variable_set(var,tag_2) if tag_1.nil? and !tag_2.nil?
168
+ send(tag+'=',tag_2) if tag_1.nil? and !tag_2.nil?
169
+ }
170
+ end
171
+ end
172
+ class Virtual < Tipo
173
+ attr_reader :cd
174
+ def initialize(cd,sFile)
175
+ @cd=cd
176
+ @sFile=sFile
177
+ end
178
+ end
179
+ class Audiofile < Tipo
180
+ def parse
181
+ ::AudioFile.open(@sFile) do |file|
182
+ @sample_rate=file.rate
183
+ @channels=file.channels
184
+ @bits_per_sample=file.bits
185
+ @time=file.frame_count/file.rate.to_f
186
+ end
187
+ end
188
+ end
189
+ class Wav < Audiofile
190
+ end
191
+ class Aiff < Audiofile
192
+ end
193
+ class Au < Audiofile
194
+ end
195
+ class Snd < Audiofile
196
+ end
197
+ class Ogg < Tipo
198
+ def parse
199
+ aInfo={"title"=>"title","artist"=>"artist","album"=>"album", "date"=>"year", "tracknumber"=>"tracknumber"}
200
+ f=File.open(@sFile, "r")
201
+ vf = ::Ogg::VorbisFile.new
202
+ vf.open(f)
203
+ comments=vf.comments(-1)
204
+ @channels=vf.channels(-1)
205
+ @sample_rate=vf.sample_rate(-1)
206
+ @time=vf.time_total(-1)
207
+ @bps=vf.bitrate(-1)
208
+ arreglarValoresEstandar(aInfo) {|tag| comments[tag]}
209
+ vf.close
210
+ end
211
+ end
212
+ class Flac < Tipo
213
+ def parse
214
+ aInfo={"title"=>"title","artist"=>"artist","album"=>"album", "date"=>"year", "tracknumber"=>"tracknumber"}
215
+ oInfo=::Flac.info(@sFile)
216
+ @time = oInfo.time
217
+ @sample_rate = oInfo.sample_rate;
218
+ @channels= oInfo.channels;
219
+ @bits_per_sample=oInfo.bits_per_sample
220
+ @bps=(@size * 8 / @time)
221
+ arreglarValoresEstandar(aInfo) {|tag|
222
+ oInfo.comments[tag]}
223
+ end
224
+
225
+ end
226
+ class FileName < Tipo
227
+ # Define las estructuras de nombre de archivo que pueden ser parseadas
228
+ ESTRUCTURAS=[
229
+ "%a-%b-%n-%t",
230
+ "%a-%y-%b/%n-%t",
231
+ "%a-%y-%b/%c/%n-%t",
232
+ "%a-%b/%c/%n-%t",
233
+ "%a-%n-%t",
234
+ "%a/%b\\(%y\\)/%n-%t",
235
+ "%a/%y-%b/%n-%t",
236
+ "%a/%y-%b/%n\\.%t",
237
+ "%a/%y-%b/%t",
238
+ "%a-%b/%n-%t",
239
+ "%a-%b/%t",
240
+ "%a/%n-%t",
241
+ "%n-%t",
242
+ "%a-%t",
243
+ "%a/%t",
244
+ "%t"]
245
+ def parse
246
+ hEquil={'%a'=>'artist','%y'=>'year','%b'=>'album','%n'=>'tracknumber', '%t'=>'title'}
247
+ x=0
248
+ sFile=@sFile.gsub("_"," ")
249
+ sSupport=SUPPORT.join('|')
250
+ ESTRUCTURAS.each {|sTexto|
251
+ aSec=sTexto.scan(/%[abcnty]/)
252
+ rx=Regexp.new(".*/"+sTexto.gsub(/%[a|b|t]/, '\s*?([^/]+?)\s*?').gsub("%y", '\s*?(\d{4,4})\s*?').gsub("%n", '\s*?(\d{1,2})\.?\s*?').gsub("%c",'CD[\s-]?(\d)') + "\.(#{sSupport})$")
253
+ if match=rx.match(sFile)
254
+ puts "Patron:"+sTexto if $DEBUG
255
+ x=1
256
+ aSec.each{|tag|
257
+ valor=match[x].strip
258
+ if tag!='%n' and tag!='%y' and tag!='%c' and valor=~/^\d+$/
259
+ puts "#{sFile} : Valor num�rico donde no corresponde en #{tag}:[#{valor}] #{rx}"
260
+ next 2
261
+ end
262
+ case tag
263
+ when '%c'
264
+ @album+="[CD "+valor+"]"
265
+ when '%n'
266
+ @tracknumber=valor.to_i
267
+ when '%y'
268
+ @year=valor.to_i
269
+ else
270
+ puts "#{sFile} : Posible error - Valor numérico donde no corresponde en #{tag}:#{valor}" if valor=~/^\d+$/
271
+ send(hEquil[tag]+'=',arreglarValor(tag,valor))
272
+ end
273
+ x+=1
274
+ }
275
+ break;
276
+ end # fin if
277
+ }
278
+ end
279
+ end
280
+ class Mp3 < Tipo
281
+ def parse
282
+ aInfo={'title'=>'title', 'artist'=>'artist', 'album'=>'album', 'tracknum'=>'tracknumber','year'=>'year'}
283
+ ::Mp3Info.open(@sFile) do |mp3info|
284
+ @sample_rate=mp3info.samplerate
285
+ @channels=2
286
+ @bits_per_sample=16
287
+ @time=mp3info.length
288
+ @bps=mp3info.bitrate * 1024
289
+ arreglarValoresEstandar(aInfo) {|tag| mp3info.tag[tag]}
290
+ end
291
+ end
292
+ end
293
+ class Ape < Tipo
294
+ def parse
295
+ aInfo={'title'=>'title', 'artist'=>'artist', 'album'=>'album', 'track'=>'tracknumber','year'=>'year'}
296
+ begin
297
+ oInfo=Mac.info(@sFile)
298
+ @sample_rate=oInfo.samplerate
299
+ @channels=oInfo.channels
300
+ @time=oInfo.length
301
+ @bps=(@size*8/@time)
302
+ arreglarValoresEstandar(aInfo) {|tag| oInfo.send(tag)}
303
+ rescue Exception => bang
304
+ puts bang.to_s
305
+ end
306
+ end
307
+ end
308
+ class Mpc < FileName
309
+ def parse
310
+ aInfo={'title'=>'title', 'artist'=>'artist', 'album'=>'album', 'tracknumber'=>'tracknumber','year'=>'year'}
311
+ oInfo=::Mpc.info(@sFile)
312
+ @sample_rate=oInfo.sample_rate
313
+ @channels=oInfo.channels
314
+ @time=oInfo.time
315
+ @bps=oInfo.bps
316
+ arreglarValoresEstandar(aInfo) {|tag| oInfo.send(tag)}
317
+ end
318
+ end
319
+ class Shn < FileName
320
+ end
321
+ end
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ # =bymain
3
+ # Catori: El mas grandioso y ocioso catalogador de musica
4
+ # escrito en ruby y orientado a la linea de comandos.
5
+ require 'getoptlong'
6
+ require 'audioinfo'
7
+ require 'catori/Catalogador'
8
+ require 'catori/Db'
9
+ module Catori
10
+ VERSION="0.2.3"
11
+ CONFIG_DIR=File.expand_path("~/.config/php.apsique.com")
12
+ CONFIG_FILE=CONFIG_DIR+"/catori.conf"
13
+ LIB_DIR = File.expand_path(File.dirname(__FILE__)+"/../lib")
14
+ def self.version
15
+ "Catori "+VERSION
16
+ end
17
+ def self.usage
18
+ <<USAGE
19
+ Use: catori [--catalog DISC_ID [--device PATH] [--mount] ] [--query QUERY] [--help] [--version] [--edit]
20
+
21
+ Store the information about music files on PATH in DISC_ID tag.
22
+
23
+ Catalog a CD / DVD: catori [--mount] [--device PATH] --catalog CD_TITLE
24
+ Retrieve information: catori --query [--artist ARTIST] [--title TITLE] [--file FILE]
25
+ Install on a Mysql Database: catori --install --database DB --user USER --password PW
26
+ Help: catori --help
27
+ Version: catori --version
28
+
29
+ Send bugs to clbustos at gmail.com
30
+
31
+ USAGE
32
+ end
33
+ class App
34
+ def run
35
+ iArgs=ARGV.size
36
+ parser = GetoptLong.new
37
+ parser.set_options(
38
+ ['--catalog', '-c', GetoptLong::REQUIRED_ARGUMENT],
39
+ ['--gui', GetoptLong::NO_ARGUMENT],
40
+ ['--install', GetoptLong::NO_ARGUMENT],
41
+ ['--user', GetoptLong::REQUIRED_ARGUMENT],
42
+ ['--database', GetoptLong::REQUIRED_ARGUMENT],
43
+ ['--password', GetoptLong::REQUIRED_ARGUMENT],
44
+ ['--pretend', '-p', GetoptLong::NO_ARGUMENT],
45
+ ['--mount', '-m', GetoptLong::NO_ARGUMENT],
46
+ ['--device', '-d', GetoptLong::REQUIRED_ARGUMENT],
47
+ ['--help', GetoptLong::NO_ARGUMENT],
48
+ ['--version', GetoptLong::NO_ARGUMENT],
49
+ ['--query', '-u', GetoptLong::NO_ARGUMENT],
50
+ ['--edit', '-e', GetoptLong::NO_ARGUMENT],
51
+ ['--artist', GetoptLong::REQUIRED_ARGUMENT],
52
+ ['--album', GetoptLong::REQUIRED_ARGUMENT],
53
+ ['--title', GetoptLong::REQUIRED_ARGUMENT],
54
+ ['--file', GetoptLong::REQUIRED_ARGUMENT],
55
+ ['--delete', GetoptLong::NO_ARGUMENT],
56
+ ['--cd', GetoptLong::REQUIRED_ARGUMENT]
57
+ )
58
+ parser.each_option do |name, arg|
59
+ eval "$OPT_#{name.sub(/^--/, '').gsub(/-/, '_').upcase} = '#{arg}'"
60
+ end
61
+ hQuery=Hash.new
62
+ hQuery['artist']=$OPT_ARTIST if !$OPT_ARTIST.nil?
63
+ hQuery['album']=$OPT_ALBUM if !$OPT_ALBUM.nil?
64
+ hQuery['title']=$OPT_TITLE if !$OPT_TITLE.nil?
65
+ hQuery['file']=$OPT_FILE if !$OPT_FILE.nil?
66
+ hQuery['cd']=$OPT_CD if !$OPT_CD.nil?
67
+
68
+ if iArgs==0 or !$OPT_HELP.nil?
69
+ puts Catori::usage
70
+ elsif !$OPT_GUI.nil?
71
+ require 'catori/Gui'
72
+ require 'catori/Query'
73
+
74
+ gui=Catori::Gui.new(hQuery)
75
+ gui.start
76
+ exit
77
+ elsif !$OPT_INSTALL.nil?
78
+ require 'catori/Installer'
79
+ if $OPT_DATABASE.nil? or $OPT_USER.nil? or $OPT_PASSWORD.nil?
80
+ puts "Use\ncatori --install --database DATABASE --user USER --password PASSWORD"
81
+ exit
82
+ end
83
+ Catori::Installer.install($OPT_DATABASE,$OPT_USER,$OPT_PASSWORD)
84
+ elsif !$OPT_QUERY.nil?
85
+ raise "Need info for query" if hQuery.size==0
86
+ require 'catori/Query'
87
+ q=Catori::Query.new(hQuery)
88
+ puts q.plain
89
+ elsif !$OPT_EDIT.nil?
90
+ raise "Need info for query" if hQuery.size==0
91
+ require 'catori/Query'
92
+ require 'catori/XML'
93
+ q=Catori::Query.new(hQuery)
94
+ temp=`mktemp /tmp/catori.XXXXXX`.strip
95
+ if temp
96
+ fp=File.open(temp,"w")
97
+ fp.puts(q.xml)
98
+ fp.close
99
+ fecha=File.stat(temp).mtime
100
+ system("$EDITOR #{temp}")
101
+ if(File.stat(temp).mtime!=fecha)
102
+ xml=Catori::XML.new(temp)
103
+ if(xml.rastrea and i=xml.actualizar)
104
+ $stderr.puts "Actualizados "+i.to_s+" archivos"
105
+ else
106
+ $stderr.puts "Se produjo un error!"
107
+ end
108
+ else
109
+ $stderr.puts "No hay modificaciones"
110
+ end
111
+
112
+ else
113
+ raise "Can't make a temp file"
114
+ end
115
+ elsif !$OPT_VERSION.nil?
116
+ puts Catori::version
117
+ elsif !$OPT_CATALOG.nil?
118
+ $stderr.puts "Iniciando"
119
+ device=$OPT_DEVICE.nil? ? '/mnt/cdrom' : $OPT_DEVICE;
120
+ `mount #{device} &> /dev/null` if $OPT_MOUNT
121
+ c=Catori::Catalogador.new($OPT_CATALOG,!$OPT_PRETEND.nil?,device)
122
+ c.deletePrevious if !$OPT_DELETE.nil?
123
+ c.rastrea
124
+ `umount #{device} &> /dev/null` if $OPT_MOUNT
125
+ `eject #{device} &> /dev/null`if $OPT_MOUNT
126
+ $stderr.puts "Listo"
127
+ end
128
+ end
129
+ end
130
+ end
131
+