jse 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ === 0.1.0 / 2010-06-30
2
+
3
+ * Initial release
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2010 Ryan Burrows
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ LICENSE
2
+ README.md
3
+ History.txt
4
+ Manifest.txt
5
+ bin/jse
6
+ lib/jse.rb
7
+ lib/jse/cli.rb
8
+ lib/jse/field_value_transform.rb
9
+ lib/jse/filter.rb
10
+ lib/jse/regexp_filter.rb
11
+ lib/jse/stream.rb
12
+ lib/jse/subset_transform.rb
13
+ lib/jse/to_json_transform.rb
14
+ lib/jse/version.rb
@@ -0,0 +1,24 @@
1
+ # jse: Json Stream Editor
2
+
3
+ jse allows for filtering and transforming of json streams. It is
4
+ mainly designed for mining information out of json log files.
5
+
6
+ ## Usage
7
+
8
+ Use the `jse` command
9
+
10
+ ### Filtering based on field values
11
+
12
+ `jse field1:value field2:'another value' file.txt`
13
+
14
+ ### Regexp filtering on fields
15
+
16
+ `jse field:/^pattern.+$/ file.txt`
17
+
18
+ ### Printing selected fields
19
+
20
+ `jse message:/Error/ -f message log.txt`
21
+
22
+ ## Installation
23
+
24
+ `gem install jse`
data/bin/jse ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'rubygems'
4
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/jse')
5
+ require 'jse/cli'
6
+
7
+ JSE::CLI.execute(STDOUT, ARGV)
@@ -0,0 +1,12 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__))
3
+
4
+ require 'jse/stream'
5
+ require 'jse/filter'
6
+ require 'jse/regexp_filter'
7
+ require 'jse/subset_transform'
8
+ require 'jse/to_json_transform'
9
+ require 'jse/field_value_transform'
10
+
11
+ module JSE
12
+ end
@@ -0,0 +1,49 @@
1
+ require 'optparse'
2
+
3
+ module JSE
4
+ module CLI
5
+ def self.execute(stdout, arguments = [])
6
+ print = []
7
+ parser = OptionParser.new do |opts|
8
+ opts.banner = <<-BANNER.gsub(/^[ \t]*/, '')
9
+ Json Stream Editor.
10
+
11
+ Usage: #{File.basename($0)} [options]
12
+
13
+ Options are:
14
+ BANNER
15
+ opts.separator ""
16
+ opts.on("-f", "--fields a,b,c", Array,
17
+ "List of fields to return") do |fields|
18
+ print = fields
19
+ end
20
+ opts.on("-h", "--help",
21
+ "Show this help message.") { stdout.puts opts; exit }
22
+ opts.parse!(arguments)
23
+ end
24
+
25
+ if File.exist?(arguments.last)
26
+ stream = JSE::Stream.new(File.open(arguments.pop, 'r'))
27
+ else
28
+ stream = JSE::Stream.new(STDIN)
29
+ end
30
+
31
+ arguments.each do |arg|
32
+ field, text = arg.split(':')
33
+ stream.filter!(field, text)
34
+ end
35
+
36
+ unless print.empty?
37
+ stream.print!(*print)
38
+ end
39
+
40
+ begin
41
+ stream.each_line do |line|
42
+ stdout.puts line
43
+ end
44
+ rescue Errno::EPIPE
45
+ # Catch broken pipes so we can use head etc.
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,11 @@
1
+ module JSE
2
+ class FieldValueTransform
3
+ def initialize(field)
4
+ @field = field
5
+ end
6
+
7
+ def apply(hash)
8
+ hash[@field]
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module JSE
2
+ class Filter
3
+ def initialize(field, text)
4
+ @field, @text = field, text
5
+ end
6
+
7
+ def match?(json)
8
+ json[@field] == @text
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ module JSE
2
+ class RegexpFilter
3
+ def initialize(field, regexp)
4
+ @field = field
5
+ # regexp should have leading and trailing '/'
6
+ @regexp = Regexp.new(regexp[1,regexp.size-2])
7
+ end
8
+
9
+ def match?(json)
10
+ json[@field] =~ @regexp
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,91 @@
1
+ require 'json'
2
+
3
+ module JSE
4
+ class Stream
5
+ attr_accessor :filters, :transforms
6
+ attr_reader :inner
7
+
8
+ def initialize(inner)
9
+ @inner = inner
10
+ @transforms = []
11
+ @filters = []
12
+ end
13
+
14
+ def each_line
15
+ inner.each_line do |line|
16
+ unless filter_chain.eliminates?(line)
17
+ yield transform_chain.apply(line)
18
+ end
19
+ end
20
+ end
21
+
22
+ def filter!(field, text)
23
+ if looks_like_regexp?(text)
24
+ filters << RegexpFilter.new(field, text)
25
+ else
26
+ filters << Filter.new(field, text)
27
+ end
28
+ end
29
+
30
+ def print!(*field_list)
31
+ if field_list.size == 1
32
+ transforms << FieldValueTransform.new(field_list[0])
33
+ else
34
+ transforms << SubsetTransform.new(*field_list)
35
+ transforms << ToJsonTransform.new
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def looks_like_regexp?(string)
42
+ string[0,1] == '/' && string[string.size-1,1] == '/'
43
+ end
44
+
45
+ def transform_chain
46
+ TransformChain.new(transforms)
47
+ end
48
+
49
+ class TransformChain
50
+ def initialize(transforms)
51
+ @transforms = transforms
52
+ end
53
+
54
+ def apply(line)
55
+ begin
56
+ if @transforms.empty?
57
+ line
58
+ else
59
+ json = JSON.parse(line)
60
+ @transforms.inject(json){ |j, transform| transform.apply(j) }
61
+ end
62
+ rescue JSON::ParserError
63
+ $stderr.puts "Error parsing line:"
64
+ $stderr.puts line
65
+ true
66
+ end
67
+ end
68
+ end
69
+
70
+ def filter_chain
71
+ FilterChain.new(filters)
72
+ end
73
+
74
+ class FilterChain
75
+ def initialize(filters)
76
+ @filters = filters
77
+ end
78
+
79
+ def eliminates?(line)
80
+ begin
81
+ json = JSON.parse(line)
82
+ !@filters.all?{ |f| f.match?(json) }
83
+ rescue JSON::ParserError
84
+ $stderr.puts "Error parsing line:"
85
+ $stderr.puts line
86
+ true
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,14 @@
1
+ module JSE
2
+ class SubsetTransform
3
+ def initialize(*fields)
4
+ @fields = fields
5
+ end
6
+
7
+ def apply(json)
8
+ @fields.inject({}) do |result, field|
9
+ result[field] = json[field]
10
+ result
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module JSE
2
+ class ToJsonTransform
3
+ def apply(obj)
4
+ obj.to_json
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module JSE
2
+ VERSION = '0.1.0'
3
+ end
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jse
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Ryan Burrows
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-06-30 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: json
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ - !ruby/object:Gem::Dependency
33
+ name: rspec
34
+ prerelease: false
35
+ requirement: &id002 !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ segments:
40
+ - 0
41
+ version: "0"
42
+ type: :development
43
+ version_requirements: *id002
44
+ - !ruby/object:Gem::Dependency
45
+ name: cucumber
46
+ prerelease: false
47
+ requirement: &id003 !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ segments:
52
+ - 0
53
+ version: "0"
54
+ type: :development
55
+ version_requirements: *id003
56
+ - !ruby/object:Gem::Dependency
57
+ name: fakefs
58
+ prerelease: false
59
+ requirement: &id004 !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ segments:
64
+ - 0
65
+ version: "0"
66
+ type: :development
67
+ version_requirements: *id004
68
+ description: " JsonStreamEditor allows manipulation of streams of json\n"
69
+ email: rhburrows@gmail.com
70
+ executables:
71
+ - jse
72
+ extensions: []
73
+
74
+ extra_rdoc_files: []
75
+
76
+ files:
77
+ - LICENSE
78
+ - README.md
79
+ - History.txt
80
+ - Manifest.txt
81
+ - bin/jse
82
+ - lib/jse.rb
83
+ - lib/jse/cli.rb
84
+ - lib/jse/field_value_transform.rb
85
+ - lib/jse/filter.rb
86
+ - lib/jse/regexp_filter.rb
87
+ - lib/jse/stream.rb
88
+ - lib/jse/subset_transform.rb
89
+ - lib/jse/to_json_transform.rb
90
+ - lib/jse/version.rb
91
+ has_rdoc: true
92
+ homepage: http://github.com/rhburrows/jse
93
+ licenses: []
94
+
95
+ post_install_message:
96
+ rdoc_options: []
97
+
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ segments:
112
+ - 1
113
+ - 3
114
+ - 6
115
+ version: 1.3.6
116
+ requirements: []
117
+
118
+ rubyforge_project:
119
+ rubygems_version: 1.3.6
120
+ signing_key:
121
+ specification_version: 3
122
+ summary: Stream editor for JSON streams
123
+ test_files: []
124
+