ltsvr 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ltsvr.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 ongaeshi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,82 @@
1
+ # ltsvr - LTSV viewer for Ruby
2
+
3
+ LTSV Viewer made with Ruby.
4
+
5
+ * Select label `-k host,ua`, `-i time,req`
6
+ * Filtering keyword `-f ua=Mozilla`
7
+ * Go to LTSV website `--web`
8
+
9
+ Inspired by [ltsview](https://github.com/naoya/perl-Text-LTSV/blob/master/bin/ltsview).
10
+
11
+
12
+ ## Installation
13
+
14
+ $ gem install ltsvr
15
+
16
+ ## Usage
17
+
18
+ $ ltsvr -h
19
+ ltsvr [OPTION] [FILE]...
20
+ -k, --keywords LABEL Display keywords (-k host,ua)
21
+ -i, --ignore-keywords LABEL Ignore keywords (-i time,req)
22
+ -f, --filter FILTER Filtering keywords (-f host=192.168.1.1,ua=Mozilla)
23
+ --web Go to website (http://ltsv.org)
24
+
25
+ ## Sample
26
+
27
+ Specify LTSV file.
28
+
29
+ ```
30
+ $ ltsvr /path/to/log
31
+ host:127.0.0.1, ident:-, user:frank, time:[10/Oct/2000:13:55:36 -0700], req:GET /apache_pb.gif HTTP/1.0, status:200, size:2326, referer:http://www.example.com/start.html, ua:Mozilla/4.08 [en] (Win98; I ;Nav)
32
+ host:127.0.0.2, ident:-, user:mike, time:[10/Oct/2000:13:55:36 -0700], req:GET /apache_pb.gif HTTP/1.0, status:200, size:2326, referer:http://www.example.com/start.html, ua:Mozilla/4.08 [en] (Win98; I ;Nav)
33
+ host:127.0.0.3, ident:-, user:takashi, time:[10/Oct/2000:13:55:36 -0700], req:GET /apache_pb.gif HTTP/1.0, status:200, size:2326, referer:http://www.example.com/start.html, ua:Mozilla/4.08 [en] (Win98; I ;Nav)
34
+ host:127.0.0.4, ident:-, user:frank, time:[10/Oct/2000:13:55:36 -0700], req:GET /apache_pb.gif HTTP/1.0, status:200, size:2326, referer:http://www.example.com/index.html, ua:Mozilla/4.08 [en] (Win98; I ;Nav)
35
+ ```
36
+
37
+ Select label.
38
+
39
+ ```
40
+ $ ltsvr /path/to/log -k host,user
41
+ host:127.0.0.1, user:frank
42
+ host:127.0.0.2, user:mike
43
+ host:127.0.0.3, user:takashi
44
+ host:127.0.0.4, user:frank
45
+ ```
46
+
47
+ Filtering option.
48
+
49
+ ```
50
+ $ ltsvr /path/to/log -k host,user -f user=frank
51
+ host:127.0.0.1, user:frank
52
+ host:127.0.0.4, user:frank
53
+ ```
54
+
55
+ Ignore label.
56
+
57
+ ```
58
+ $ ltsvr /path/to/log -i host,ident,status,time,req,size,ua -f referer=start.html
59
+ user:frank, referer:http://www.example.com/start.html
60
+ user:mike, referer:http://www.example.com/start.html
61
+ user:takashi, referer:http://www.example.com/start.html
62
+ ```
63
+
64
+ Use pipe.
65
+
66
+ ```
67
+ $ tail -f /path/to/log | ltsvr -f user=takashi
68
+ ```
69
+
70
+ Go to LTSV website. (Launch Browser)
71
+
72
+ ```
73
+ $ ltsvr --web
74
+ ```
75
+
76
+ ## Contributing
77
+
78
+ 1. Fork it
79
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
80
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
81
+ 4. Push to the branch (`git push origin my-new-feature`)
82
+ 5. Create new Pull Request
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.test_files = FileList['test/**/test_*.rb']
7
+ test.verbose = true
8
+ end
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'ltsvr'
4
+
5
+ Ltsvr::CLI.execute(STDOUT, ARGV)
@@ -0,0 +1,6 @@
1
+ require "ltsvr/version"
2
+ require "ltsvr/cli"
3
+
4
+ module Ltsvr
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,139 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief
5
+ # @author ongaeshi
6
+ # @date 2013/02/16
7
+
8
+ require 'rubygems'
9
+ require 'ltsv'
10
+ require 'optparse'
11
+ require 'launchy'
12
+
13
+ module Ltsvr
14
+ class CLI
15
+ def self.execute(stdout, arguments=[])
16
+ options = {}
17
+ options[:keywords] = []
18
+ options[:ignore_keywords] = []
19
+ options[:filters] = []
20
+
21
+ opts = OptionParser.new("#{File.basename($0)} [OPTION] [FILE]...")
22
+ opts.on("-k LABEL", "--keywords" , "Display keywords (-k host,ua)") {|v| options[:keywords] << v }
23
+ opts.on("-i LABEL", "--ignore-keywords", "Ignore keywords (-i time,req)") {|v| options[:ignore_keywords] << v }
24
+ opts.on("-f FILTER", "--filter" , "Filtering keywords (-f host=192.168.1.1,ua=Mozilla)") {|v| options[:filters] << v }
25
+ opts.on("--web" , "Go to website (http://ltsv.org)") {|v| options[:web] = true }
26
+ opts.parse!(arguments)
27
+
28
+ if options[:web]
29
+ Launchy.open('http://ltsv.org')
30
+ return
31
+ end
32
+
33
+ obj = Ltsvr.new(options)
34
+
35
+ if File.pipe?($stdin)
36
+ while line = $stdin.gets
37
+ result = obj.parse_line(line)
38
+ stdout.puts result if result
39
+ end
40
+ elsif arguments.empty?
41
+ stdout.puts opts.help
42
+ else
43
+ arguments.each do |filename|
44
+ io = open(filename)
45
+ while line = io.gets
46
+ result = obj.parse_line(line)
47
+ stdout.puts result if result
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+
54
+ class Ltsvr
55
+ def initialize(options)
56
+ @options = options
57
+ compile
58
+ end
59
+
60
+ def parse_line(line)
61
+ hash = LTSV.parse(line)[0] || {}
62
+
63
+ # filter
64
+ return nil unless @filters.all? {|filter| filter.match? hash}
65
+
66
+ # keywords
67
+ result = {}
68
+
69
+ if @keywords.empty?
70
+ result = hash
71
+ else
72
+ @keywords.each do |k|
73
+ result[k] = hash[k]
74
+ end
75
+ end
76
+
77
+ # ignore_keywords
78
+ @ignore_keywords.each do |k|
79
+ result.delete(k)
80
+ end
81
+
82
+ # result
83
+ result_str(result)
84
+ end
85
+
86
+ private
87
+
88
+ def compile
89
+ @filters = compile_filter
90
+ @keywords = compile_keywords
91
+ @ignore_keywords = compile_ignore_keywords
92
+ # p [@filters, @keywords, @ignore_keywords]
93
+ end
94
+
95
+ def compile_filter
96
+ @options[:filters].reduce([]) do |result, v|
97
+ result + v.split(",").map do |data|
98
+ d = data.split("=")
99
+ Filter.new(d[0], d[1])
100
+ end
101
+ end
102
+ end
103
+
104
+ def compile_keywords
105
+ @options[:keywords].reduce([]) do |result, v|
106
+ result + v.split(",").map{|a|a.intern}
107
+ end
108
+ end
109
+
110
+ def compile_ignore_keywords
111
+ @options[:ignore_keywords].reduce([]) do |result, v|
112
+ result + v.split(",").map{|a|a.intern}
113
+ end
114
+ end
115
+
116
+ def result_str(hash)
117
+ result = []
118
+
119
+ hash.each do |key, value|
120
+ result << "#{key}:#{value}"
121
+ end
122
+
123
+ result.join(", ")
124
+ end
125
+
126
+ end
127
+
128
+ class Filter
129
+ def initialize(label, value)
130
+ @label = label.intern
131
+ @value = value
132
+ end
133
+
134
+ def match?(hash)
135
+ hash[@label] && hash[@label].match(@value)
136
+ end
137
+ end
138
+
139
+ end
@@ -0,0 +1,3 @@
1
+ module Ltsvr
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ltsvr/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "ltsvr"
8
+ gem.version = Ltsvr::VERSION
9
+ gem.authors = ["ongaeshi"]
10
+ gem.email = ["ongaeshi0621@gmail.com"]
11
+ gem.description = %q{LTSV Viewer made with Ruby. Select label. Filtering keyword. Go to LTSV website.}
12
+ gem.summary = %q{LTSV viewer for Ruby}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency 'ltsv'
21
+ gem.add_dependency 'launchy'
22
+ end
@@ -0,0 +1,4 @@
1
+ host:127.0.0.1 ident:- user:frank time:[10/Oct/2000:13:55:36 -0700] req:GET /apache_pb.gif HTTP/1.0 status:200 size:2326 referer:http://www.example.com/start.html ua:Mozilla/4.08 [en] (Win98; I ;Nav)
2
+ host:127.0.0.2 ident:- user:mike time:[10/Oct/2000:13:55:36 -0700] req:GET /apache_pb.gif HTTP/1.0 status:200 size:2326 referer:http://www.example.com/start.html ua:Mozilla/4.08 [en] (Win98; I ;Nav)
3
+ host:127.0.0.3 ident:- user:takashi time:[10/Oct/2000:13:55:36 -0700] req:GET /apache_pb.gif HTTP/1.0 status:200 size:2326 referer:http://www.example.com/start.html ua:Mozilla/4.08 [en] (Win98; I ;Nav)
4
+ host:127.0.0.1 ident:- user:frank time:[10/Oct/2000:13:55:36 -0700] req:GET /apache_pb.gif HTTP/1.0 status:200 size:2326 referer:http://www.example.com/index.html ua:Mozilla/4.08 [en] (Win98; I ;Nav)
@@ -0,0 +1,52 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief ファイルテスト用ユーティリティ
5
+ # @author ongaeshi
6
+ # @date 2011/02/21
7
+ #
8
+ # 使い方:
9
+ #
10
+ # class TestCdstk < Test::Unit::TestCase
11
+ # include FileTestUtils
12
+ # end
13
+ #
14
+ # すると以下のことを自動でやってくれます
15
+ #
16
+ # 1. tmpディレクトリの作成
17
+ # 2. tmpディレクトリに移動
18
+ # 3. テスト実行
19
+ # 4. 元のディレクトリに戻る
20
+ # 5. tmpディレクトリの削除
21
+ #
22
+
23
+ require 'fileutils'
24
+
25
+ module FileTestUtils
26
+ def setup
27
+ create_tmp_dir
28
+ FileUtils.cd(@tmp_dir)
29
+ end
30
+
31
+ def teardown
32
+ teardown_custom(true)
33
+ end
34
+
35
+ def teardown_custom(is_remove_dir)
36
+ FileUtils.cd(@prev_dir)
37
+ FileUtils.rm_rf(@tmp_dir) if (is_remove_dir)
38
+ end
39
+
40
+ def tmp_path(path)
41
+ File.join @tmp_dir, path
42
+ end
43
+
44
+ private
45
+
46
+ def create_tmp_dir
47
+ @prev_dir = Dir.pwd
48
+ @tmp_dir = File.join(File.dirname(__FILE__), "tmp")
49
+ FileUtils.rm_rf(@tmp_dir)
50
+ FileUtils.mkdir_p(@tmp_dir)
51
+ end
52
+ end
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief
5
+ # @author ongaeshi
6
+ # @date 2013/02/17
7
+
8
+ require 'ltsvr/cli'
9
+ require 'test_helper'
10
+
11
+ module Ltsvr
12
+ class TestCLI < Test::Unit::TestCase
13
+ def setup
14
+ @string_io = StringIO.new
15
+ end
16
+
17
+ def teardown
18
+ end
19
+
20
+ def test_no_arg
21
+ assert_match /--filter/, command("")
22
+ end
23
+
24
+ def test_file_specify
25
+ r = command(TEST_LTSV).split("\n")
26
+ assert_equal 4, r.size
27
+ end
28
+
29
+ def test_filter
30
+ r = command("#{TEST_LTSV} -f user=takashi").split("\n")
31
+ assert_equal 1, r.size
32
+ assert_match /takashi/, r[0]
33
+ end
34
+
35
+ def test_filter_multi
36
+ r = command("#{TEST_LTSV} -f user=frank,referer=index").split("\n")
37
+ assert_equal 1, r.size
38
+ assert_match /index.html/, r[0]
39
+ end
40
+
41
+ def test_filter_multi_arguments
42
+ r = command("#{TEST_LTSV} -f user=frank,referer=index -f ua=Mozilla").split("\n")
43
+ assert_equal 1, r.size
44
+ assert_match /index.html/, r[0]
45
+ end
46
+
47
+ def test_keywords
48
+ r = command("#{TEST_LTSV} -k host,user").split("\n")
49
+ assert_equal "host:127.0.0.1, user:frank", r[0]
50
+ end
51
+
52
+ def test_keywords_multi
53
+ r = command("#{TEST_LTSV} -k host -k user").split("\n")
54
+ assert_equal "host:127.0.0.1, user:frank", r[0]
55
+ end
56
+
57
+ def test_ignore_keywords
58
+ r = command("#{TEST_LTSV} -i ua,referer,time -i ident,req,size").split("\n")
59
+ assert_equal "host:127.0.0.1, user:frank, status:200", r[0]
60
+ end
61
+
62
+ private
63
+
64
+ def command(arg)
65
+ CLI.execute(@string_io, arg.split)
66
+ @string_io.string
67
+ end
68
+
69
+ TEST_LTSV = File.join(File.dirname(__FILE__), "data/test.ltsv")
70
+ end
71
+ end
72
+
73
+
@@ -0,0 +1,29 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # @file
4
+ # @brief
5
+ # @author ongaeshi
6
+ # @date 2013/02/17
7
+
8
+ require 'ltsvr/cli'
9
+ require 'test_helper'
10
+
11
+ module Ltsvr
12
+ class TestFilter < Test::Unit::TestCase
13
+ def test_match?
14
+ hash = {:host=>"127.0.0.1", :ident=>"-", :user=>"frank", :time=>"[10/Oct/2000:13:55:36 -0700]", :req=>"GET /apache_pb.gif HTTP/1.0", :status=>"200", :size=>"2326", :referer=>"http://www.example.com/start.html", :ua=>"Mozilla/4.08 [en] (Win98; I ;Nav)"}
15
+
16
+ assert Filter.new("host", "127.0.0.1").match?(hash)
17
+ assert Filter.new(:host, "127.0.0.1").match?(hash) # Support symbol
18
+ assert !Filter.new("host", "127.0.0.2").match?(hash)
19
+ assert Filter.new("user", "frank").match?(hash)
20
+ assert Filter.new("time", "2000").match?(hash) # Sub match
21
+ assert !Filter.new("time", "2001").match?(hash)
22
+ assert Filter.new("ua", "Mozilla").match?(hash)
23
+ end
24
+ end
25
+ end
26
+
27
+
28
+
29
+
@@ -0,0 +1,3 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'file_test_utils'
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ltsvr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - ongaeshi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ltsv
16
+ requirement: &2152872300 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *2152872300
25
+ - !ruby/object:Gem::Dependency
26
+ name: launchy
27
+ requirement: &2152871880 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *2152871880
36
+ description: LTSV Viewer made with Ruby. Select label. Filtering keyword. Go to LTSV
37
+ website.
38
+ email:
39
+ - ongaeshi0621@gmail.com
40
+ executables:
41
+ - ltsvr
42
+ extensions: []
43
+ extra_rdoc_files: []
44
+ files:
45
+ - .gitignore
46
+ - Gemfile
47
+ - LICENSE.txt
48
+ - README.md
49
+ - Rakefile
50
+ - bin/ltsvr
51
+ - lib/ltsvr.rb
52
+ - lib/ltsvr/cli.rb
53
+ - lib/ltsvr/version.rb
54
+ - ltsvr.gemspec
55
+ - test/data/test.ltsv
56
+ - test/file_test_utils.rb
57
+ - test/test_cli.rb
58
+ - test/test_filter.rb
59
+ - test/test_helper.rb
60
+ homepage: ''
61
+ licenses: []
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ! '>='
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.11
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: LTSV viewer for Ruby
84
+ test_files:
85
+ - test/data/test.ltsv
86
+ - test/file_test_utils.rb
87
+ - test/test_cli.rb
88
+ - test/test_filter.rb
89
+ - test/test_helper.rb
90
+ has_rdoc: