Class: Arquivo::C118pdf

Inherits:
Object
  • Object
show all
Defined in:
lib/arquivo/pdf.rb,
lib/arquivo/extrato.rb

Overview

permite processar documentos PDF

Instance Attribute Summary collapse

processamento collapse

segmentacao collapse

Instance Method Summary collapse

Constructor Details

#initialize(pdf, opt) ⇒ C118pdf

Returns PDF c118.

Parameters:

  • pdf (String)

    PDF c118

  • opt (Hash)

    parametrizar JPG

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)



32
33
34
35
36
37
38
39
# File 'lib/arquivo/extrato.rb', line 32

def initialize(pdf, opt)
  @file = pdf
  @ext = File.extname(pdf).downcase
  @base = File.basename(pdf, File.extname(pdf))
  @id = @base[/\w+/]
  @size = File.size(pdf)
  @opcoes = opt
end

Instance Attribute Details

#baseString (readonly)

Returns base do documento.

Returns:

  • (String)

    base do documento



13
14
15
# File 'lib/arquivo/extrato.rb', line 13

def base
  @base
end

#extString (readonly)

Returns extensao do documento.

Returns:

  • (String)

    extensao do documento



11
12
13
# File 'lib/arquivo/extrato.rb', line 11

def ext
  @ext
end

#fileString (readonly)

Returns nome do documento.

Returns:

  • (String)

    nome do documento



9
10
11
# File 'lib/arquivo/extrato.rb', line 9

def file
  @file
end

#idString (readonly)

Returns id do documento ft/rc/ex/sc <numero>.

Returns:

  • (String)

    id do documento ft/rc/ex/sc <numero>



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

def id
  @id
end

#nomeString (readonly)

Returns nome extrato.

Returns:

  • (String)

    nome extrato



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

def nome
  @nome
end

#opcoesHash (readonly)

Returns opcoes parametrizar JPG.

Returns:

  • (Hash)

    opcoes parametrizar JPG



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

def opcoes
  @opcoes
end

#paginaString (readonly)

Returns texto pagina.

Returns:

  • (String)

    texto pagina



24
25
26
# File 'lib/arquivo/extrato.rb', line 24

def pagina
  @pagina
end

#paginasArray<Integer> (readonly)

Returns lista paginas do extrato.

Returns:

  • (Array<Integer>)

    lista paginas do extrato



22
23
24
# File 'lib/arquivo/extrato.rb', line 22

def paginas
  @paginas
end

#sizeInteger (readonly)

Returns tamanho do documento.

Returns:

  • (Integer)

    tamanho do documento



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

def size
  @size
end

Instance Method Details

#faz_dashboardObject

cria PDF do dashboard



148
149
150
151
152
153
154
# File 'lib/arquivo/pdf.rb', line 148

def faz_dashboard
  c = 'gs -sDEVICE=pdfwrite ' \
      '-dNOPAUSE -dBATCH -dQUIET -dPDFSETTINGS=/printer ' \
      '-sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage -dAutoRotatePages=/All'
  system "#{c} -sOutputFile=#{base}-a4.pdf \"#{file}\" #{O2}"
  puts "#{base}-a4"
end

#faz_extratoObject

cria PDF do extrato



124
125
126
127
128
129
130
# File 'lib/arquivo/extrato.rb', line 124

def faz_extrato
  system "#{ghostscript} " \
    "-sOutputFile=#{base}/#{nome}-extrato.pdf " \
    "-sPageList=#{paginas.join(',')} \"#{file}\" #{O2}"
  puts "#{nome}-extrato"
  nome_extrato
end

#final(kda) ⇒ C118pdf

Returns pdf totalmente processado.

Examples:

kda-ft1901

[["ft1901","legal","assembleia","expediente","-1395"]]

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (C118pdf)

    pdf totalmente processado



31
32
33
34
35
36
37
38
39
40
# File 'lib/arquivo/pdf.rb', line 31

def final(kda)
  stamp(kda)
  o = "tmp/zip/#{base}.pdf"

  system "#{ghostscript} -sOutputFile=#{o} \"#{file}\" #{O2}"
  # copia original se processado for maior
  system "cp \"#{file}\" #{o}" if File.size(o) > size

  C118pdf.new(o, opcoes)
end

#first_pagina?Boolean

Returns primeira pagina?.

Returns:

  • (Boolean)

    primeira pagina?



80
81
82
# File 'lib/arquivo/extrato.rb', line 80

def first_pagina?
  leitor && proxima_pagina && nome_extrato
end

#ghostscriptString

Returns comando PDF language interpreter c118.

Returns:

  • (String)

    comando PDF language interpreter c118



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/arquivo/extrato.rb', line 110

