class WebSandboxConsole::ViewFile

Constants

PageTips

页面相关提示

Attributes

content_is_trimed[RW]
end_line_num[RW]
file_or_dir[RW]
grep_content[RW]
sed_end_time[RW]
sed_start_time[RW]
start_line_num[RW]
touch_grep_protect[RW]

Public Class Methods

new(opts = {}) click to toggle source
# File lib/web_sandbox_console/view_file.rb, line 20
def initialize(opts = {})
  @file_or_dir     = opts[:file_or_dir]
  @start_line_num  = (opts[:start_line_num].presence || 1).to_i
  @end_line_num    = (opts[:end_line_num].presence || 100).to_i
  @sed_start_time  = opts[:sed_start_time]
  @sed_end_time    = opts[:sed_end_time]
  @grep_content    = opts[:grep_content]
  @touch_grep_protect  = false
  @content_is_trimed   = false
  @is_big_file_return  = false
  @special_line_return = false
end

Public Instance Methods

add_line_num(lines) click to toggle source

添加行号

# File lib/web_sandbox_console/view_file.rb, line 217
def add_line_num(lines)
  start_num = is_big_file? ? 1 : start_line_num
  lines.each_with_index.map do |line, index| 
    line = "#{index + start_num}:  #{line}"
    hightlight_grep_content(line)
  end
end
blacklist_all_file_dir_arr() click to toggle source

黑名单 包含自身 及其 子目录/文件

# File lib/web_sandbox_console/view_file.rb, line 85
def blacklist_all_file_dir_arr
  black_lists = WebSandboxConsole.view_file_blacklist
  return [] if black_lists.blank?

  result_arr = black_lists.inject([]) do |result_arr, black_item_path|
    current_path = project_path(black_item_path)

    if is_directory?(current_path)
      result_arr.concat(dir_all_sub_file_or_dir(current_path))
    else
      result_arr
    end
  end
  black_lists.map{|i| project_path(i)}.concat(result_arr)
end
cal_file_total_line_num() click to toggle source

计算文件总行数

# File lib/web_sandbox_console/view_file.rb, line 163
def cal_file_total_line_num
  `wc -l < #{file_or_dir_path}`.to_i
end
check_blacklist() click to toggle source

检查是否为黑名单 文件 / 目录

# File lib/web_sandbox_console/view_file.rb, line 102
def check_blacklist
  black_lists = blacklist_all_file_dir_arr
  raise ViewFileError, '文件或目录无权限查看' if black_lists.include?(file_or_dir_path) || black_lists.include?(file_or_dir_path + '/')
end
check_only_view_log() click to toggle source

检查 仅能查看日志

# File lib/web_sandbox_console/view_file.rb, line 108
def check_only_view_log
  if WebSandboxConsole.only_view_log_file
    raise ViewFileError, '仅可查看日志目录/文件' unless file_or_dir.split("/")[0] == 'log'
  end
end
check_param() click to toggle source

检查参数

# File lib/web_sandbox_console/view_file.rb, line 47
def check_param
  raise ViewFileError, '文件或目录参数不能为空' if file_or_dir.blank?
  raise ViewFileError, "过滤内容中不能出现单引号" if grep_content.to_s.include?("'")
end
content_trim(lines) click to toggle source

修剪过滤内容

# File lib/web_sandbox_console/view_file.rb, line 206
def content_trim(lines)
  if lines.length > 1000
    @content_is_trimed = true
    # 内容太多时 只返回前1000行
    lines.first(1000)
  else
    lines
  end
end
correction_line_num() click to toggle source

纠正起始行数

# File lib/web_sandbox_console/view_file.rb, line 53
def correction_line_num
  if @start_line_num > @end_line_num
    @end_line_num = @start_line_num + 100
  end
end
dir_all_sub_file_or_dir(current_dir) click to toggle source

目录下所有子文件 目录

# File lib/web_sandbox_console/view_file.rb, line 80
def dir_all_sub_file_or_dir(current_dir)
  Dir["#{current_dir}**/*"]
end
file_or_dir_exists() click to toggle source

是否存在

# File lib/web_sandbox_console/view_file.rb, line 70
def file_or_dir_exists
  raise ViewFileError, '文件或目录不存在' unless File.exists?(file_or_dir_path)
end
file_or_dir_path() click to toggle source

绝对路径

# File lib/web_sandbox_console/view_file.rb, line 65
def file_or_dir_path
  "#{Rails.root}/#{file_or_dir}"
end
files_in_dir() click to toggle source

目录下文件

# File lib/web_sandbox_console/view_file.rb, line 115
def files_in_dir
  lines = Dir["#{file_or_dir_path}/*"].map do |path|
    path += is_directory?(path) ? '(目录)' : '(文件)'
    path[file_or_dir_path.length..-1]
  end
  {lines: lines}
end
grep_file_content() click to toggle source

过滤文件

