gribr 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +42 -0
  5. data/Rakefile +43 -0
  6. data/VERSION +1 -0
  7. data/gribr.gemspec +68 -0
  8. data/lib/gribr/core_ext/file.rb +38 -0
  9. data/lib/gribr/core_ext.rb +1 -0
  10. data/lib/gribr/degrib/cube.rb +15 -0
  11. data/lib/gribr/degrib/file.rb +78 -0
  12. data/lib/gribr/degrib/index.rb +51 -0
  13. data/lib/gribr/degrib/inventory.rb +24 -0
  14. data/lib/gribr/degrib/inventory_record.rb +44 -0
  15. data/lib/gribr/degrib/probe_record.rb +56 -0
  16. data/lib/gribr/degrib.rb +21 -0
  17. data/lib/gribr/executeable.rb +26 -0
  18. data/lib/gribr/inventory.rb +62 -0
  19. data/lib/gribr/utils.rb +23 -0
  20. data/lib/gribr/wgrib/inventory.rb +24 -0
  21. data/lib/gribr/wgrib/inventory_record.rb +51 -0
  22. data/lib/gribr/wgrib.rb +15 -0
  23. data/lib/gribr.rb +6 -0
  24. data/spec/fixtures/wind.grib +0 -0
  25. data/spec/gribr_spec.rb +9 -0
  26. data/spec/lib/gribr/core_ext/file_spec.rb +48 -0
  27. data/spec/lib/gribr/degrib/cube_spec.rb +20 -0
  28. data/spec/lib/gribr/degrib/file_spec.rb +69 -0
  29. data/spec/lib/gribr/degrib/index_spec.rb +83 -0
  30. data/spec/lib/gribr/degrib/inventory_record_spec.rb +121 -0
  31. data/spec/lib/gribr/degrib/inventory_spec.rb +47 -0
  32. data/spec/lib/gribr/degrib/probe_record_spec.rb +103 -0
  33. data/spec/lib/gribr/degrib_spec.rb +17 -0
  34. data/spec/lib/gribr/executeable_spec.rb +25 -0
  35. data/spec/lib/gribr/inventory_spec.rb +21 -0
  36. data/spec/lib/gribr/wgrib/inventory_record_spec.rb +60 -0
  37. data/spec/lib/gribr/wgrib/inventory_spec.rb +17 -0
  38. data/spec/lib/gribr/wgrib_spec.rb +17 -0
  39. data/spec/spec_helper.rb +9 -0
  40. metadata +127 -0
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ *~
2
+ *.sw?
3
+ .DS_Store
4
+ coverage
5
+ doc
6
+ ext
7
+ rdoc
8
+ pkg
9
+ /.yardoc
10
+ /spec/fixtures/wind.dat
11
+ /WIND_09101200.txt
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Roman Scherer
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,42 @@
1
+ = Gribr - Read gridded binary (GRIB) files with Ruby.
2
+
3
+ Gribr is a Ruby library for reading gridded binary (GRIB)
4
+ files. Currently there is only a wrapper around the command line
5
+ program "degrib" available. More to come. See the spec folder for
6
+ examples ...
7
+
8
+ require 'gribr'
9
+
10
+ file = Gribr::Degrib::File.new("spec/fixtures/t12z.HTSGW.grib")
11
+
12
+ # Probe a location and return the records as an array.
13
+ file.probe(43.121, 10.232) #=> Array
14
+
15
+ # Probe a location and yield the records.
16
+ file.probe(43.121, 10.232) do |record|
17
+ puts record
18
+ end
19
+
20
+ # Do we have an index?
21
+ file.indexed? #=> false
22
+
23
+ # Create the index. Probing a location is much faster with an index ...
24
+ file.index!
25
+ file.indexed? #=> true
26
+
27
+ == Note on Patches/Pull Requests
28
+
29
+ * Fork the project.
30
+ * Make your feature addition or bug fix.
31
+ * Add tests for it. This is important so I don't break it in a
32
+ future version unintentionally.
33
+
34
+ * Commit, do not mess with rakefile, version, or history (if you want
35
+ to have your own version, that is fine but bump version in a commit
36
+ by itself I can ignore when I pull).
37
+
38
+ * Send me a pull request. Bonus points for topic branches.
39
+
40
+ == Copyright
41
+
42
+ Copyright (c) 2009 Roman Scherer. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "gribr"
8
+ gem.summary = %Q{Ruby wrapper to read gridded binary (GRIB) files with degrib.}
9
+ gem.description = %Q{Ruby wrapper to read gridded binary (GRIB) files with degrib.}
10
+ gem.email = "roman.scherer@burningswell.com"
11
+ gem.homepage = "http://github.com/r0man/gribr"
12
+ gem.authors = ["Roman Scherer"]
13
+ gem.add_development_dependency "rspec"
14
+ gem.add_development_dependency "yard"
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+ task :default => [:spec]
35
+
36
+ begin
37
+ require 'yard'
38
+ YARD::Rake::YardocTask.new
39
+ rescue LoadError
40
+ task :yardoc do
41
+ abort "YARD is not available. In order to run yardoc, you must: sudo gem install yard"
42
+ end
43
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
data/gribr.gemspec ADDED
@@ -0,0 +1,68 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{gribr}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Roman Scherer"]
12
+ s.date = %q{2009-11-02}
13
+ s.description = %q{Ruby wrapper to read gridded binary (GRIB) files with degrib.}
14
+ s.email = %q{roman.scherer@burningswell.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "gribr.gemspec",
27
+ "lib/gribr.rb",
28
+ "lib/gribr/degrib.rb",
29
+ "lib/gribr/degrib/file.rb",
30
+ "lib/gribr/degrib/inventory_record.rb",
31
+ "lib/gribr/degrib/probe_record.rb",
32
+ "spec/fixtures/wind.grib",
33
+ "spec/gribr_spec.rb",
34
+ "spec/lib/gribr/degrib/file_spec.rb",
35
+ "spec/lib/gribr/degrib/inventory_record_spec.rb",
36
+ "spec/lib/gribr/degrib/probe_record_spec.rb",
37
+ "spec/spec_helper.rb"
38
+ ]
39
+ s.homepage = %q{http://github.com/r0man/gribr}
40
+ s.rdoc_options = ["--charset=UTF-8"]
41
+ s.require_paths = ["lib"]
42
+ s.rubygems_version = %q{1.3.4}
43
+ s.summary = %q{Ruby wrapper to read gridded binary (GRIB) files with degrib.}
44
+ s.test_files = [
45
+ "spec/gribr_spec.rb",
46
+ "spec/lib/gribr/degrib/probe_record_spec.rb",
47
+ "spec/lib/gribr/degrib/inventory_spec.rb",
48
+ "spec/lib/gribr/degrib/inventory_record_spec.rb",
49
+ "spec/lib/gribr/degrib/file_spec.rb",
50
+ "spec/spec_helper.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ s.add_development_dependency(%q<rspec>, [">= 0"])
59
+ s.add_development_dependency(%q<yard>, [">= 0"])
60
+ else
61
+ s.add_dependency(%q<rspec>, [">= 0"])
62
+ s.add_dependency(%q<yard>, [">= 0"])
63
+ end
64
+ else
65
+ s.add_dependency(%q<rspec>, [">= 0"])
66
+ s.add_dependency(%q<yard>, [">= 0"])
67
+ end
68
+ end
@@ -0,0 +1,38 @@
1
+ module Gribr
2
+ module CoreExt
3
+
4
+ module File
5
+
6
+ def self.included(base)
7
+ base.send :include, InstanceMethods
8
+ base.send :extend, ClassMethods
9
+ end
10
+
11
+ module InstanceMethods
12
+
13
+ def exist?
14
+ ::File.exist? path
15
+ end
16
+
17
+ def delete
18
+ ::File.delete path
19
+ end
20
+
21
+ alias_method :unlink, :delete
22
+
23
+ end
24
+
25
+ module ClassMethods
26
+
27
+ def gribfile?(path)
28
+ ::File.open(path.respond_to?(:path) ? path.path : path) { |file| file.read(4) == "GRIB" }
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+
38
+ ::File.send(:include, Gribr::CoreExt::File)
@@ -0,0 +1 @@
1
+ require 'gribr/core_ext/file'
@@ -0,0 +1,15 @@
1
+ module Gribr
2
+ module Degrib
3
+
4
+ class Cube < ::File
5
+
6
+ EXTNAME = "dat".freeze
7
+
8
+ def self.extname
9
+ EXTNAME
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,78 @@
1
+ require 'gribr/degrib/index'
2
+ require 'gribr/degrib/inventory'
3
+
4
+ module Gribr
5
+ module Degrib
6
+
7
+ class File < ::File
8
+
9
+ def initialize(*params)
10
+ super; validate!
11
+ end
12
+
13
+ # Return the degrib index file.
14
+ def index
15
+ @index ||= (indexed? ? Index.new(indexname) : Index.create(self))
16
+ end
17
+
18
+ # Build the degrib index file.
19
+ def index!
20
+ @index = Index.create!(self)
21
+ end
22
+
23
+ # Return true if the degrib index file exists.
24
+ def indexed?
25
+ File.exists?(indexname)
26
+ end
27
+
28
+ # Returns the pathname of the degrib index file.
29
+ def indexname
30
+ path.gsub(Regexp.new("#{File.extname(path)}$"), ".#{Index::EXTNAME}")
31
+ end
32
+
33
+ # Returns the inventory of the file.
34
+ def inventory(options = {})
35
+ @inventory ||= Inventory.file(self)
36
+ end
37
+
38
+ # Probe the grib file at the given location and return/yield the records.
39
+ def probe(latitude, longitude, options = { }, &block)
40
+ probe_one(latitude, longitude, options, &block)
41
+ end
42
+
43
+ protected
44
+
45
+ def probe_one(latitude, longitude, options = { }, &block)
46
+
47
+ records = Array.new
48
+ command = probe_one_command(latitude, longitude, options)
49
+
50
+ IO.popen(command).each_with_index do |line, index|
51
+ next if index == 0
52
+ record = ProbeRecord.parse!(line)
53
+ records << record
54
+ yield(record) if block_given?
55
+ end
56
+
57
+ records
58
+
59
+ end
60
+
61
+ def probe_one_command(latitude, longitude, options = { })
62
+ command = "#{Degrib.executeable.name}"
63
+ command << " #{indexed? ? indexname : path}"
64
+ command << " #{indexed? ? '-DP' : '-P'}"
65
+ command << " -pnt #{latitude},#{longitude}"
66
+ command << " -Unit m"
67
+ command << " -pntStyle 1"
68
+ command
69
+ end
70
+
71
+ def validate!
72
+ raise "Sorry, not a grib file: #{path}" unless self.class.gribfile?(self); ensure; rewind
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+ end
@@ -0,0 +1,51 @@
1
+ require 'gribr/degrib/cube'
2
+
3
+ module Gribr
4
+ module Degrib
5
+
6
+ class Index < ::File
7
+
8
+ EXTNAME = "idx".freeze
9
+
10
+ def delete
11
+ super
12
+ cube.delete if cube.exist?
13
+ end
14
+
15
+ # Returns the cube of the degrib index.
16
+ def cube
17
+ @cube ||= Cube.new(cubename)
18
+ end
19
+
20
+ # Returns the pathname of the degrib cube file.
21
+ def cubename
22
+ path.gsub(Regexp.new("#{File.extname(path)}$"), ".#{Cube.extname}")
23
+ end
24
+
25
+ class << self
26
+
27
+ def command(file)
28
+ file = File.new(file.respond_to?(:path) ? file.path : file) unless file.kind_of?(File)
29
+ "#{Degrib.executeable.name} #{file.path} -Data -Index #{file.indexname}"
30
+ end
31
+
32
+ def create(file)
33
+ gribfile = File.new(file.respond_to?(:path) ? file.path : file)
34
+ system(command(gribfile))
35
+ new(gribfile.indexname) if $? == 0
36
+ end
37
+
38
+ def create!(file)
39
+ create(file) || raise("Can't create degrib index for #{file}.")
40
+ end
41
+
42
+ def extname
43
+ EXTNAME
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require 'gribr/inventory'
2
+ require 'gribr/degrib/inventory_record'
3
+
4
+ module Gribr
5
+ module Degrib
6
+
7
+ class Inventory < Gribr::Inventory
8
+
9
+ class << self
10
+
11
+ def command(file)
12
+ "degrib #{file.respond_to?(:path) ? file.path : file} -I"
13
+ end
14
+
15
+ def parse_record(line)
16
+ InventoryRecord.parse!(line)
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,44 @@
1
+ require 'gribr/utils'
2
+
3
+ module Gribr
4
+ module Degrib
5
+
6
+ class InventoryRecord < Struct.new(:description, :element, :end_position, :level, :number, :start_position, :unit, :reference_time, :valid_time, :version)
7
+
8
+ include Gribr::RegexpParser
9
+
10
+ REGEXP_ELEMENT = Regexp.new('(([^=]+)="(.*\[(.+)\])")').freeze
11
+ REGEXP_FLOAT = Regexp.new('((\+|-)?\d+.?\d*)').freeze
12
+ REGEXP_INTEGER = Regexp.new('(\d+)').freeze
13
+ REGEXP_LEVEL = Regexp.new('([^,]+)').freeze
14
+ REGEXP_TIMESTAMP = Regexp.new('((\d{2})/(\d{2})/(\d{4})\s+(\d{2}):(\d{2}))').freeze
15
+
16
+ def end_position_of_previous
17
+ start_position - 1 if number > 1
18
+ end
19
+
20
+ def self.build(match_data)
21
+
22
+ if match_data
23
+ record = new
24
+ record.number = match_data[1].to_i
25
+ record.start_position = match_data[3].to_i
26
+ record.version = match_data[4].to_i
27
+ record.element = match_data[6]
28
+ record.description = match_data[7]
29
+ record.unit = match_data[8]
30
+ record.level = match_data[9]
31
+ record.reference_time = Time.utc(match_data[13].to_i, match_data[11].to_i, match_data[12].to_i, match_data[14].to_i, match_data[15].to_i)
32
+ record.valid_time = Time.utc(match_data[19].to_i, match_data[17].to_i, match_data[18].to_i, match_data[20].to_i, match_data[21].to_i)
33
+ record
34
+ end
35
+
36
+ end
37
+
38
+ def self.regexp
39
+ @regexp ||= Regexp.new([REGEXP_FLOAT, REGEXP_INTEGER, REGEXP_INTEGER, REGEXP_ELEMENT, REGEXP_LEVEL, REGEXP_TIMESTAMP, REGEXP_TIMESTAMP].join('\s*,\s*')).freeze
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ require 'gribr/utils'
2
+
3
+ module Gribr
4
+ module Degrib
5
+
6
+ class ProbeRecord < Struct.new(:element, :latitude, :longitude, :reference_time, :unit, :valid_time, :value)
7
+
8
+ include RegexpParser
9
+
10
+ REGEXP_ELEMENT = Regexp.new("(.*)").freeze
11
+ REGEXP_FLOAT = Regexp.new("((\\+|-)?\\d+.?\\d*)").freeze
12
+ REGEXP_LOCATION = Regexp.new("((#{REGEXP_FLOAT}),(#{REGEXP_FLOAT}))").freeze
13
+ REGEXP_TIMESTAMP = Regexp.new("(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})").freeze
14
+ REGEXP_UNIT = Regexp.new("([^)]+)").freeze
15
+
16
+ SEPARATOR = "\t".freeze
17
+ TIME_FORMAT = "%Y-%m-%d %H:%M:%S".freeze
18
+
19
+ def to_s(options = {})
20
+ [ latitude.to_s, longitude.to_s, element, unit, format_time(reference_time, options), format_time(valid_time, options), value.to_s ].join(SEPARATOR)
21
+ end
22
+
23
+ protected
24
+
25
+ def format_time(time, options = {})
26
+ time.strftime(options[:time] || TIME_FORMAT)
27
+ end
28
+
29
+ class << self
30
+
31
+ def build(match_data)
32
+
33
+ if match_data
34
+ record = new
35
+ record.latitude = match_data[3].to_f
36
+ record.longitude = match_data[6].to_f
37
+ record.element = match_data[8]
38
+ record.unit = match_data[9]
39
+ record.reference_time = Time.utc(*match_data[10..14].map(&:to_i))
40
+ record.valid_time = Time.utc(*match_data[15..19].map(&:to_i))
41
+ record.value = match_data[20].to_f
42
+ record
43
+ end
44
+
45
+ end
46
+
47
+ def regexp
48
+ @regexp ||= Regexp.new("\\(#{REGEXP_LOCATION}\\),\\s+#{REGEXP_ELEMENT}\\[#{REGEXP_UNIT}\\],\\s+#{REGEXP_TIMESTAMP},\\s+#{REGEXP_TIMESTAMP},\\s+#{REGEXP_FLOAT}").freeze
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ require 'gribr/executeable'
2
+ require 'gribr/degrib/cube'
3
+ require 'gribr/degrib/file'
4
+ require 'gribr/degrib/index'
5
+ require 'gribr/degrib/inventory'
6
+ require 'gribr/degrib/inventory_record'
7
+ require 'gribr/degrib/probe_record'
8
+
9
+ module Gribr
10
+
11
+ module Degrib
12
+
13
+ def self.executeable
14
+ @executeable ||= Executable.new("degrib")
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+
@@ -0,0 +1,26 @@
1
+ module Gribr
2
+
3
+ class Executable
4
+
5
+ attr_reader :name
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ end
10
+
11
+ def exist?
12
+ File.exist?(path)
13
+ end
14
+
15
+ def path
16
+ @path ||= candidates.find { |candidate| File.exists?(candidate) }
17
+ end
18
+
19
+ protected
20
+
21
+ def candidates
22
+ ENV["PATH"].split(":").collect { |path| File.join(path, name) }
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,62 @@
1
+ module Gribr
2
+
3
+ class Inventory
4
+
5
+ def initialize(messages = Array.new)
6
+ @messages = Hash.new
7
+ messages.each { |message| add_message(message) }
8
+ end
9
+
10
+ def add_message(message)
11
+ set_end_position_of_previous(message)
12
+ @messages[message.number] = message
13
+ end
14
+
15
+ def messages
16
+ @messages.values.sort_by(&:number)
17
+ end
18
+
19
+ protected
20
+
21
+ def set_end_position_of_previous(message)
22
+ @messages[message.number - 1].end_position = message.end_position_of_previous if @messages[message.number - 1]
23
+ end
24
+
25
+ class << self
26
+
27
+ def file(file)
28
+ Gribr::Degrib::File.gribfile?(file) ? grib_file(file) : inventory_file(file)
29
+ end
30
+
31
+ def io(io)
32
+
33
+ inventory = new
34
+
35
+ io.each_with_index do |line, index|
36
+
37
+ if index > 0
38
+ message = parse_record(line)
39
+ inventory.add_message(message)
40
+ yield(message) if block_given?
41
+ end
42
+
43
+ end
44
+
45
+ inventory
46
+
47
+ end
48
+
49
+ protected
50
+
51
+ def grib_file(file)
52
+ IO.popen(command(file)) { |io| io(io) }
53
+ end
54
+
55
+ def inventory_file(file)
56
+ ::File.open(file.respond_to?(:path) ? file.path : file) { |file| io(file) }
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,23 @@
1
+ module Gribr
2
+
3
+ module RegexpParser
4
+
5
+ def self.included(base)
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def parse(line)
12
+ build regexp.match(line.to_s)
13
+ end
14
+
15
+ def parse!(line)
16
+ parse(line) || raise(ArgumentError, "Can't parse: #{line}")
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'gribr/inventory'
2
+ require 'gribr/wgrib/inventory_record'
3
+
4
+ module Gribr
5
+ module Wgrib
6
+
7
+ class Inventory < Gribr::Inventory
8
+
9
+ class << self
10
+
11
+ def command(file)
12
+ "wgrib #{file.respond_to?(:path) ? file.path : file} -s"
13
+ end
14
+
15
+ def parse_record(line)
16
+ ShortInventoryRecord.parse!(line)
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end