sqed 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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