sqed 0.3.2 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 764316ed1537a871299cafd5c1f1df6045c525ec
4
- data.tar.gz: ebc12360ba5d9eabe0b895c4238d7785bb1d8d4f
3
+ metadata.gz: 97003b6e21e84313180a638df393052b18a7eb25
4
+ data.tar.gz: e125134f5ed864b06fd4b8280228261e7d1eac40
5
5
  SHA512:
6
- metadata.gz: dcee70b54a7cc400fcdf220de15f2c79a479102cb0fa1cd57e6e81ca9e4d92247c9a40fad717f43051adaae40d30c511be4eff3dcd84e60baf7bdad5eef7e189
7
- data.tar.gz: e191bbc0ca11a86c0ec7a6a06bf0068a0cfa78e97766e6533f1182bb9e6f73c790fbd3ff7ba3702910b1dc8749554cba779664d509700d40e81107f941be0ba7
6
+ metadata.gz: cd0e7287ef11ba6fef8784be32c24898784125dde881e2b8082b15d1f19a5995c55e434924057f2bdd8ef27419a51b9e118351f20ebbff594b9a7d7e4f500a6b
7
+ data.tar.gz: 2e87fa5f7e6cd1bb0f5db13158e6c5e41e812a547cd2f90f44ce5104de8105d6595a60c86a2794ff5804615a5a5659da51c9daaed5ede8236661d0a85fb39c0b
@@ -1 +1 @@
1
- 2.3.1
1
+ 2.4.3
@@ -0,0 +1,66 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ ## Uncomment and set this to only include directories you want to watch
5
+ # directories %w(app lib config test spec features) \
6
+ # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
+
8
+ ## Note: if you are using the `directories` clause above and you are not
9
+ ## watching the project directory ('.'), then you will want to move
10
+ ## the Guardfile to a watched dir and symlink it back, e.g.
11
+ #
12
+ # $ mkdir config
13
+ # $ mv Guardfile config/
14
+ # $ ln -s config/Guardfile .
15
+ #
16
+ # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
+
18
+ guard :minitest do
19
+ # with Minitest::Unit
20
+ watch(%r{^test/(.*)\/?test_(.*)\.rb$})
21
+ watch(%r{^lib/(.*/)?([^/]+)\.rb$}) { |m| "test/#{m[1]}test_#{m[2]}.rb" }
22
+ watch(%r{^test/test_helper\.rb$}) { 'test' }
23
+
24
+ # with Minitest::Spec
25
+ # watch(%r{^spec/(.*)_spec\.rb$})
26
+ # watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
27
+ # watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
28
+
29
+ end
30
+
31
+ # Note: The cmd option is now required due to the increasing number of ways
32
+ # rspec may be run, below are examples of the most common uses.
33
+ # * bundler: 'bundle exec rspec'
34
+ # * bundler binstubs: 'bin/rspec'
35
+ # * spring: 'bin/rspec' (This will use spring if running and you have
36
+ # installed the spring binstubs per the docs)
37
+ # * zeus: 'zeus rspec' (requires the server to be started separately)
38
+ # * 'just' rspec: 'rspec'
39
+
40
+ guard :rspec, cmd: "bundle exec rspec" do
41
+ require "guard/rspec/dsl"
42
+ dsl = Guard::RSpec::Dsl.new(self)
43
+
44
+ # Feel free to open issues for suggestions and improvements
45
+
46
+ # RSpec files
47
+ rspec = dsl.rspec
48
+ watch(rspec.spec_helper) { rspec.spec_dir }
49
+ watch(rspec.spec_support) { rspec.spec_dir }
50
+ watch(rspec.spec_files)
51
+
52
+ # Ruby files
53
+ ruby = dsl.ruby
54
+ dsl.watch_spec_files_for(ruby.lib_files)
55
+
56
+ # Turnip features and steps
57
+ # watch(%r{^spec/acceptance/(.+)\.feature$})
58
+ # watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
59
+ # Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
60
+ # end
61
+ end
62
+
63
+ # guard :rubocop do
64
+ # watch(%r{.+\.rb$})
65
+ # watch(%r{(?:.+/)?\.rubocop\.yml$}) { |m| File.dirname(m[0]) }
66
+ # end
@@ -1,12 +1,12 @@
1
1
  # encoding: UTF-8
