library/log/src/modules/LogViewCore.rb
# ***************************************************************************
#
# Copyright (c) 2002 - 2012 Novell, Inc.
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, contact Novell, Inc.
#
# To contact Novell about this file by physical or electronic mail,
# you may find current contact information at www.novell.com
#
# ***************************************************************************
# File: modules/LogViewCore.ycp
# Package: YaST2
# Summary: Displaying a log
# Authors: Jiri Srain <jsrain@suse.cz>
# Arvin Schnell <aschnell@suse.de>
#
# $Id: LogViewCore.ycp 45503 2008-03-17 09:46:23Z aschnell $
require "yast"
require "shellwords"
module Yast
class LogViewCoreClass < Module
def main
Yast.import "UI"
textdomain "base"
Yast.import "Report"
# default value of maximum displayed lines
@max_lines_default = 100
# lines of the log
@lines = []
# data describing log:
# file: filename to read from
# grep: grep file with expression
# command: command to run (use instead of file and grep)
# max_lines: max lines to keep (0 -> infinite)
@data = {}
# id of background process
@id = nil
# flag indicating if background process is (or should be) running
@is_running = false
end
def GetNewLines
return [] if !@is_running
if !Convert.to_boolean(SCR.Read(path(".process.running"), @id))
@is_running = false
Report.Error(_("Error occurred while reading the log."))
return []
end
new_lines = []
loop do
line = Convert.to_string(SCR.Read(path(".process.read_line"), @id))
break if line.nil?
new_lines = Builtins.add(new_lines, line)
end
deep_copy(new_lines)
end
# Remove unneeded items from a list of lines
# If max_lines is 0, then don't remove anything
def DeleteOldLines
max_lines = Ops.get_integer(@data, "max_lines", @max_lines_default)
return if max_lines == 0
if Ops.greater_than(
Ops.subtract(Ops.subtract(Builtins.size(@lines), max_lines), 1),
0
)
@lines = Builtins.sublist(
@lines,
Ops.subtract(Ops.subtract(Builtins.size(@lines), max_lines), 1)
)
end
nil
end
# Starts the log reading command via process agent.
#
# The LogView widget must exist when calling this function. The `MaxLines
# parameter of the widget will be set.
def Start(widget, data)
widget = deep_copy(widget)
data = deep_copy(data)
if !@id.nil?
SCR.Execute(path(".process.release"), @id)
@id = nil
end
@data = deep_copy(data)
file = Ops.get_string(@data, "file", "")
grep = Ops.get_string(@data, "grep", "")
command = Ops.get_string(@data, "command", "")
max_lines = Ops.get_integer(@data, "max_lines", @max_lines_default)
if command == ""
if grep == ""
command = Builtins.sformat("/usr/bin/tail -n %1 -f %2",
max_lines.to_s.shellescape, file.shellescape)
else
command = Builtins.sformat(
"tail -n +0 -f %1 | grep --line-buffered %2",
file.shellescape,
grep.shellescape
)
if max_lines != 0
lc_command = Builtins.sformat(
"/usr/bin/grep -c %2 %1",
file.shellescape,
grep.shellescape
)
bash_output = Convert.to_map(
SCR.Execute(path(".target.bash_output"), lc_command)
)
if Ops.get_integer(bash_output, "exit", 1) == 0
lc = Builtins.filterchars(
Ops.get_string(bash_output, "stdout", ""),
"1234567890"
)
lines_count = Builtins.tointeger(lc)
# don't know why without doubling it discards more lines,
# out of YaST2 it works
lines_count = Ops.subtract(
lines_count,
Ops.multiply(2, max_lines)
)
lines_count = 0 if Ops.less_than(lines_count, 0)
command << Builtins.sformat(" | tail -n +%1", lines_count.to_s.shellescape) if Ops.greater_than(lines_count, 0)
end
end
end
end
Builtins.y2milestone("Calling process agent with command %1", command)
@id = Convert.to_integer(
SCR.Execute(path(".process.start_shell"), command, "tty" => true)
)
@is_running = true
Builtins.sleep(100)
@lines = GetNewLines()
DeleteOldLines()
UI.ChangeWidget(widget, :MaxLines, max_lines)
UI.ChangeWidget(
widget,
:Value,
Builtins.mergestring(Builtins.maplist(@lines) do |line|
Ops.add(line, "\n")
end, "")
)
nil
end
def Update(widget)
widget = deep_copy(widget)
if !@id.nil?
new_lines = GetNewLines()
if Ops.greater_than(Builtins.size(new_lines), 0)
@lines = Convert.convert(
Builtins.merge(@lines, new_lines),
from: "list",
to: "list <string>"
)
DeleteOldLines()
UI.ChangeWidget(
widget,
:LastLine,
Builtins.mergestring(Builtins.maplist(new_lines) do |line|
Ops.add(line, "\n")
end, "")
)
end
end
nil
end
def Stop
if !@id.nil?
SCR.Execute(path(".process.release"), @id)
@id = nil
end
nil
end
def GetLines
deep_copy(@lines)
end
publish function: :Start, type: "void (term, map <string, any>)"
publish function: :Update, type: "void (term)"
publish function: :Stop, type: "void ()"
publish function: :GetLines, type: "list <string> ()"
end
LogViewCore = LogViewCoreClass.new
LogViewCore.main
end