jse 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+