2
2
 
3
- recent_ruby = RUBY_VERSION >= '2.1.1'
4
- raise "IMPORTANT: sqed gem requires ruby >= 2.1.1" unless recent_ruby
3
+ recent_ruby = RUBY_VERSION >= '2.4.1'
4
+ raise 'IMPORTANT: sqed gem requires ruby >= 2.4.1' unless recent_ruby
5
5
 
6
- require "rmagick"
6
+ require 'rmagick'
7
7
 
8
8
  # Instances take the following
9
- # 1) A base image @image
9
+ # 1) An :image @image
10
10
  # 2) A target extraction pattern, or individually specified attributes
11
11
  #
12
12
  # Return a Sqed::Result
@@ -17,85 +17,78 @@ require "rmagick"
17
17
  class Sqed
18
18
 
19
19
  require_relative 'sqed_config'
20
- require_relative "sqed/extractor"
21
- require_relative "sqed/result"
20
+ require_relative 'sqed/extractor'
21
+ require_relative 'sqed/result'
22
22
 
23
23
  # initial image which is an instance of ImageMagick::Image, containing background and stage, or just stage
24
24
  attr_accessor :image
25
25
 
26
- # !optional! A lookup macro that if provided sets boundary_finder, layout, and metadata_map. These can be individually overwritten.
26
+ # !optional! A lookup macro that if provided sets boundary_finder, layout, and metadata_map.
27
+ # These can be individually overwritten.
27
28
  # Legal values are symbols taken from SqedConfig::EXTRACTION_PATTERNS.
28
- # DO NOT pass pattern outside of a sqed instance!
29
29
  #
30
- # !! Always passed as an option :target_pattern, an persisted as :pattern
30
+ # !! Patterns are not intended to be persisted in external databases (they may change names). !!
31
+ # To persist Sqed metadata in something like Postgres reference individual
32
+ # attributes (e.g. layout, metadata_map, boundary_finder).
33
+ #
34
+ # @return [Symbol] like `:seven_slot`, see Sqed::CONFIG for valid options,
35
+ # default value is `nil`
36
+ # not required if layout, metadata_map, and boundary_finder are provided
31
37
  attr_accessor :pattern
32
38
 
33
- # Provide a specific layout, overrides layout metadata taken from pattern
39
+ # @return [Symbol] like `:cross`
40
+ # !! Provide a specific layout, passed as option :layout, overrides layout metadata taken from :pattern, defaults to `:cross`
34
41
  attr_accessor :layout
35
42
 
36
43
  # the image that is the cropped content for parsing
37
44
  attr_accessor :stage_image
38
45
 
39
- # a Sqed::Boundaries instance that stores the coordinates of the stage
46
+ # @return [Sqed::Boundaries instance]
47
+ # stores the coordinates of the stage
40
48
  attr_accessor :stage_boundary
41
49
 
42
- # a Sqed::Boundaries instances that contains the coordinates of the interan stage sections
50
+ # @return [Sqed::Boundaries instance]
51
+ # contains the coordinates of the internal stage sections
43
52
  attr_accessor :boundaries
44
53
 
45
- # Boolean, whether to detect the border on initialization, i.e. new()
54
+ # @return [Boolean] defaults to `true`
55
+ # when true detects border on initialization
46
56
  attr_accessor :has_border
47
57
 
48
- # a symbol, :red, :green, :blue, describing the boundary color within the stage
58
+ # @return [Symbol] like `:red`, `:green`, `:blue`, defaults to `:green`
59
+ # describing the boundary color within the stage
49
60
  attr_accessor :boundary_color
50
61
 
51
- # Boolean, whether to do the boundary detection (not stage detection at present) against a thumbnail version of the passed image (faster, less accurate, true be default)
62
+ # @return [Boolean] defaults to `true` (faster, less accurate)
63
+ # if `true` do the boundary detection (not stage detection at present)
64
+ # against a thumbnail version of the passed image
52
65
  attr_accessor :use_thumbnail
