class FileWatch::Ext::XlsxTail
Public Class Methods
new(opts={})
click to toggle source
Calls superclass method
FileWatch::Ext::TailBase::new
# File lib/filewatch/ext/xlsxtail.rb, line 8 def initialize(opts={}) @pos = {} super end
Public Instance Methods
subscribe(&block)
click to toggle source
# File lib/filewatch/ext/xlsxtail.rb, line 14 def subscribe(&block) # subscribe(stat_interval = 1, discover_interval = 5, &block) @watch.subscribe(@opts[:stat_interval], @opts[:discover_interval]) do |event, path| case event when :create, :create_initial if @files.member?(path) @logger.debug("#{event} for #{path}: already exists in @files") next end if _open_file(path, event) _read_file(path, &block) end when :modify @logger.debug(":modify for #{path}") when :delete @logger.debug(":delete for #{path}, deleted from @files") _progressdb_delete(path, &block) if @opts[:progressdb] && @opts[:progressdb_del] @files.delete(path) _sincedb_delete(path) @statcache.delete(path) else @logger.warn("unknown event type #{event} for #{path}") end end # @watch.subscribe end
Private Instance Methods
_open_file(path, event)
click to toggle source
# File lib/filewatch/ext/xlsxtail.rb, line 54 def _open_file(path, event) @logger.debug("_open_file: #{path}: opening") begin @files[path] = SimpleXlsxReader.open(path) rescue # don't emit this message too often. if a file that we can't # read is changing a lot, we'll try to open it more often, # and might be spammy. now = Time.now.to_i if now - @lastwarn[path] > OPEN_WARN_INTERVAL @logger.warn("failed to open #{path}: #{$!}") @lastwarn[path] = now else @logger.debug("(warn supressed) failed to open #{path}: #{$!}") end #@files.delete(path) return false end stat = File::Stat.new(path) size = get_size(path) if @iswindows fileId = Winhelper.GetWindowsUniqueFileIdentifier(path) inode = [fileId, stat.dev_major, stat.dev_minor] else inode = [stat.ino.to_s, stat.dev_major, stat.dev_minor] end @statcache[path] = inode if @sincedb.member?(inode) last_size = @sincedb[inode][:pos] @logger.debug("#{path}: sincedb last value #{@sincedb[inode]}, cur size #{size}") if last_size <= size @logger.debug("#{path}: sincedb: seeking to #{last_size}") @pos[path] = last_size else @logger.debug("#{path}: last value size is greater than current value, starting over") @sincedb[inode] = {:size => size, :pos => 0} end elsif event == :create_initial && @files[path] # TODO(sissel): Allow starting at beginning of the file. if @opts[:start_new_files_at] == :beginning @logger.debug("#{path}: initial create, no sincedb, seeking to beginning of file") @pos[path] = 0 @sincedb[inode] = {:size => size, :pos => 0} else # seek to end @logger.debug("#{path}: initial create, no sincedb, seeking to end #{size}") @pos[path] = size @sincedb[inode] = {:size => size, :pos => size} end elsif event == :create @pos[path] = 0 @sincedb[inode] = {:size => size, :pos => 0} else @logger.debug("#{path}: staying at position 0, no sincedb") end return true end
_read_file(path) { |path, data, :log| ... }
click to toggle source
# File lib/filewatch/ext/xlsxtail.rb, line 118 def _read_file(path, &block) changed = false pos = 0 worksheets = @files[path].sheets worksheets.each_with_index do |worksheet, index_sheet| worksheet.rows.each_with_index do |row, index_row| pos += 1 if pos > @pos[path] changed = true sheet_name = worksheet.name.empty? ? "Sheet#{index_sheet+1}" : worksheet.name if pos == @size #end of file is reached data = {:row => row, :wsname => sheet_name, :eof => true} else data = {:row => row, :wsname => sheet_name, :eof => false} end yield(path, data, :log) @pos[path] = pos @sincedb[@statcache[path]][:pos] = pos _check_sincedb(false, path, &block) end end end _check_sincedb(true, path, &block) if changed end
get_size(path)
click to toggle source
# File lib/filewatch/ext/xlsxtail.rb, line 44 def get_size(path) doc = SimpleXlsxReader.open(path) pos = 0 doc.sheets.each do |worksheet| pos += worksheet.rows.length end @size = pos end