Class: WebSandboxConsole::ViewFile

Inherits:
Object
  • Object
show all
Defined in:
lib/web_sandbox_console/view_file.rb

Constant Summary collapse

PageTips =

页面相关提示

{
  touch_grep_protect: "由于过滤执行时间太长,已触发过滤保护,返回内容为最后1000行",
  content_is_trimed: "当前返回内容太多,仅展示满足条件的1000行",
  is_big_file_return: "当前文件视为大文件,返回最后1000行",
  special_line_return: "当前按指定行数返回,若未指定行数,则默认返回文件前100行"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ ViewFile

Returns a new instance of ViewFile.



20
21
22
23
24
25
26
27
28
29
30
31
# 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

Instance Attribute Details

#content_is_trimedObject

内容是否有裁剪



10
11
12
# File 'lib/web_sandbox_console/view_file.rb', line 10

def content_is_trimed
  @content_is_trimed
end

#end_line_numObject

结束行数



5
6
7
# File 'lib/web_sandbox_console/view_file.rb', line 5

def end_line_num
  @end_line_num
end

#file_or_dirObject

文件或目录



3
4
5
# File 'lib/web_sandbox_console/view_file.rb', line 3

def file_or_dir
  @file_or_dir
end

#grep_contentObject

过滤内容



8
9
10
# File 'lib/web_sandbox_console/view_file.rb', line 8

def grep_content
  @grep_content
end

#sed_end_timeObject

结束时间



7
8
9
# File 'lib/web_sandbox_console/view_file.rb', line 7

def sed_end_time
  @sed_end_time
end

#sed_start_timeObject

开始时间



6
7
8
# File 'lib/web_sandbox_console/view_file.rb', line 6

def sed_start_time
  @sed_start_time
end

#start_line_numObject

起始行数



4
5
6
# File 'lib/web_sandbox_console/view_file.rb', line 4

def start_line_num
  @start_line_num
end

#touch_grep_protectObject

是否触发过滤保护



9
10
11
# File 'lib/web_sandbox_console/view_file.rb', line 9

def touch_grep_protect
  @touch_grep_protect
end

Instance Method Details

#add_line_num(lines) ⇒ Object

添加行号



217
218
219
220
221
222
223
# 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_arrObject

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



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# 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_numObject

计算文件总行数



163
164
165
# 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_blacklistObject

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

Raises:



102
103
104
105
# 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_logObject

检查 仅能查看日志



108
109
110
111
112
# 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_paramObject

检查参数

Raises:



47
48
49
50
# 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) ⇒ Object

修剪过滤内容



206
207
208
209
210
211
212
213
214
# 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_numObject

纠正起始行数



53
54
55
56
57
# 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) ⇒ Object

目录下所有子文件 目录



80
81
82
# 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_existsObject

是否存在

Raises:



70
71
72
# 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_pathObject

绝对路径



65
66
67
# File 'lib/web_sandbox_console/view_file.rb', line 65

def file_or_dir_path
  "#{Rails.root}/#{file_or_dir}"
end

#files_in_dirObject

目录下文件



115
116
117
118
119
120
121
# 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_contentObject

过滤文件



194
195
196
197
198
199
200
201
202
203
# 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_protectObject

过滤超时保护



183
184
185
186
187
188
189
190
191
# 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) ⇒ Object

高亮内容



226
227
228
229
230
231
232
# 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?Boolean

是否为大文件

Returns:

  • (Boolean)


124
125
126
# 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) ⇒ Boolean

是目录?

Returns:

  • (Boolean)


75
76
77
# File 'lib/web_sandbox_console/view_file.rb', line 75

def is_directory?(path)
  File.directory?(path)
end

#need_grep?Boolean

是否需要过滤

Returns:

  • (Boolean)


129
130
131
# File 'lib/web_sandbox_console/view_file.rb', line 129

def need_grep?
  @sed_start_time || @grep_content.present?
end

#project_path(path) ⇒ Object

转换成项目路径



60
61
62
# File 'lib/web_sandbox_console/view_file.rb', line 60

def project_path(path)
  "#{Rails.root}/#{path}"
end

#special_line_contentObject

按指定行返回



178
179
180
# 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) ⇒ Object

最后 xx 行



168
169
170
# 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) ⇒ Object

最后多少行内容



173
174
175
# File 'lib/web_sandbox_console/view_file.rb', line 173

def tail_any_line_content(num)
  `tail -n #{num} #{file_or_dir_path}`
end

#viewObject



33
34
35
36
37
38
39
40
41
42
43
44
# 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_fileObject

查看文件/目录



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# 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