53
66
 
54
- # Provide a metadata map, overrides metadata taken from pattern.
55
- # !! Always passed as an option :target_metadata_map, an persisted as :metadata_map
67
+ # Provide a metadata map, overrides metadata taken from pattern
56
68
  attr_accessor :metadata_map
57
69
 
58
70
  # Provide a boundary_finder, overrides metadata taken from pattern
59
71
  attr_accessor :boundary_finder
60
72
 
61
- def initialize(target_image: nil, target_pattern: nil, target_layout: nil, has_border: true, boundary_color: :green, use_thumbnail: true, boundary_finder: nil, target_metadata_map: nil)
62
- raise 'extraction pattern not defined' if target_pattern && !SqedConfig::EXTRACTION_PATTERNS.keys.include?(target_pattern)
63
-
64
- # data, and stubs for results
65
- @image = target_image
66
- @boundaries = nil
67
- @stage_boundary = Sqed::Boundaries.new(:internal_box)
68
-
73
+ def initialize(**opts)
69
74
  # extraction metadata
70
- @pattern = target_pattern # not required if target_layout, target_metadata_map, and boundary_finder are provided
71
-
72
- @has_border = has_border
73
- @boundary_finder = boundary_finder.constantize if boundary_finder
74
- @layout = target_layout
75
- @layout ||= SqedConfig::EXTRACTION_PATTERNS[pattern][:layout] if pattern
75
+ @image = opts[:image]
76
76
 
77
- @metadata_map = target_metadata_map
78
- @boundary_color = boundary_color
79
- @use_thumbnail = use_thumbnail
80
-
81
- set_stage_boundary if @image
77
+ configure(opts)
78
+ stub_results
82
79
  end
83
80
 
84
81
  # @return [Hash]
85
- # federate extraction options and apply user provided over-rides
82
+ # federate extraction options
86
83
  def extraction_metadata
87
- data = {}
88
- data = SqedConfig::EXTRACTION_PATTERNS[pattern] if pattern
89
-
90
- # if pattern is not provided, these must be
91
- data[:boundary_finder] = @boundary_finder if boundary_finder
92
- data[:target_layout] = layout if layout
93
- data[:target_metadata_map] = metadata_map if metadata_map
94
-
95
- data[:boundary_color] = boundary_color
96
- data[:has_border] = has_border
97
- data[:use_thumbnail] = use_thumbnail
98
- data
84
+ {
85
+ boundary_finder: boundary_finder,
86
+ layout: layout,
87
+ metadata_map: metadata_map,
88
+ boundary_color: boundary_color,
89
+ has_border: has_border,
90
+ use_thumbnail: use_thumbnail
91
+ }
99
92
  end
100
93
 
101
94
  # @return [ImageMagick::Image]
@@ -117,14 +110,13 @@ class Sqed
117
110
  end
118
111
 
119
112
  def stage_image
120
- crop_image if @stage_image.nil?
121
- @stage_image
113
+ crop_image if @stage_image.nil?
114
+ @stage_image
122
115
  end
123
116
 
124
- # Return [Sqed::Boundaries instance]
117
+ # @return [Sqed::Boundaries instance, nil]
125
118
  # a boundaries instance that has the original image (prior to cropping stage) coordinates
126
119
  def native_boundaries
127
- # check for @boundaries.complete first? OR handle partial detections ?!
128
120
  if @boundaries.complete
129
121
  @boundaries.offset(stage_boundary)
130
122
  else
@@ -132,7 +124,7 @@ class Sqed
132
124
  end
133
125
  end
134
126
 
135
- # return [Image]
127
+ # @return [Image]
136
128
  # crops the stage if not done, then sets/returns @stage_image
137
129
  def crop_image
138
130
  if has_border
@@ -145,19 +137,20 @@ class Sqed
145
137
 
146
138
  def result
147
139
  return false if image.nil?
148
- return false if pattern.nil? && (metadata_map.nil? && layout.nil? && boundary_finder.nil?)
149
140
 
