class Arquivo::C118pdf

permite processar documentos PDF

permite processar documentos PDF

Attributes

base[R]

@return [String] base do documento

ext[R]

@return [String] extensao do documento

file[R]

@return [String] nome do documento

id[R]

@return [String] id do documento ft/rc/ex/sc <numero>

nome[R]

@return [String] nome extrato

opcoes[R]

@return [Hash] opcoes parametrizar JPG

pagina[R]

@return [String] texto pagina

paginas[R]

@return [Array<Integer>] lista paginas do extrato

size[R]

@return [Integer] tamanho do documento

Public Class Methods

new(pdf, opt) click to toggle source

@param [String] pdf PDF c118 @param opt (see C118jpg#initialize) @option opt (see C118jpg#initialize) @return [C118pdf] PDF c118

# 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

Public Instance Methods

faz_dashboard() click to toggle source

cria PDF do dashboard

# 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_extrato() click to toggle source

cria PDF do extrato

# 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) click to toggle source

@param [Array] kda lista dados para reclassificacao do documento @return [C118pdf] pdf totalmente processado @example kda-ft1901

[["ft1901","legal","assembleia","expediente","-1395"]]
# 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?() click to toggle source

@return [Boolean] primeira pagina?

# File lib/arquivo/extrato.rb, line 80
def first_pagina?
  leitor && proxima_pagina && nome_extrato
end
ghostscript() click to toggle source

@return [String] comando PDF language interpreter c118

# 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) click to toggle source

@param [String] jpg imagem final (se existir) @return [Boolean] scanned pdf?

# 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
leitor() click to toggle source

@return [Enumerator::Lazy] leitor pdf

# File lib/arquivo/extrato.rb, line 85
def leitor
  @leitor ||= PDF::Reader.new(file).pages.lazy
rescue StandardError
  @leitor = nil
end
marca() click to toggle source

cria pdf com selo no canto inferior esquerdo

# 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_extrato() click to toggle source

@return [String] nome proximo extrato

# 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?() click to toggle source

@return [Boolean] primeira pagina de extrato?

# File lib/arquivo/extrato.rb, line 70
def novo_extrato?
  pagina_extrato? && pagina.match?(/extrato +combinado/i)
end
pagina_extrato?() click to toggle source

@return [Boolean] pagina de extrato?

# File lib/arquivo/extrato.rb, line 75
def pagina_extrato?
  pagina.include?('45463760224')
end
processa_extrato(cnt) click to toggle source

@!group segmentacao segmenta extrato limpando publicidade

@param [Integer] cnt contador pagina em processamento

# 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?() click to toggle source

@return [Boolean] posso segmentar extrato?

# 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) click to toggle source

@!group processamento processa pdf para arquivo

@param [Hash] dad dados oficiais para reclassificacao de faturas e recibos @example dad

{"ft1901"=>[["ft1901","legal","assembleia","expediente","-1395"]],
 "ft1944"=>[["ft1944","banco","juro","dc3029998410","100"],
            ["ft1944","banco","irc","dc3029998410","-28"]]}
# 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_pagina() click to toggle source

@return [String] texto duma pagina pdf

# File lib/arquivo/extrato.rb, line 92
def proxima_pagina
  @pagina = leitor.next.text
rescue StopIteration
  @pagina = nil
end
split() click to toggle source

segmenta PDF pelas suas paginas

# 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) click to toggle source

@param kda (see final) @return [String] texto completo do selo

# 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) click to toggle source

@param kda (see final) @return [String] texto base do selo

# File lib/arquivo/pdf.rb, line 59
def stamp_base(kda)
  @base = id + '-' + stamp_rubrica(kda) + stamp_sha
end
stamp_descricao(kda) click to toggle source

@param kda (see final) @return [String] descricoes dos movimentos contabilidade @example kda-rc1911

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

@example kda-ft1901 (see final)

# 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) click to toggle source

@param kda (see final) @return [String] adiciona digitos do valor absoluto do documento @example kda-ft1901 (see final)

# 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) click to toggle source

@param kda (see final) @return [String] adiciona ids dos movimentos multibanco @example kda-ft1904

[["ft1904-mb00016410","material","mangueira","limpeza","-3998"],
 ["ft1904-mb00095312","material","lampadas","sos","-4585"]]
# 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) click to toggle source

@param kda (see final) @return [String] rubrica dos movimentos contabilidade @example kda-ft1901 (see final) @example kda-rc1911 (see stamp_descricao)

# 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_sha() click to toggle source

@return [String] SHA256 do documento para arquivar

# File lib/arquivo/pdf.rb, line 114
def stamp_sha
  '-' + `sha256sum #{file}`[/\w+/]
end