]> git.immae.eu Git - perso/Immae/Projets/Ruby/Monitor.git/blob - windows.rb
Customization of window size
[perso/Immae/Projets/Ruby/Monitor.git] / windows.rb
1 require "time"
2 require "open3"
3
4 class IO
5 def readline_nonblock
6 buffer = ""
7 buffer << read_nonblock(1) while buffer[-1] != "\n"
8 buffer
9 rescue IO::WaitReadable => blocking
10 if (not buffer.empty?)
11 ungetc(buffer)
12 end
13 raise blocking
14 end
15 end
16
17
18 class Ncurses::WINDOW
19 def print_line(str, hscroll=0)
20 revert_color = false
21 str[0,5].match(/\033\[3(.)m/) { |c| #Line starts with an escape sequence. We handle that `a la xterm`
22 Ncurses.init_pair(10, c[1].to_i, Ncurses::COLOR_BLACK)
23 self.attron(Ncurses.COLOR_PAIR(10))
24 revert_color = true
25 str = str[5,str.length]
26 }
27 str = str.gsub("\011"," ")
28 #Any other control char is ignored and escaped
29 str = str.gsub(/[[:cntrl:]]/) { |m|
30 "^"+(m.ord + 64).chr
31 }
32 if(hscroll > 0)
33 strcut = str[hscroll,str.length]
34 if(strcut.nil? or strcut.empty?)
35 str = ""
36 else
37 str = "…"+strcut
38 end
39 end
40 strlen = str.length
41 winlen = self.getmaxx-self.getcurx-1
42 if(strlen <= winlen)
43 self.addstr(str + " "*(winlen-strlen))
44 else
45 self.addstr(str[0,winlen-1]+"…")
46 end
47 if(revert_color)
48 self.attroff(Ncurses.COLOR_PAIR(10))
49 end
50 end
51 end
52
53
54 class List_Win
55 def initialize(sections, size)
56 @params = sections
57 @win = Ncurses::WINDOW.new(0, size*Ncurses.COLS()/100, 0, 0)
58 @win.border(*([0]*8))
59 @win.keypad(true)
60 @win.timeout(1000)
61 @win.refresh()
62 @entry = 0
63 end
64
65 def getch()
66 @win.getch()
67 end
68 def clear()
69 @win.clear()
70 end
71 def resize(x,y)
72 @win.resize(x,y)
73 end
74 def move(x,y)
75 @win.move(x,y)
76 end
77 def refresh()
78 @win.refresh()
79 end
80
81 def print_list(entry=nil)
82 if(not entry.nil?)
83 @entry = entry
84 end
85 i = 0
86 @params.each { |section_name,section|
87 if(@entry == i)
88 @win.attron(Ncurses::A_REVERSE)
89 end
90 @win.move(i+1,1)
91 @win.print_line(section['Name'])
92 if(@entry == i)
93 @win.attroff(Ncurses::A_REVERSE)
94 end
95 i = i+1
96 }
97 @win.border(*([0]*8))
98 @win.move(0,3)
99 @win.addstr("Menu")
100 @win.refresh()
101 end
102 end
103
104 class Buff_Win
105 def initialize(winsize,winpos,params)
106 @params = params
107 @win = Ncurses::WINDOW.new(0, winsize, 0, winpos)
108 @panel = Ncurses::Panel::PANEL.new(@win)
109 if(@params['Type'] == 'oneshot')
110 @buffer = Buffer.new(0)
111 else
112 @buffer = Buffer.new(@params['Buffer'].to_i)
113 end
114 @proc = nil
115 @curr_offset = 0
116 @hscroll = 0
117 update_date()
118
119 spawn_proc()
120 print_buffer()
121 end
122
123 def move_resize(winsize,winpos)
124 newwin = Ncurses::WINDOW.new(0, winsize, 0, winpos)
125 Ncurses::Panel.replace_panel(@panel, newwin)
126 Ncurses.delwin(@win)
127 @win = newwin
128 print_buffer()
129 end
130 def update_date()
131 @last_update = Time.now
132 @date = @last_update.strftime("%F %R:%S")
133 end
134
135 def win_border()
136 @win.border(*([0]*8))
137 win_header()
138 end
139 def win_header()
140 @win.move(0,3)
141 @win.addnstr(@params['Name'],@win.getmaxx-@date.length-10)
142 @win.move(0,@win.getmaxx-@date.length-2)
143 @win.addstr(@date)
144 end
145 def refresh()
146 @win.refresh()
147 end
148 def clear()
149 @win.clear()
150 end
151
152 def show_win()
153 Ncurses::Panel.top_panel(@panel)
154 Ncurses::Panel.update_panels
155 end
156
157 def hscroll(scroll=0)
158 @hscroll += scroll
159 if(@hscroll < 0)
160 @hscroll = 0
161 end
162 if(@hscroll > @buffer.maxlen()-@win.getmaxx+3)
163 @hscroll = @buffer.maxlen()-@win.getmaxx+3
164 end
165 print_buffer()
166 refresh()
167 end
168 def scroll(scroll=0,goto=nil,fact=nil)
169 if (not fact.nil?)
170 scroll = (fact * @win.getmaxy.to_f).to_i
171 elsif (not goto.nil?)
172 @curr_offset = (goto * @buffer.size()).to_i
173 scroll = 0
174 end
175 #@curr_offset -= @win.getmaxy/2
176 @curr_offset += scroll
177 if(@curr_offset < 0)
178 @curr_offset = 0
179 end
180 if(@curr_offset > @buffer.size()-@win.getmaxy+2)
181 @curr_offset = @buffer.size()-@win.getmaxy+2
182 end
183 print_buffer()
184 refresh()
185 end
186
187 def print_buffer()
188 #clear()
189 win_border()
190 j = 1
191 @buffer.yield(@win.getmaxy-2,@curr_offset) { |l,type|
192 @win.move(j,1)
193 if(type == 1) then @win.attron(Ncurses.COLOR_PAIR(1)) end
194 @win.print_line(l,hscroll=@hscroll)
195 if(type == 1) then @win.attroff(Ncurses.COLOR_PAIR(1)) end
196 j = j+1
197 }
198 if(@buffer.has_before?)
199 @win.move(2,@win.getmaxx-1)
200 @win.attron(Ncurses::A_REVERSE)
201 @win.addstr("↑")
202 @win.attroff(Ncurses::A_REVERSE)
203 end
204 if(@buffer.has_after?)
205 @win.move(@win.getmaxy-2,@win.getmaxx-1)
206 @win.attron(Ncurses::A_REVERSE)
207 @win.addstr("↓")
208 @win.attroff(Ncurses::A_REVERSE)
209 end
210 end
211
212 def proc_readlines()
213 begin
214 while true
215 @buffer.push(@proc.readline_nonblock)
216 update_date()
217 end
218 rescue IO::WaitReadable
219 end
220 end
221
222 def update(force=false)
223 if(@params['Type'] == 'continuous')
224 proc_readlines()
225 end
226 if(@params['Type'] == 'oneshot')
227 if(force or (Time.now - @last_update > @params['Periodic'].to_i))
228 @buffer.clear()
229 spawn_proc()
230 clear()
231 end
232 end
233 print_buffer()
234 end
235
236 def spawn_proc()
237 if(@params['Type'] == 'oneshot')
238 update_date()
239 Open3.popen3(@params["Command"]) { |i,o,e,t|
240 while ((not o.eof?) or (not e.eof?))
241 rs = IO.select([o,e],nil)[0]
242 r = (rs[0].eof?)? rs[1] : rs[0]
243
244 if r.fileno == o.fileno
245 @buffer.push(r.readline)
246 elsif r.fileno == e.fileno
247 @buffer.push(r.readline,type=1)
248 end
249 end
250 }
251 elsif(@params['Type'] == 'continuous')
252 @proc = IO.popen(@params["Command"])
253 proc_readlines()
254 end
255 end
256 end
257
258