def ghostscript
  # filtrar images para scq e extratos
  fi = /^[se]/i.match?(id) ? ' -dFILTERIMAGE' : ''

  'gs -sDEVICE=pdfwrite ' \
    '-dNOPAUSE -dBATCH -dQUIET ' \
    '-sPAPERSIZE=a4 -dFIXEDMEDIA -dPDFFitPage ' \
    '-dPDFSETTINGS=/screen -dDetectDuplicateImages ' \
    '-dColorImageDownsampleThreshold=1 ' \
    '-dGrayImageDownsampleThreshold=1 ' \
    '-dMonoImageDownsampleThreshold=1' + fi
end

#jpg?(jpg) ⇒ Boolean

Returns scanned pdf?.

Parameters:

  • jpg (String)

    imagem final (se existir)

Returns:

  • (Boolean)

    scanned pdf?



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/arquivo/pdf.rb', line 120

def jpg?(jpg)
  return false if id[0] == 'r'

  o = "tmp/#{id}.txt"
  # se pdf contem texto -> not scanned pdf
  system "pdftotext -q -eol unix -nopgbrk \"#{file}\" #{o}"
  return false if File.size?(o)

  system "pdfimages -q -j \"#{file}\" tmp/#{id}"
  # utilizar somente 1 imagem, comvertida em jpg
  system "convert #{Dir.glob("tmp/#{id}-???.???")[0]} #{jpg} #{O2}"

  # jpg demasiado pequeno -> not scanned pdf
  File.size?(jpg) > LT
end

#leitorEnumerator::Lazy

Returns leitor pdf.

Returns:

  • (Enumerator::Lazy)

    leitor pdf



85
86
87
88
89
# File 'lib/arquivo/extrato.rb', line 85

def leitor
  @leitor ||= PDF::Reader.new(file).pages.lazy
rescue StandardError
  @leitor = nil
end

#marcaObject

cria pdf com selo no canto inferior esquerdo



137
138
139
140
141
142
143
144
145
# File 'lib/arquivo/pdf.rb', line 137

def marca
  # nome pdf com selo determina a ordem das paginas no arquivo final
  o = "tmp/stamped-#{base[/-(\w+)/, 1]}-#{id}.pdf"
  s = '2 2 moveto /Ubuntu findfont 7 scalefont ' \
       "setfont (#{base}) show"
  system "#{ghostscript} -sOutputFile=tmp/stamp-#{id}.pdf -c \"#{s}\";" \
         "pdftk tmp/zip/#{base}.pdf " \
         "stamp tmp/stamp-#{id}.pdf output #{o} #{O2}"
end

#nome_extratoString

Returns nome proximo extrato.

Returns:

  • (String)

    nome proximo extrato



99
100
101
102
103
104
105
106
107
# File 'lib/arquivo/extrato.rb', line 99

def nome_extrato
  return false unless pagina

  @paginas = []
  n = pagina.scan(%r{N\. *(\d+)/(\d+)}).flatten
  @nome = n.empty? ? nil : "ex#{n[1]}-#{n[0]}"
rescue StandardError
  @nome = nil
end

#novo_extrato?Boolean

Returns primeira pagina de extrato?.

Returns:

  • (Boolean)

    primeira pagina de extrato?



70
71
72
# File 'lib/arquivo/extrato.rb', line 70

def novo_extrato?
  pagina_extrato? && pagina.match?(/extrato +combinado/i)
end

#pagina_extrato?Boolean

Returns pagina de extrato?.

Returns:

  • (Boolean)

    pagina de extrato?



75
76
77
# File 'lib/arquivo/extrato.rb', line 75

def pagina_extrato?
  pagina.include?('45463760224')
end

#processa_extrato(cnt) ⇒ Object

segmenta extrato limpando publicidade

Parameters:

  • cnt (Integer)

    contador pagina em processamento



45
46
47
48
49
50
51
52
53
54
# File 'lib/arquivo/extrato.rb', line 45

def processa_extrato(cnt)
  cnt += 1
  @paginas << cnt if pagina_extrato?
  if proxima_pagina
    faz_extrato if novo_extrato?
    processa_extrato(cnt)
  else
    faz_extrato
  end
end

#processa_extrato?Boolean

Returns posso segmentar extrato?.

Returns:

  • (Boolean)

    posso segmentar extrato?



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/arquivo/extrato.rb', line 57

def processa_extrato?
  return true if ext == '.pdf' && size.positive? && !File.exist?(base) &&
                 first_pagina?

  if File.exist?(base)
    puts "erro: #{base} pasta ja existe"
  else
    puts "erro: #{file} nao consigo obter primeira pagina do EXTRATO"
  end
  false
end

#processa_pdf(dad) ⇒ Object

processa pdf para arquivo

Examples:

dad

{"ft1901"=>[["ft1901","legal","assembleia","expediente","-1395"]],
 "ft1944"=>[["ft1944","banco","juro","dc3029998410","100"],
            ["ft1944","banco","irc","dc3029998410","-28"]]}

