class Arquivo::C118dir
permite processar e arquivar pasta com documentos c118
permite processar e arquivar pasta com documentos c118
Attributes
@return [Symbol] conteudo da pasta
@return (see obtem_dados
)
@return [String] documento c118
@return [Enumerator] items dentro duma pasta
@return [String] local da pasta
@return (see obtem_noiseprof
)
@return [String] nome ficheiro de arquivo
@return [Hash] parametrizar JPG, MINUTA
Public Class Methods
@param pasta (see CLI#dir
) @param [Hash] opt parametrizar JPG, MINUTA @option opt [Numeric] :fuzz (29) trim jpg N-1, escolhe menor -> scanned pdf @option opt [Numeric] :quality (15) compress jpg N% -> scanned pdf (less=low quality) @option opt [Numeric] :threshold (9) limiar maximo para silencio, 0% = silencio puro @option opt [Numeric] :sound (1) segundos de som para terminar silencio @option opt [Numeric] :amount (0.00001) qtd ruido a ser removido, @option opt [Numeric] :rate (16) sample rate - radio-16k, CD-44.1k, PC-48k, pro-96k @return [C118dir] pasta de documentos c118
# File lib/arquivo/noise.rb, line 41 def initialize(dir, opt) c = Dir.glob(File.join(dir, '*')) @local = dir @items = c.each @nome = File.basename(dir, File.extname(dir)) + '-' + Date.today.strftime('%Y%m%d') @opcoes = opt @contem = obtem_conteudo(c) end
Public Instance Methods
@param [Array<String, Float, String>] seg segmento, duracao, file silencio @param thr (see maximo_silencio
) @return [String] comando para cortar silencio inicial sum segmento
# File lib/arquivo/noise.rb, line 101 def cmd_silencio(seg, thr) ";sox #{seg[0]} #{seg[2]} silence 1 #{opcoes[:sound]}t #{thr}% #{O2}" end
@param [Array<String, Float>] seg segmento, duracao silencio inicial @return [String] perfil sonoro do silencio inicial dum segmento
# File lib/arquivo/noise.rb, line 113 def cria_noiseprof(seg) return unless seg[1] > opcoes[:sound] o = "tmp/noiseprof-#{File.basename(seg[0], File.extname(seg[0]))}" # obter noiseprof do silencio no inicio system "sox #{seg[0]} -n trim 0 #{seg[1]} noiseprof #{o} #{O2}" # so noiseprof validos sao devolvidos @noiseprof = File.size?(o).positive? ? o : nil end
@param [String] audio ficheiro de audio @return [Float] duracao ficheiro audio em segundos
# File lib/arquivo/noise.rb, line 132 def duracao(audio) `soxi -V0 -D #{audio} #{O1}`.to_f end
@param seg (see cmd_silencio
) @return [Float] duracao silencio em segundos
# File lib/arquivo/noise.rb, line 107 def duracao_silencio(seg) (seg[1] - duracao(seg[2])).round(2, half: :down) end
@param [Array] lsg lista segmentos audio com duracoes e file silencio @param [Numeric] thr limiar para silencio em processamento @return [Array<String, Float>] segmento com maior duracao silencio inicial
# File lib/arquivo/noise.rb, line 93 def maximo_silencio(lsg, thr) system lsg.inject('') { |s, e| s + cmd_silencio(e, thr) }[1..-1] lsg.map { |e| [e[0], duracao_silencio(e)] }.max_by { |_, s| s } end
@return [String] proximo item dentro da pasta
# File lib/arquivo/dir.rb, line 66 def next_item @item = items.next rescue StopIteration @item = nil end
@param [Float] sin duracao silencio @param thr (see maximo_silencio
) @return [Boolean] segmento audio tem som ou silencio no inicio
# File lib/arquivo/noise.rb, line 86 def noisy?(sin, thr) thr < opcoes[:threshold] && sin <= opcoes[:sound] end
Agrupa conteudo duma pasta segundo tipos de documentos validos
@param [Array] fls lista items duma pasta @return [Symbol] tipo de conteudo @example contem
:fsc scq :fsg minutas :frc recibos :fft faturas :fex extratos
# File lib/arquivo/noise.rb, line 61 def obtem_conteudo(fls) t = fls.group_by { |f| File.ftype(f)[0] + File.basename(f)[0, 2] }.keys return unless t.size == 1 && DT.include?(t[0].to_sym) t[0].to_sym end
@!group dados folhas-calculo c118 @return [Hash] dados oficiais para classificacao de faturas e recibos
# File lib/arquivo/dir.rb, line 74 def obtem_dados @dados = {} # somente faturas e recibos necessitam reclassificacao return unless %i[fft frc].include?(contem) # folha c118-contas s = '1PbiMrtTtqGztZMhe3AiJbDS6NQE9o3hXebnQEFdt954' @dados = C118sheets.new.folhas .get_spreadsheet_values(s, contem.to_s + '!A2:E') .values.group_by { |k| k[0][/\w+/] } rescue StandardError @dados = {} end
@!group perfil silencio @return [String] perfil do maior silencio inicial de todos segmentos audio
# File lib/arquivo/noise.rb, line 70 def obtem_noiseprof return unless contem == :fsg l = obtem_segmentos return unless l.size.positive? t = -1 m = ['', 0] m = maximo_silencio(l, t += 1) while noisy?(m[1], t) cria_noiseprof(m) end
@return [Array] lista segmentos audio com duracoes e file silencio
# File lib/arquivo/noise.rb, line 125 def obtem_segmentos AT.map { |e| Dir.glob(File.join(local, 'sg*' + e)) }.flatten .map { |s| [s, duracao(s), "tmp/thr-#{File.basename(s)}"] } end
processa ficheiro JPG, PDF ou AUDIO
@param [String] ext tipo ficheiro
# File lib/arquivo/dir.rb, line 44 def processa_file(ext) opt = opcoes case ext when '.jpg' then C118jpg.new(item, opt).processa_jpg(dados) when '.pdf' then C118pdf.new(item, opt).processa_pdf(dados) when *AT then C118mp3.new(item, opt).processa_mp3(noiseprof) else puts "erro: #{ext} nao posso processar este tipo de dicheiro" end end
cria ficheiros finais para arquivo
@param [Numeric] num numero de documentos dentro do arquivo
# File lib/arquivo/dir.rb, line 26 def processa_fim(num) return unless num.positive? cmd = if contem == :fsg "rm -f #{nome}.*;sox tmp/zip/* #{nome}.mp3" else "rm -f #{nome}.*;pdftk tmp/stamped* cat output #{nome}.pdf" end system cmd + ";cd tmp/zip;tar cf ../../#{nome}.tar *" \ ";cd ../..;gzip --best #{nome}.tar" \ ';rm -rf tmp' puts "#{nome} (#{num})" end
@!group processamento processa items duma pasta
# File lib/arquivo/dir.rb, line 10 def processa_items n = 0 while next_item if File.ftype(item) == 'directory' C118dir.new(item, opcoes).processa_pasta else processa_file(File.extname(item).downcase) n += 1 end end processa_fim(n) end
processa conteudo duma pasta
# File lib/arquivo/dir.rb, line 56 def processa_pasta if contem system 'mkdir -p tmp/zip' obtem_dados obtem_noiseprof end processa_items end