X-Git-Url: https://git.immae.eu/?p=perso%2FImmae%2FProjets%2FRuby%2FMonitor.git;a=blobdiff_plain;f=monitor.rb;h=249e2a3c7d63cfb93f1f66ff0a5ff8a043ad176d;hp=09f9e59cf8bb109f157d6fa5fe4fbb65fb5d4ea8;hb=HEAD;hpb=cfddfd90ca8df888683529fcf683958da0894b10 diff --git a/monitor.rb b/monitor.rb index 09f9e59..c2a57f8 100644 --- a/monitor.rb +++ b/monitor.rb @@ -1,378 +1,18 @@ #!/usr/bin/env ruby -require "time" require "ncurses" -require "inifile" -require "open3" -require 'optparse' -require 'ostruct' +require_relative 'ini_read' +require_relative 'windows' +require_relative 'buffer' -class IO - def readline_nonblock - buffer = "" - buffer << read_nonblock(1) while buffer[-1] != "\n" - buffer - rescue IO::WaitReadable => blocking - if (not buffer.empty?) - ungetc(buffer) - end - raise blocking - end -end - -class OptParse - def parse(args) - - options = OpenStruct.new() - options.inifile = nil - - opt_parser = OptionParser.new() do |opts| - - opts.banner = "Usage: monitor [options]" - opts.separator "" - - opts.on( '-f', "-f ini_file", "chose a different initialization file") do |ini| - options.inifile = ini - end - end - opt_parser.parse!(args) - return options - end -end - -class List_Win - def initialize(inifile) - @params = inifile - @win = Ncurses::WINDOW.new(0, Ncurses.COLS()/4, 0, 0) - @win.border(*([0]*8)) - @win.keypad(true) - @win.timeout(1000) - @win.refresh() - @entry = 0 - end - - def getch() - @win.getch() - end - def clear() - @win.clear() - end - def resize(x,y) - @win.resize(x,y) - end - def move(x,y) - @win.move(x,y) - end - def refresh() - @win.refresh() - end - - def print_list(entry=nil) - if(not entry.nil?) - @entry = entry - end - i = 0 - @params.each_section do |section| - if(@entry == i) - @win.attron(Ncurses::A_REVERSE) - end - @win.move(i+1,1) - print_line(@win,@params[section]['Name']) - if(@entry == i) - @win.attroff(Ncurses::A_REVERSE) - end - i = i+1 - end - @win.border(*([0]*8)) - @win.move(0,3) - @win.addstr("Menu") - @win.refresh() - end -end - -class Buff_Win - def initialize(winsize,winpos,params) - @params = params - @win = Ncurses::WINDOW.new(0, winsize, 0, winpos) - @panel = Ncurses::Panel::PANEL.new(@win) - if(@params['Type'] == 'oneshot') - @buffer = Buffer.new(0) - else - @buffer = Buffer.new(@params['Buffer'].to_i) - end - @proc = nil - @curr_offset = 0 - @hscroll = 0 - update_date() - - spawn_proc() - print_buffer() - end - - def move_resize(winsize,winpos) - newwin = Ncurses::WINDOW.new(0, winsize, 0, winpos) - Ncurses::Panel.replace_panel(@panel, newwin) - Ncurses.delwin(@win) - @win = newwin - print_buffer() - end - def update_date() - @last_update = Time.now - @date = @last_update.strftime("%F %R:%S") - end - - def win_border() - @win.border(*([0]*8)) - win_header() - end - def win_header() - @win.move(0,3) - @win.addnstr(@params['Name'],@win.getmaxx-@date.length-10) - @win.move(0,@win.getmaxx-@date.length-2) - @win.addstr(@date) - end - def refresh() - @win.refresh() - end - def clear() - @win.clear() - end - - def show_win() - Ncurses::Panel.top_panel(@panel) - Ncurses::Panel.update_panels - end - - def hscroll(scroll=0) - @hscroll += scroll - if(@hscroll < 0) - @hscroll = 0 - end - if(@hscroll > @buffer.maxlen()-@win.getmaxx+3) - @hscroll = @buffer.maxlen()-@win.getmaxx+3 - end - print_buffer() - refresh() - end - def scroll(scroll=0,goto=nil,fact=nil) - if (not fact.nil?) - scroll = (fact * @win.getmaxy.to_f).to_i - elsif (not goto.nil?) - @curr_offset = (goto * @buffer.size()).to_i - scroll = 0 - end - #@curr_offset -= @win.getmaxy/2 - @curr_offset += scroll - if(@curr_offset < 0) - @curr_offset = 0 - end - if(@curr_offset > @buffer.size()-@win.getmaxy+2) - @curr_offset = @buffer.size()-@win.getmaxy+2 - end - print_buffer() - refresh() - end - - def print_buffer() - #clear() - win_border() - j = 1 - @buffer.yield(@win.getmaxy-2,@curr_offset) { |l,type| - @win.move(j,1) - if(type == 1) then @win.attron(Ncurses.COLOR_PAIR(1)) end - print_line(@win,l,hscroll=@hscroll) - if(type == 1) then @win.attroff(Ncurses.COLOR_PAIR(1)) end - j = j+1 - } - if(@buffer.has_before?) - @win.move(2,@win.getmaxx-1) - @win.attron(Ncurses::A_REVERSE) - @win.addstr("↑") - @win.attroff(Ncurses::A_REVERSE) - end - if(@buffer.has_after?) - @win.move(@win.getmaxy-2,@win.getmaxx-1) - @win.attron(Ncurses::A_REVERSE) - @win.addstr("↓") - @win.attroff(Ncurses::A_REVERSE) - end - end - - def proc_readlines() - begin - while true - @buffer.push(@proc.readline_nonblock) - update_date() - end - rescue IO::WaitReadable - end - end - - def update(force=false) - if(@params['Type'] == 'continuous') - proc_readlines() - end - if(@params['Type'] == 'oneshot') - if(force or (Time.now - @last_update > @params['Periodic'].to_i)) - @buffer.clear() - spawn_proc() - clear() - end - end - print_buffer() - end - - def spawn_proc() - if(@params['Type'] == 'oneshot') - update_date() - Open3.popen3(@params["Command"]) { |i,o,e,t| - while ((not o.eof?) or (not e.eof?)) - rs = IO.select([o,e],nil)[0] - r = (rs[0].eof?)? rs[1] : rs[0] - - if r.fileno == o.fileno - @buffer.push(r.readline) - elsif r.fileno == e.fileno - @buffer.push(r.readline,type=1) - end - end - } - elsif(@params['Type'] == 'continuous') - @proc = IO.popen(@params["Command"]) - proc_readlines() - end - end -end - -class Buffer - def initialize(size) - @size = size - @buff = [] - @buff_type = [] - @current = 0 - @wrap = false - @before = false - @after = false - end - def size() - return @buff.length - end - def maxlen() - maxlen = 0 - @buff.each do |string| - if string.length > maxlen - maxlen = string.length - end - end - return maxlen - end - - def push(string,type=0) - if(string.chomp.empty?) then string = " " end - string.split( /\r?\n/ ).each do |line| - @buff[@current] = line - @buff_type[@current] = type - if(@size > 0) - @current = (1+@current) % @size - else - @current = 1+@current - end - if(@current == 0) then @wrap = true end - end - end - def yield(size,offset=0,&block) - if(size < 0) then size = 0 end - range = Range.new(0,@current-1).to_a - if(@wrap) - range = Range.new(@current,@size-1).to_a + range - end - range = range.last(size+offset)[0,size] - @before = (size+offset < @buff.length) - @after = (offset != 0 and size < @buff.length) - if(block) - range.each do |i| - yield [@buff[i],@buff_type[i]] - end - else - return range.collect{|r| [@buff[r],@buff_type[r]]} - end - end - def has_after?() - return @after - end - def has_before?() - return @before - end - def clear() - @current = 0 - @buff = [] - @buff_type = [] - end -end - -def find_ini(option_inifile) - if(not option_inifile.nil?) - inifile = option_inifile - elsif(ENV.has_key?('MONITOR_RC')) - inifile = ENV['MONITOR_RC'] - elsif(Process.uid == 0) - inifile = "/etc/monitor.rc" - else - inifile = ENV['HOME']+"/.monitorrc" - end - return inifile -end - -def read_ini(ini) - inifile = IniFile.load(ini) - if(inifile.nil?) - puts "Initialization file not found or not readable" - exit - end - return inifile -end - -def print_line(win, str, hscroll=0) - revert_color = false - str[0,5].match(/\033\[3(.)m/) { |c| #Line starts with an escape sequence. We handle that `a la xterm` - Ncurses.init_pair(10, c[1].to_i, Ncurses::COLOR_BLACK) - win.attron(Ncurses.COLOR_PAIR(10)) - revert_color = true - str = str[5,str.length] - } - str = str.gsub("\011"," ") - #Any other control char is ignored and escaped - str = str.gsub(/[[:cntrl:]]/) { |m| - "^"+(m.ord + 64).chr - } - if(hscroll > 0) - strcut = str[hscroll,str.length] - if(strcut.nil? or strcut.empty?) - str = "" - else - str = "…"+strcut - end - end - strlen = str.length - winlen = win.getmaxx-win.getcurx-1 - if(strlen <= winlen) - win.addstr(str + " "*(winlen-strlen)) - else - win.addstr(str[0,winlen-1]+"…") - end - if(revert_color) - win.attroff(Ncurses.COLOR_PAIR(10)) - end -end - -def make_bufwins(inifile) +def make_bufwins(sections,size) bufwins = [] - inifile.each_section do |section| - bufwin = Buff_Win.new(Ncurses.COLS()-Ncurses.COLS()/4, - Ncurses.COLS()/4, - inifile[section]) + sections.each { |section_name,section| + bufwin = Buff_Win.new(Ncurses.COLS()-size*Ncurses.COLS()/100, + size*Ncurses.COLS()/100, + section) bufwins.push(bufwin) - end + } return bufwins end @@ -382,11 +22,11 @@ def update_buffers(bufwins) end end -def redraw_all(list,bufwins,curr_bufwin) +def redraw_all(list,bufwins,curr_bufwin, size) bufwins.each do |bufwin| - bufwin.move_resize(Ncurses.COLS()-Ncurses.COLS()/4,Ncurses.COLS()/4) + bufwin.move_resize(Ncurses.COLS()-size*Ncurses.COLS()/100,size*Ncurses.COLS()/100) end - list.resize(Ncurses.LINES(), Ncurses.COLS()/4) + list.resize(Ncurses.LINES(), size*Ncurses.COLS()/100) list.clear() list.print_list() list.refresh() @@ -394,8 +34,7 @@ def redraw_all(list,bufwins,curr_bufwin) end -options = OptParse.new().parse(ARGV) -inifile = read_ini(find_ini(options.inifile)) +inistruct = Ini_read.new() begin # initialize ncurses Ncurses.initscr @@ -409,8 +48,8 @@ begin Ncurses.init_pair(10, Ncurses::COLOR_WHITE, Ncurses::COLOR_BLACK) - list = List_Win.new(inifile) - bufwins = make_bufwins(inifile) + list = List_Win.new(inistruct.sections, inistruct.global['list_size']) + bufwins = make_bufwins(inistruct.sections, inistruct.global['list_size']) entry = 0 cur_bufwin = bufwins[entry] cur_bufwin.show_win() @@ -428,11 +67,11 @@ begin cur_bufwin.show_win() list.print_list(entry=entry) when 12 #ctrl+L - redraw_all(list,bufwins,cur_bufwin) + redraw_all(list,bufwins,cur_bufwin, inistruct.global['list_size']) when 18 #ctrl+R cur_bufwin.update(force=true) when Ncurses::KEY_RESIZE - redraw_all(list,bufwins,cur_bufwin) + redraw_all(list,bufwins,cur_bufwin, inistruct.global['list_size']) when Ncurses::KEY_LEFT cur_bufwin.hscroll(scroll=-1) when Ncurses::KEY_RIGHT