Parameters:

  • dad (Hash)

    dados oficiais para reclassificacao de faturas e recibos



19
20
21
22
23
24
25
# File 'lib/arquivo/pdf.rb', line 19

def processa_pdf(dad)
  o = "tmp/#{id}-extract.jpg"
  pdf = jpg?(o) ? C118jpg.new(o, opcoes).apara.pdf : self

  # usar trimed pdf somente se for menor que original
  (pdf.size < size ? pdf : self).final(dad[id]).marca
end

#proxima_paginaString

Returns texto duma pagina pdf.

Returns:

  • (String)

    texto duma pagina pdf



92
93
94
95
96
# File 'lib/arquivo/extrato.rb', line 92

def proxima_pagina
  @pagina = leitor.next.text
rescue StopIteration
  @pagina = nil
end

#splitObject

segmenta PDF pelas suas paginas



157
158
159
160
# File 'lib/arquivo/pdf.rb', line 157

def split
  system "pdftk #{file} burst output #{base}/pg%04d-#{base}.pdf;rm -f #{base}/*.txt"
  puts "#{base}-split"
end

#stamp(kda) ⇒ String

Returns texto completo do selo.

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    texto completo do selo



44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/arquivo/pdf.rb', line 44

def stamp(kda)
  stamp_base(kda)
  return unless kda

  stamp_digitos(kda)
  stamp_mb(kda)
  d = stamp_descricao(kda)
  return if d.empty?

  @base += '-' + I18n.transliterate(d, locale: :pt)
                     .gsub(/[ [[:punct:]]]/, '-')
end

#stamp_base(kda) ⇒ String

Returns texto base do selo.

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    texto base do selo



59
60
61
# File 'lib/arquivo/pdf.rb', line 59

def stamp_base(kda)
  @base = id + '-' + stamp_rubrica(kda) + stamp_sha
end

#stamp_descricao(kda) ⇒ String

Returns descricoes dos movimentos contabilidade.

Examples:

kda-rc1911

[[_,_,"quota 2019-Janeiro","glB albino soares","541"],
 [_,_,"quota 2019-Fevereiro","glB albino soares","541"]]

kda-ft1901

[["ft1901","legal","assembleia","expediente","-1395"]]

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    descricoes dos movimentos contabilidade



88
89
90
91
92
93
94
# File 'lib/arquivo/pdf.rb', line 88

def stamp_descricao(kda)
  if id[0] == 'f'
    kda.group_by { |e| e[2] }
  else
    kda.group_by { |e| e[2][/\d{4}-(\w{3})/, 1] }
  end.keys.filter { |e| e }.join('-')
end

#stamp_digitos(kda) ⇒ String

Returns adiciona digitos do valor absoluto do documento.

Examples:

kda-ft1901

[["ft1901","legal","assembleia","expediente","-1395"]]

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    adiciona digitos do valor absoluto do documento



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

def stamp_digitos(kda)
  n = kda.inject(0) { |s, e| s + e[4].to_i }.abs
  @base += '-' + format('%<valor>06d', valor: n)
end

#stamp_mb(kda) ⇒ String

Returns adiciona ids dos movimentos multibanco.

Examples:

kda-ft1904

[["ft1904-mb00016410","material","mangueira","limpeza","-3998"],
 ["ft1904-mb00095312","material","lampadas","sos","-4585"]]

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    adiciona ids dos movimentos multibanco



76
77
78
79
80
# File 'lib/arquivo/pdf.rb', line 76

def stamp_mb(kda)
  d = kda.group_by { |e| e[0][/-(mb\d+)/, 1] }
         .keys.join('-')
  @base += '-' + d unless d.size.zero?
end

#stamp_rubrica(kda) ⇒ String

Returns rubrica dos movimentos contabilidade.

Examples:

kda-ft1901

[["ft1901","legal","assembleia","expediente","-1395"]]

kda-rc1911

[[_,_,"quota 2019-Janeiro","glB albino soares","541"],
 [_,_,"quota 2019-Fevereiro","glB albino soares","541"]]

Parameters:

  • kda (Array)

    lista dados para reclassificacao do documento

Returns:

  • (String)

    rubrica dos movimentos contabilidade



100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/arquivo/pdf.rb', line 100

def stamp_rubrica(kda)
  if kda
    if id[0] == 'f'
      kda.group_by { |e| e[1] }
    else
      # rubrica recibos = id condomino (ex: h3d)
      kda.group_by { |e| e[3][/\w+/] }
    end.keys.join('-')
  else
    base[/-(\w+)/, 1]
  end
end

#stamp_shaString

Returns SHA256 do documento para arquivar.

Returns:

  • (String)

    SHA256 do documento para arquivar



114
115
116
# File 'lib/arquivo/pdf.rb', line 114

def stamp_sha
  '-' + `sha256sum #{file}`[/\w+/]
end