]> git.immae.eu Git - perso/Immae/Projets/Ruby/Monitor.git/blobdiff - monitor.rb
classes in separate files
[perso/Immae/Projets/Ruby/Monitor.git] / monitor.rb
index 5e32cf28f2d5f83e66e42763f84d50193fc80f87..f61ce9b8d534361191d46d7ae40222c2d6df934d 100644 (file)
@@ -4,6 +4,10 @@ require "time"
 require "ncurses"
 require "inifile"
 require "open3"
+require 'optparse'
+require 'ostruct'
+require_relative 'buffer'
+require_relative 'windows'
 
 class IO
     def readline_nonblock
@@ -18,279 +22,61 @@ class IO
     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
+class OptParse
+  def parse(args)
+    
+    options = OpenStruct.new()
+    options.inifile = nil
 
-  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
+    opt_parser = OptionParser.new() do |opts|
+      
+      opts.banner = "Usage: monitor [options]"
+      opts.separator ""
 
-  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)
+      opts.on( '-f', "-f ini_file", "chose a different initialization file") do |ini|
+        options.inifile = ini
       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()
+    opt_parser.parse!(args)
+    return options
   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()
-    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()
-    if(@params['Type'] == 'continuous')
-      proc_readlines()
-    end
-    if(@params['Type'] == 'oneshot')
-      if(Time.now - @last_update > @params['Periodic'].to_i)
-        @buffer.clear()
-        spawn_proc()
-      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
+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
 
-class Buffer
-  def initialize(size)
-    @size = size
-    @buff = []
-    @buff_type = []
-    @current = 0
-    @wrap = false
-    @before = false
-    @after = false
-  end
-  def size()
-    return @buff.length
+def read_ini(ini)
+  inifile = IniFile.load(ini)
+  if(inifile.nil?)
+    puts "Initialization file not found or not readable"
+    exit
   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)
-    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 read_ini()
-  inifile = IniFile.load('monitorrc')
   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?)
@@ -306,6 +92,9 @@ def print_line(win, str, hscroll=0)
   else
     win.addstr(str[0,winlen-1]+"…")
   end
+  if(revert_color)
+    win.attroff(Ncurses.COLOR_PAIR(10))
+  end
 end
 
 def make_bufwins(inifile)
@@ -335,6 +124,10 @@ def redraw_all(list,bufwins,curr_bufwin)
   list.refresh()
   curr_bufwin.refresh()
 end
+
+
+options = OptParse.new().parse(ARGV)
+inifile = read_ini(find_ini(options.inifile))
 begin
   # initialize ncurses
   Ncurses.initscr
@@ -345,10 +138,9 @@ begin
   #Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt
   Ncurses.stdscr.keypad(true)     # turn on keypad mode
   Ncurses.init_pair(1, Ncurses::COLOR_RED,   Ncurses::COLOR_BLACK)
+  Ncurses.init_pair(10, Ncurses::COLOR_WHITE,   Ncurses::COLOR_BLACK)
 
 
-  inifile = read_ini()
-
   list = List_Win.new(inifile)
   bufwins = make_bufwins(inifile)
   entry = 0
@@ -369,6 +161,8 @@ begin
       list.print_list(entry=entry)
     when 12 #ctrl+L
       redraw_all(list,bufwins,cur_bufwin)
+    when 18 #ctrl+R
+      cur_bufwin.update(force=true)
     when Ncurses::KEY_RESIZE
       redraw_all(list,bufwins,cur_bufwin)
     when Ncurses::KEY_LEFT