# File lib/web_sandbox_console/view_file.rb, line 194
def grep_file_content
  content = if @sed_start_time && @grep_content.present?
    grep_timeout_protect {`sed -n '/#{@sed_start_time}/,/#{@sed_end_time}/p' #{file_or_dir_path} | fgrep '#{@grep_content}'`}
  elsif @sed_start_time
    grep_timeout_protect {`sed -n '/#{@sed_start_time}/,/#{@sed_end_time}/p' #{file_or_dir_path}`}
  else
    grep_timeout_protect {`fgrep '#{@grep_content}' #{file_or_dir_path}`}
  end
  content.split("\n")
end
grep_timeout_protect() { || ... } click to toggle source

过滤超时保护

# File lib/web_sandbox_console/view_file.rb, line 183
def grep_timeout_protect
  begin
    Timeout::timeout(8) {yield}
  rescue Timeout::Error => e
    # 触发过滤保护
    @touch_grep_protect = true
    tail_any_line_content(1000)
  end
end
hightlight_grep_content(content) click to toggle source

高亮内容

# File lib/web_sandbox_console/view_file.rb, line 226
def hightlight_grep_content(content)
  if @grep_content.present?
    content.gsub(@grep_content.to_s, "<span style='color: #E35520;'> #{@grep_content}</span>").html_safe
  else
    content
  end
end
is_big_file?() click to toggle source

是否为大文件

# File lib/web_sandbox_console/view_file.rb, line 124
def is_big_file?
  File.new(file_or_dir_path).size > 10.megabytes
end
is_directory?(path) click to toggle source

是目录?

# File lib/web_sandbox_console/view_file.rb, line 75
def is_directory?(path)
  File.directory?(path)
end
need_grep?() click to toggle source

是否需要过滤

# File lib/web_sandbox_console/view_file.rb, line 129
def need_grep?
  @sed_start_time || @grep_content.present?
end
project_path(path) click to toggle source

转换成项目路径

# File lib/web_sandbox_console/view_file.rb, line 60
def project_path(path)
  "#{Rails.root}/#{path}"
end
special_line_content() click to toggle source

按指定行返回

# File lib/web_sandbox_console/view_file.rb, line 178
def special_line_content
  File.readlines(file_or_dir_path)[(start_line_num - 1)..(end_line_num - 1)]
end
tail_any_line(num) click to toggle source

最后 xx 行

# File lib/web_sandbox_console/view_file.rb, line 168
def tail_any_line(num)
  tail_any_line_content(num).split("\n")
end
tail_any_line_content(num) click to toggle source

最后多少行内容

# File lib/web_sandbox_console/view_file.rb, line 173
def tail_any_line_content(num)
  `tail -n #{num} #{file_or_dir_path}`
end
view() click to toggle source
# File lib/web_sandbox_console/view_file.rb, line 33
def view
  begin
    check_param
    correction_line_num
    file_or_dir_exists
    check_blacklist
    check_only_view_log
    view_file
  rescue ViewFileError => e
    {lines: [e.message]}
  end
end
view_file() click to toggle source

查看文件/目录

# File lib/web_sandbox_console/view_file.rb, line 134
def view_file
  if is_directory?(file_or_dir_path)
    files_in_dir
  else # 文件
    parse_start_and_end_time
    lines = if need_grep?
      grep_file_content
    elsif is_big_file?
      @is_big_file_return = true
      tail_any_line(1000)
    else
      @special_line_return = true
      special_line_content
    end
    # 修剪行数
    lines = content_trim(lines)

    {
      lines: add_line_num(lines), 
      total_line_num: cal_file_total_line_num,
      touch_grep_protect: @touch_grep_protect,
      content_is_trimed: @content_is_trimed,
      is_big_file_return: @is_big_file_return,
      special_line_return: @special_line_return
    }
  end
end

Private Instance Methods

datetime_formatter() click to toggle source

解析日期格式

# File lib/web_sandbox_console/view_file.rb, line 251
def datetime_formatter
  logger_datetime_is_default_formatter ? "%FT%T" : "%F %T"
end
logger_datetime_is_default_formatter() click to toggle source

日志时间格式是否为标准格式

# File lib/web_sandbox_console/view_file.rb, line 243
def logger_datetime_is_default_formatter
  # 抽取日志的第二行
  logger_line   = `head -n 2 #{file_or_dir_path} | tail -n 1`
  datatime_part = logger_line.split(/DEBUG:|INFO:|WARN:|ERROR:|FATAL:|UNKNOWN:/).first.to_s
  datatime_part.include?("T")
end
parse_start_and_end_time() click to toggle source

解析时间

# File lib/web_sandbox_console/view_file.rb, line 236
def parse_start_and_end_time
  formatter = datetime_formatter
  @sed_start_time = DateTime.parse(@sed_start_time).strftime(formatter) rescue nil
  @sed_end_time   = DateTime.parse(@sed_end_time).strftime(formatter) rescue nil
end