150
141
  extractor = Sqed::Extractor.new(
151
- target_boundaries: boundaries,
152
- target_metadata_map: extraction_metadata[:target_metadata_map],
153
- target_image: stage_image)
142
+ boundaries: boundaries,
143
+ metadata_map: metadata_map, # extraction_metadata[:metadata_map],
144
+ image: stage_image
145
+ )
146
+
154
147
  extractor.result
155
148
  end
156
149
 
157
150
  # @return [Hash]
158
151
  # an overview of data/metadata, for debugging purposes only
159
152
  def attributes
160
- { target_image: image,
153
+ { image: image,
161
154
  boundaries: boundaries,
162
155
  stage_boundary: stage_boundary
163
156
  }.merge!(extraction_metadata)
@@ -165,9 +158,76 @@ class Sqed
165
158
 
166
159
  protected
167
160
 
161
+ def configure(opts)
162
+ configure_from_pattern(opts[:pattern])
163
+ configure_boundary_finder(opts)
164
+ configure_layout(opts)
165
+ configure_metadata_map(opts)
166
+
167
+ @has_border = opts[:has_border]
168
+ @has_border = true if @has_border.nil?
169
+
170
+ @boundary_color = opts[:boundary_color]
171
+ @boundary_color ||= :green
172
+
173
+ @use_thumbnail = opts[:use_thumbnail]
174
+ @use_thumbnail = true if @use_thumbnail.nil?
175
+ end
176
+
177
+ def configure_from_pattern(value)
178
+ return if value.nil?
179
+ value = value.to_sym
180
+ raise "provided extraction pattern '#{value}' not defined" if !SqedConfig::EXTRACTION_PATTERNS.keys.include?(value)
181
+ @pattern = value
182
+ a = SqedConfig::EXTRACTION_PATTERNS[pattern]
183
+ @boundary_finder = a[:boundary_finder]
184
+ @layout = a[:layout]
185
+ @metadata_map = a[:metadata_map]
186
+ true
187
+ end
188
+
189
+ def configure_boundary_finder(opts)
190
+ @boundary_finder = opts[:boundary_finder].constantize if !opts[:boundary_finder].nil?
191
+ @boundary_finder ||= Sqed::BoundaryFinder::CrossFinder
192
+ end
193
+
194
+ def configure_layout(opts)
195
+ @layout = opts[:layout]
196
+ if p = opts[:pattern]
197
+ @layout ||= SqedConfig::EXTRACTION_PATTERNS[p][:layout]
198
+ end
199
+ @layout ||= :cross
200
+ end
201
+
202
+ def configure_metadata_map(opts)
203
+ @metadata_map = opts[:metadata_map] unless opts[:metadata_map].nil?
204
+ end
205
+
206
+ # stubs for data and results
207
+ def stub_results
208
+ @boundaries = nil
209
+ @stage_boundary = Sqed::Boundaries.new(:internal_box)
210
+ set_stage_boundary if @image
211
+ end
212
+
213
+ def get_section_boundaries
214
+ boundary_finder.new(section_params).boundaries
215
+ end
216
+
217
+ # @return [Hash]
218
+ # variables for the isolated stage image
219
+ def section_params
220
+ {
221
+ image: stage_image,
222
+ use_thumbnail: use_thumbnail,
223
+ layout: layout,
224
+ boundary_color: boundary_color
225
+ }
226
+ end
227
+
168
228
  def set_stage_boundary
169
229
  if has_border
170
- boundary = Sqed::BoundaryFinder::StageFinder.new(target_image: image).boundaries
230
+ boundary = Sqed::BoundaryFinder::StageFinder.new(image: image).boundaries
171
231
  if boundary.populated?
172
232
  @stage_boundary.set(0, boundary.for(0))
173
233
  else
@@ -178,12 +238,4 @@ class Sqed
178
238
  end
179
239
  end
180
240
 
181
- def get_section_boundaries
182
- options = {target_image: stage_image, use_thumbnail: use_thumbnail}
183
- options.merge!( target_layout: extraction_metadata[:target_layout] ) unless extraction_metadata[:boundary_finder].name == 'Sqed::BoundaryFinder::CrossFinder'
184
- options.merge!( boundary_color: boundary_color) if extraction_metadata[:boundary_finder].name == 'Sqed::BoundaryFinder::ColorLineFinder'
185
-
186
- extraction_metadata[:boundary_finder].new(options).boundaries
187
- end
188
-
189
241
  end
@@ -1,8 +1,11 @@
1
- # An Sqed::Boundaries is a simple wrapper for a hash that contains the co-ordinates for each section of a layout.
2
1
 
3
- # Layouts are Hashes defined in EXTRACTION_PATTERNS[<pattern>][<layout>]
4
- #
5
- class Sqed::Boundaries
2
+ class Sqed
3
+
4
+ # An Sqed::Boundaries is a simple wrapper for a hash that contains the co-ordinates for each section of a layout.
5
+ #
6
+ # Layouts are Hashes defined in EXTRACTION_PATTERNS[<pattern>][<layout>]
7
+ #
8
+ class Boundaries
6
9
  include Enumerable
7
10
 
8
11
  # stores a hash
@@ -12,11 +15,12 @@ class Sqed::Boundaries
12
15
  # 0 => [10,10,40,40]
13
16
  attr_reader :coordinates
14
17
 
15
- # A symbol from Sqed::Config::LAYOUTS.keys
18
+ # A symbol from Sqed::Config::LAYOUTS.keys
16
19
  # :right_t
17
20
  attr_accessor :layout
18
21
 
19
- # Boolean, whether or not the last method to populate this object passed fully
22
+ # @return [Boolean] whether or not the last method to populate this object
23
+ # executed to completion
20
24
  attr_accessor :complete
21
25
 
22
26
  def initialize(layout = nil)
@@ -34,17 +38,19 @@ class Sqed::Boundaries
34
38
  end
35
39
  end
36
40
 
41
+ # @return [Sqed::Boundaries instance]
42
+ # the idea here is to create a deep copy of self, offsetting by boundary
43
+ # as we go
37
44
  def offset(boundary)
38
- b = Sqed::Boundaries.new() # the idea here is to create a deep copy of self, offsetting by boundary as we go
39
- (0..self.coordinates.length - 1).each do |i|
40
- b.set(i,
41
- [(self.x_for(i) + boundary.x_for(0)),
42
- (self.y_for(i) + boundary.y_for(0)),
43
- self.width_for(i),
44
- self.height_for(i)]
45
- )
45
+ b = Sqed::Boundaries.new
46
+ (0..coordinates.length - 1).each do |i|
47
+ b.set(i,
48
+ [(x_for(i) + boundary.x_for(0)),
49
+ (y_for(i) + boundary.y_for(0)),
50
+ width_for(i),
51
+ height_for(i)])
46
52
  end
47
- b.complete = self.complete
53
+ b.complete = complete
48
54
  b
49
55
  end
50
56
 
@@ -84,25 +90,24 @@ class Sqed::Boundaries
84
90
  end
85
91
 
86
92
  def populated?
87
- self.each do |index, coords|
93
+ each do |index, coords|
88
94
  coords.each do |c|
89
95
  return false if c.nil?
90
96
  end
91
97
  end
92
- true
98
+ true
93
99
  end
94
100
 
95
101
  def zoom(width_factor, height_factor)
96
102
  coordinates.keys.each do |i|
97
- set(i, [
98
- (x_for(i).to_f * width_factor).to_i,
99
- (y_for(i).to_f * height_factor).to_i,
100
- (width_for(i).to_f * width_factor).to_i,
101
- (height_for(i).to_f * height_factor).to_i
103
+ set(i, [
104
+ (x_for(i).to_f * width_factor).to_i,
105
+ (y_for(i).to_f * height_factor).to_i,
106
+ (width_for(i).to_f * width_factor).to_i,
107
+ (height_for(i).to_f * height_factor).to_i
102
108
  ])
103
-
104
- end
109
+ end
105
110
  end
106
111
 
107
-
112
+ end
108
113
  end