Class: Arquivo::C118dir

Inherits:
Enumerator
  • Object
show all
Defined in:
lib/arquivo/dir.rb,
lib/arquivo/noise.rb

Overview

permite processar e arquivar pasta com documentos c118

Instance Attribute Summary collapse

processamento collapse

dados folhas-calculo c118 collapse

perfil silencio collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir, opt) ⇒ C118dir

Returns pasta de documentos c118.

Parameters:

  • opt (Hash)

    parametrizar JPG, MINUTA

  • pasta (String)

    contem os documentos para arquivar

Options Hash (opt):

  • :fuzz (Numeric) — default: 29

    trim jpg N-1, escolhe menor -> scanned pdf

  • :quality (Numeric) — default: 15

    compress jpg N% -> scanned pdf (less=low quality)

  • :threshold (Numeric) — default: 9

    limiar maximo para silencio, 0% = silencio puro

  • :sound (Numeric) — default: 1

    segundos de som para terminar silencio

  • :amount (Numeric) — default: 0.00001

    qtd ruido a ser removido,

  • :rate (Numeric) — default: 16

    sample rate - radio-16k, CD-44.1k, PC-48k, pro-96k



41
42
43
44
45
46
47
48
49
# 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

Instance Attribute Details

#contemSymbol (readonly)

Returns conteudo da pasta.

Returns:

  • (Symbol)

    conteudo da pasta



23
24
25
# File 'lib/arquivo/noise.rb', line 23

def contem
  @contem
end

#dadosHash (readonly)

Returns dados oficiais para classificacao de faturas e recibos.

Returns:

  • (Hash)

    dados oficiais para classificacao de faturas e recibos



28
29
30
# File 'lib/arquivo/noise.rb', line 28

def dados
  @dados
end

#itemString (readonly)

Returns documento c118.

Returns:

  • (String)

    documento c118



26
27
28
# File 'lib/arquivo/noise.rb', line 26

def item
  @item
end

#itemsEnumerator (readonly)

Returns items dentro duma pasta.

Returns:

  • (Enumerator)

    items dentro duma pasta



17
18
19
# File 'lib/arquivo/noise.rb', line 17

def items
  @items
end

#localString (readonly)

Returns local da pasta.

Returns:

  • (String)

    local da pasta



15
16
17
# File 'lib/arquivo/noise.rb', line 15

def local
  @local
end

#noiseprofString (readonly)

Returns perfil do maior silencio inicial de todos segmentos audio.

Returns:

  • (String)

    perfil do maior silencio inicial de todos segmentos audio



30
31
32
# File 'lib/arquivo/noise.rb', line 30

def noiseprof
  @noiseprof
end

#nomeString (readonly)

Returns nome ficheiro de arquivo.

Returns:

  • (String)

    nome ficheiro de arquivo



19
20
21
# File 'lib/arquivo/noise.rb', line 19

def nome
  @nome
end

#opcoesHash (readonly)

Returns parametrizar JPG, MINUTA.

Returns:

  • (Hash)

    parametrizar JPG, MINUTA



21
22
23
# File 'lib/arquivo/noise.rb', line 21

def opcoes
  @opcoes
end

Instance Method Details

#cmd_silencio(seg, thr) ⇒ String

Returns comando para cortar silencio inicial sum segmento.

Parameters:

  • seg (Array<String, Float, String>)

    segmento, duracao, file silencio

  • thr (Numeric)

    limiar para silencio em processamento

Returns:

  • (String)

    comando para cortar silencio inicial sum segmento



101
102
103
# 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

#cria_noiseprof(seg) ⇒ String

Returns perfil sonoro do silencio inicial dum segmento.

Parameters:

  • seg (Array<String, Float>)

    segmento, duracao silencio inicial

Returns:

  • (String)

    perfil sonoro do silencio inicial dum segmento



113
114
115
116
117
118
119
120
121
122
# 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

#duracao(audio) ⇒ Float

Returns duracao ficheiro audio em segundos.

Parameters:

  • audio (String)

    ficheiro de audio

Returns:

  • (Float)

    duracao ficheiro audio em segundos



132
133
134
# File 'lib/arquivo/noise.rb', line 132

def duracao(audio)
  `soxi -V0 -D #{audio} #{O1}`.to_f
end

#duracao_silencio(seg) ⇒ Float

Returns duracao silencio em segundos.

Parameters:

  • seg (Array<String, Float, String>)

    segmento, duracao, file silencio

Returns:

  • (Float)

    duracao silencio em segundos



107
108
109
# File 'lib/arquivo/noise.rb', line 107

def duracao_silencio(seg)
  (seg[1] - duracao(seg[2])).round(2, half: :down)
end

#maximo_silencio(lsg, thr) ⇒ Array<String, Float>

Returns segmento com maior duracao silencio inicial.

Parameters:

  • lsg (Array)

    lista segmentos audio com duracoes e file silencio

  • thr (Numeric)

    limiar para silencio em processamento

Returns:

  • (Array<String, Float>)

    segmento com maior duracao silencio inicial



93
94
95
96
# 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

#next_itemString

Returns proximo item dentro da pasta.

Returns:

  • (String)

    proximo item dentro da pasta



66
67
68
69
70
# File 'lib/arquivo/dir.rb', line 66

def next_item
  @item = items.next
rescue StopIteration
  @item = nil
end

#noisy?(sin, thr) ⇒ Boolean

Returns segmento audio tem som ou silencio no inicio.

Parameters:

  • sin (Float)

    duracao silencio

  • thr (Numeric)

    limiar para silencio em processamento

Returns:

  • (Boolean)

    segmento audio tem som ou silencio no inicio



86
87
88
# File 'lib/arquivo/noise.rb', line 86

def noisy?(sin, thr)
  thr < opcoes[:threshold] && sin <= opcoes[:sound]
end

#obtem_conteudo(fls) ⇒ Symbol

Agrupa conteudo duma pasta segundo tipos de documentos validos

Examples:

contem

:fsc scq
:fsg minutas
:frc recibos
:fft faturas
:fex extratos

Parameters:

  • fls (Array)

    lista items duma pasta

Returns:

  • (Symbol)

    tipo de conteudo



61
62
63
64
65
66
# 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

#obtem_dadosHash

Returns dados oficiais para classificacao de faturas e recibos.

Returns:

  • (Hash)

    dados oficiais para classificacao de faturas e recibos



74
75
76
77
78
79
80
81
82
83
84
85
86
# 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

#obtem_noiseprofString

Returns perfil do maior silencio inicial de todos segmentos audio.

Returns:

  • (String)

    perfil do maior silencio inicial de todos segmentos audio



70
71
72
73
74
75
76
77
78
79
80
81
# 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

#obtem_segmentosArray

Returns lista segmentos audio com duracoes e file silencio.

Returns:

  • (Array)

    lista segmentos audio com duracoes e file silencio



125
126
127
128
# 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_file(ext) ⇒ Object

processa ficheiro JPG, PDF ou AUDIO

Parameters:

  • ext (String)

    tipo ficheiro



44
45
46
47
48
49
50
51
52
53
# 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

#processa_fim(num) ⇒ Object

cria ficheiros finais para arquivo

Parameters:

  • num (Numeric)

    numero de documentos dentro do arquivo



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 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

#processa_itemsObject

processa items duma pasta



10
11
12
13
14
15
16
17
18
19
20
21
# 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_pastaObject

processa conteudo duma pasta



56
57
58
59
60
61
62
63
# 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