picguard 1.0.0 → 1.0.1

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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +10 -0
  3. data/.gitignore +9 -0
  4. data/.rspec +2 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +81 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +6 -0
  10. data/bin/setup +8 -0
  11. data/circle.yml +3 -0
  12. data/lib/configuration.rb +11 -0
  13. data/lib/google/apis/vision_v1.rb +37 -0
  14. data/lib/google/apis/vision_v1/classes.rb +1259 -0
  15. data/lib/google/apis/vision_v1/representations.rb +370 -0
  16. data/lib/google/apis/vision_v1/service.rb +91 -0
  17. data/lib/guard_validator.rb +58 -0
  18. data/lib/picguard.rb +40 -0
  19. data/lib/picguard/version.rb +3 -0
  20. data/lib/services/analyzer.rb +40 -0
  21. data/lib/services/builders/annotate_image.rb +16 -0
  22. data/lib/services/builders/batch.rb +15 -0
  23. data/lib/services/builders/feature.rb +16 -0
  24. data/lib/services/builders/image.rb +15 -0
  25. data/lib/services/builders/request.rb +27 -0
  26. data/lib/services/builders/vision.rb +17 -0
  27. data/lib/services/image_preparator.rb +46 -0
  28. data/lib/services/validators/likelihood.rb +31 -0
  29. data/picguard.gemspec +30 -0
  30. data/spec/guard_validator_spec.rb +72 -0
  31. data/spec/picguard_spec.rb +22 -0
  32. data/spec/services/analyzer_spec.rb +33 -0
  33. data/spec/services/builders/annotate_image_spec.rb +15 -0
  34. data/spec/services/builders/batch_spec.rb +18 -0
  35. data/spec/services/builders/feature_spec.rb +26 -0
  36. data/spec/services/builders/image_spec.rb +12 -0
  37. data/spec/services/builders/vision_spec.rb +14 -0
  38. data/spec/services/image_preparator_spec.rb +36 -0
  39. data/spec/services/validators/likelihood_spec.rb +26 -0
  40. data/spec/spec_helper.rb +10 -0
  41. data/spec/support/img/cat.jpg +0 -0
  42. data/spec/support/img/face-example.jpg +0 -0
  43. data/spec/support/img/gun-violence.jpg +0 -0
  44. data/spec/support/result_hash_stub.rb +212 -0
  45. metadata +64 -4
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe Picguard do
4
+ before(:all) do
5
+ Picguard.configure do |config|
6
+ config.google_api_key = ENV['GCLOUD_KEY']
7
+ config.threshold_adult = "POSSIBLE"
8
+ config.threshold_violence = "UNLIKELY"
9
+ config.threshold_face = 0.8
10
+ end
11
+ end
12
+ it 'has a version number' do
13
+ expect(Picguard::VERSION).not_to be nil
14
+ end
15
+
16
+ describe '#analyze' do
17
+ subject { described_class.analyze(image_path: "spec/support/img/face-example.jpg") }
18
+ it 'returns a result as hash' do
19
+ expect(subject).to be_an_instance_of(Hash)
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Analyzer do
4
+ subject { described_class.new(
5
+ result = ResultHashStub.new.api_hash_result,
6
+ threshold_adult = 'POSSIBLE',
7
+ threshold_violence = 'POSSIBLE',
8
+ threshold_face = 0.8
9
+ ) }
10
+ describe '#call' do
11
+ let(:analyzed_result) { subject.call }
12
+
13
+ it 'returns a valid hash' do
14
+ expect(analyzed_result).to be_an_instance_of(Hash)
15
+ expect(analyzed_result).to have_key(:safe_search)
16
+ expect(analyzed_result[:safe_search]).to have_key(:adult)
17
+ expect(analyzed_result[:safe_search]).to have_key(:violence)
18
+ expect(analyzed_result).to have_key(:face_recognised)
19
+ end
20
+
21
+ it 'returns adult content violation' do
22
+ expect(analyzed_result[:safe_search][:adult]).to be(true)
23
+ end
24
+
25
+ it 'does not return violent content violation' do
26
+ expect(analyzed_result[:safe_search][:violence]).to be(false)
27
+ end
28
+
29
+ it 'recognises face' do
30
+ expect(analyzed_result[:face_recognised]).to be(true)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Builders::AnnotateImage do
4
+ subject { described_class.new(image, [feature]) }
5
+ let(:image) do
6
+ Google::Apis::VisionV1::Image.new(content: open('spec/support/img/face-example.jpg').to_a.join)
7
+ end
8
+ let(:feature) { Google::Apis::VisionV1::Feature.new(type: 'FACE_DETECTION') }
9
+
10
+ describe '#call' do
11
+ it 'creates valid Google::Apis::VisionV1::AnnotateImageRequest object' do
12
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::AnnotateImageRequest
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Builders::BatchAnnotateImages do
4
+ subject { described_class.new([image_request]) }
5
+ let(:image) do
6
+ Google::Apis::VisionV1::Image.new(content: open('spec/support/img/face-example.jpg').to_a.join)
7
+ end
8
+ let(:feature) { Google::Apis::VisionV1::Feature.new(type: 'FACE_DETECTION') }
9
+ let(:image_request) do
10
+ Google::Apis::VisionV1::AnnotateImageRequest.new(image: [image], features: [feature])
11
+ end
12
+
13
+ describe '#call' do
14
+ it 'creates valid Google::Apis::VisionV1::BatchAnnotateImagesRequest object' do
15
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::BatchAnnotateImagesRequest
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Builders::Feature do
4
+ let(:type) { 'SAFE_SEARCH_DETECTION' }
5
+ let(:max_results) { '3' }
6
+
7
+ context 'max_results is defined' do
8
+ subject { described_class.new(type, max_results) }
9
+
10
+ describe '#call' do
11
+ it 'creates valid Google::Apis::VisionV1::Feature object' do
12
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::Feature
13
+ end
14
+ end
15
+ end
16
+
17
+ context 'max_results is not defined' do
18
+ subject { described_class.new(type) }
19
+
20
+ describe '#call' do
21
+ it 'creates valid Google::Apis::VisionV1::Feature object' do
22
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::Feature
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Builders::Image do
4
+ subject { described_class.new(image_path) }
5
+ let(:image_path) { 'spec/support/img/face-example.jpg' }
6
+
7
+ describe '#call' do
8
+ it 'creates valid Google::Apis::VisionV1::Image object' do
9
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::Image
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Builders::Vision do
4
+ subject { described_class.new }
5
+
6
+ before { Picguard.configure { |config| config.google_api_key = "google_api_key" } }
7
+
8
+ describe '#call' do
9
+ it 'creates valid Google::Apis::VisionV1::VisionService object with given key' do
10
+ expect(subject.call).to be_an_instance_of Google::Apis::VisionV1::VisionService
11
+ expect(subject.call.key).to eq "google_api_key"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+ require 'mini_magick'
3
+
4
+ describe Services::ImagePreparator do
5
+ describe '#call' do
6
+ context 'image is too big' do
7
+ let(:image_path) { 'spec/support/img/face-example.jpg' }
8
+
9
+ context 'with face detection' do
10
+ subject { described_class.new(image_path, true, true).call }
11
+ it 'resizes picture to 1600x' do
12
+ expect(MiniMagick::Image.open(subject).dimensions.first).to equal 1600
13
+ end
14
+ end
15
+
16
+ context 'without face detection' do
17
+ subject { described_class.new(image_path, false, true).call }
18
+ it 'resizes picture to 640x' do
19
+ expect(MiniMagick::Image.open(subject).dimensions.first).to equal 640
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'image is below the threshold' do
25
+ let(:image_path) do
26
+ img = MiniMagick::Image.open('spec/support/img/face-example.jpg')
27
+ img.resize(800).path
28
+ end
29
+ subject { described_class.new(image_path, true, true).call }
30
+ it 'does not resize the picture' do
31
+ original_dimensions = MiniMagick::Image.open(image_path).dimensions
32
+ expect(MiniMagick::Image.open(subject).dimensions).to match_array(original_dimensions)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Services::Validators::Likelihood do
4
+ subject { described_class.new(response, threshold) }
5
+ let(:threshold) { 'possible' }
6
+
7
+ context 'response is below the threshold' do
8
+ let(:response) { 'unlikely' }
9
+
10
+ describe '#call' do
11
+ it 'checks whether response is acceptable' do
12
+ expect(subject.call).to eq false
13
+ end
14
+ end
15
+ end
16
+
17
+ context 'response is above the threshold' do
18
+ let(:response) { 'likely' }
19
+
20
+ describe '#call' do
21
+ it 'checks whether response is acceptable' do
22
+ expect(subject.call).to eq true
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,10 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+ SimpleCov.start do
4
+ add_filter '/lib/google/apis'
5
+ end
6
+
7
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
8
+ require 'picguard'
9
+ require 'pry'
10
+ require 'support/result_hash_stub'
Binary file
@@ -0,0 +1,212 @@
1
+ class ResultHashStub
2
+
3
+ attr_reader :api_hash_result
4
+
5
+ def initialize
6
+ @api_hash_result =
7
+ {:safe_search_annotation =>
8
+ {:medical => "POSSIBLE", :violence =>
9
+ "VERY_UNLIKELY", :spoof => "VERY_UNLIKELY", :adult => "VERY_LIKELY"
10
+ }, :face_annotations => [
11
+ {:tilt_angle => -5.6747785,
12
+ :under_exposed_likelihood => "VERY_UNLIKELY", :fd_bounding_poly =>
13
+ {
14
+ :vertices => [
15
+ {:y => 66, :x => 212
16
+ },
17
+ {:y => 66, :x => 309
18
+ },
19
+ {:y => 162, :x => 309
20
+ },
21
+ {:y => 162, :x => 212
22
+ }]
23
+ }, :landmarking_confidence => 0.54256278, :joy_likelihood =>
24
+ "UNLIKELY", :detection_confidence => 0.81811, :surprise_likelihood =>
25
+ "VERY_UNLIKELY", :anger_likelihood => "VERY_UNLIKELY",
26
+ :headwear_likelihood => "VERY_UNLIKELY", :bounding_poly =>
27
+ {
28
+ :vertices => [
29
+ {:y => 15, :x => 181
30
+ },
31
+ {:y => 15, :x => 319
32
+ },
33
+ {:y => 176, :x => 319
34
+ },
35
+ {:y => 176, :x => 181
36
+ }]
37
+ }, :pan_angle => 21.601442, :landmarks => [
38
+ {:position =>
39
+ {:y =>
40
+ 92.158325, :z => 0.00041507356, :x => 247.91048
41
+ }, :type => "LEFT_EYE"
42
+ },
43
+ {:position =>
44
+ {:y => 95.865105, :z => 14.610845, :x =>
45
+ 284.24
46
+ }, :type => "RIGHT_EYE"
47
+ },
48
+ {:position =>
49
+ {:y => 80.607, :z => -2.5638669, :x =>
50
+ 234.99283
51
+ }, :type => "LEFT_OF_LEFT_EYEBROW"
52
+ },
53
+ {:position =>
54
+ {:y => 84.722275, :z => -4.653347, :x =>
55
+ 262.35208
56
+ }, :type => "RIGHT_OF_LEFT_EYEBROW"
57
+ },
58
+ {:position =>
59
+ {:y => 86.8425, :z => 2.8803124, :x =>
60
+ 281.2482
61
+ }, :type => "LEFT_OF_RIGHT_EYEBROW"
62
+ },
63
+ {:position =>
64
+ {:y => 87.784157, :z => 23.202911, :x =>
65
+ 300.01212
66
+ }, :type => "RIGHT_OF_RIGHT_EYEBROW"
67
+ },
68
+ {:position =>
69
+ {:y => 93.327347, :z => -0.74257189, :x =>
70
+ 271.58786
71
+ }, :type => "MIDPOINT_BETWEEN_EYES"
72
+ },
73
+ {:position =>
74
+ {:y => 121.89613, :z => -9.7575331, :x =>
75
+ 272.08487
76
+ }, :type => "NOSE_TIP"
77
+ },
78
+ {:position =>
79
+ {:y => 134.86389, :z => 1.2005523, :x =>
80
+ 265.13113
81
+ }, :type => "UPPER_LIP"
82
+ },
83
+ {:position =>
84
+ {:y => 145.711, :z => 5.1032391, :x =>
85
+ 262.22424
86
+ }, :type => "LOWER_LIP"
87
+ },
88
+ {:position =>
89
+ {:y => 132.93515, :z => 6.4996686, :x =>
90
+ 241.32828
91
+ }, :type => "MOUTH_LEFT"
92
+ },
93
+ {:position =>
94
+ {:y => 139.00401, :z => 18.114491, :x =>
95
+ 275.54007
96
+ }, :type => "MOUTH_RIGHT"
97
+ },
98
+ {:position =>
99
+ {:y => 139.32642, :z => 4.637207, :x =>
100
+ 263.2186
101
+ }, :type => "MOUTH_CENTER"
102
+ },
103
+ {:position =>
104
+ {:y => 123.55997, :z => 10.26918, :x =>
105
+ 276.53827
106
+ }, :type => "NOSE_BOTTOM_RIGHT"
107
+ },
108
+ {:position =>
109
+ {:y => 121.06685, :z => 1.5411681, :x =>
110
+ 256.73715
111
+ }, :type => "NOSE_BOTTOM_LEFT"
112
+ },
113
+ {:position =>
114
+ {:y => 127.45449, :z => 0.13932635, :x =>
115
+ 267.49707
116
+ }, :type => "NOSE_BOTTOM_CENTER"
117
+ },
118
+ {:position =>
119
+ {:y => 89.913605, :z => -2.8806689, :x =>
120
+ 249.3102
121
+ }, :type => "LEFT_EYE_TOP_BOUNDARY"
122
+ },
123
+ {:position =>
124
+ {:y => 93.544769, :z => 3.4420719, :x =>
125
+ 257.01355
126
+ }, :type => "LEFT_EYE_RIGHT_CORNER"
127
+ },
128
+ {:position =>
129
+ {:y => 94.753471, :z => -0.046903312, :x =>
130
+ 247.54877
131
+ }, :type => "LEFT_EYE_BOTTOM_BOUNDARY"
132
+ },
133
+ {:position =>
134
+ {:y => 91.094345, :z => 0.55011082, :x =>
135
+ 238.81487
136
+ }, :type => "LEFT_EYE_LEFT_CORNER"
137
+ },
138
+ {:position =>
139
+ {:y => 92.459457, :z => -1.2200928, :x =>
140
+ 247.72058
141
+ }, :type => "LEFT_EYE_PUPIL"
142
+ },
143
+ {:position =>
144
+ {:y => 94.214386, :z => 12.550914, :x =>
145
+ 288.2327
146
+ }, :type => "RIGHT_EYE_TOP_BOUNDARY"
147
+ },
148
+ {:position =>
149
+ {:y => 97.126755, :z => 22.092098, :x =>
150
+ 293.21048
151
+ }, :type => "RIGHT_EYE_RIGHT_CORNER"
152
+ },
153
+ {:position =>
154
+ {:y => 99.567993, :z => 15.348606, :x =>
155
+ 285.91495
156
+ }, :type => "RIGHT_EYE_BOTTOM_BOUNDARY"
157
+ },
158
+ {:position =>
159
+ {:y => 96.592667, :z => 12.590128, :x =>
160
+ 278.9971
161
+ }, :type => "RIGHT_EYE_LEFT_CORNER"
162
+ },
163
+ {:position =>
164
+ {:y => 96.920578, :z => 14.648366, :x =>
165
+ 287.66995
166
+ }, :type => "RIGHT_EYE_PUPIL"
167
+ },
168
+ {:position =>
169
+ {:y => 78.016655, :z => -6.7624264, :x =>
170
+ 250.26114
171
+ }, :type => "LEFT_EYEBROW_UPPER_MIDPOINT"
172
+ },
173
+ {:position =>
174
+ {:y => 82.696075, :z => 9.9695559, :x =>
175
+ 292.5242
176
+ }, :type => "RIGHT_EYEBROW_UPPER_MIDPOINT"
177
+ },
178
+ {:position =>
179
+ {:y => 102.3996, :z => 40.218388, :x =>
180
+ 202.1022
181
+ }, :type => "LEFT_EAR_TRAGION"
182
+ },
183
+ {:position =>
184
+ {:y => 112.2905, :z => 75.182877, :x =>
185
+ 290.25772
186
+ }, :type => "RIGHT_EAR_TRAGION"
187
+ },
188
+ {:position =>
189
+ {:y => 85.515747, :z => -2.4461775, :x =>
190
+ 272.49033
191
+ }, :type => "FOREHEAD_GLABELLA"
192
+ },
193
+ {:position =>
194
+ {:y => 165.34473, :z => 12.695765, :x =>
195
+ 257.7327
196
+ }, :type => "CHIN_GNATHION"
197
+ },
198
+ {:position =>
199
+ {:y => 133.05925, :z => 28.48736, :x =>
200
+ 210.18437
201
+ }, :type => "CHIN_LEFT_GONION"
202
+ },
203
+ {:position =>
204
+ {:y => 140.82602, :z => 59.486729, :x =>
205
+ 288.02194
206
+ }, :type => "CHIN_RIGHT_GONION"
207
+ }], :blurred_likelihood => "VERY_UNLIKELY", :roll_angle =>
208
+ 8.5247707, :sorrow_likelihood => "VERY_UNLIKELY"
209
+ }]
210
+ }
211
+ end
212
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: picguard
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Szymon Baranowski
@@ -128,10 +128,55 @@ description: Picguard guards your application by filtering out the pictures cont
128
128
  email:
129
129
  - szymon.baranowski@netguru.pl
130
130
  - tomasz.jaskiewicz@netguru.pl
131
- executables: []
131
+ executables:
132
+ - console
133
+ - setup
132
134
  extensions: []
133
135
  extra_rdoc_files: []
134
- files: []
136
+ files:
137
+ - ".codeclimate.yml"
138
+ - ".gitignore"
139
+ - ".rspec"
140
+ - Gemfile
141
+ - LICENSE.txt
142
+ - README.md
143
+ - Rakefile
144
+ - bin/console
145
+ - bin/setup
146
+ - circle.yml
147
+ - lib/configuration.rb
148
+ - lib/google/apis/vision_v1.rb
149
+ - lib/google/apis/vision_v1/classes.rb
150
+ - lib/google/apis/vision_v1/representations.rb
151
+ - lib/google/apis/vision_v1/service.rb
152
+ - lib/guard_validator.rb
153
+ - lib/picguard.rb
154
+ - lib/picguard/version.rb
155
+ - lib/services/analyzer.rb
156
+ - lib/services/builders/annotate_image.rb
157
+ - lib/services/builders/batch.rb
158
+ - lib/services/builders/feature.rb
159
+ - lib/services/builders/image.rb
160
+ - lib/services/builders/request.rb
161
+ - lib/services/builders/vision.rb
162
+ - lib/services/image_preparator.rb
163
+ - lib/services/validators/likelihood.rb
164
+ - picguard.gemspec
165
+ - spec/guard_validator_spec.rb
166
+ - spec/picguard_spec.rb
167
+ - spec/services/analyzer_spec.rb
168
+ - spec/services/builders/annotate_image_spec.rb
169
+ - spec/services/builders/batch_spec.rb
170
+ - spec/services/builders/feature_spec.rb
171
+ - spec/services/builders/image_spec.rb
172
+ - spec/services/builders/vision_spec.rb
173
+ - spec/services/image_preparator_spec.rb
174
+ - spec/services/validators/likelihood_spec.rb
175
+ - spec/spec_helper.rb
176
+ - spec/support/img/cat.jpg
177
+ - spec/support/img/face-example.jpg
178
+ - spec/support/img/gun-violence.jpg
179
+ - spec/support/result_hash_stub.rb
135
180
  homepage: https://github.com/netguru/picguard
136
181
  licenses:
137
182
  - MIT
@@ -156,4 +201,19 @@ rubygems_version: 2.4.8
156
201
  signing_key:
157
202
  specification_version: 4
158
203
  summary: A gem for filtering a pictures that are being uploaded to your server.
159
- test_files: []
204
+ test_files:
205
+ - spec/guard_validator_spec.rb
206
+ - spec/picguard_spec.rb
207
+ - spec/services/analyzer_spec.rb
208
+ - spec/services/builders/annotate_image_spec.rb
209
+ - spec/services/builders/batch_spec.rb
210
+ - spec/services/builders/feature_spec.rb
211
+ - spec/services/builders/image_spec.rb
212
+ - spec/services/builders/vision_spec.rb
213
+ - spec/services/image_preparator_spec.rb
214
+ - spec/services/validators/likelihood_spec.rb
215
+ - spec/spec_helper.rb
216
+ - spec/support/img/cat.jpg
217
+ - spec/support/img/face-example.jpg
218
+ - spec/support/img/gun-violence.jpg
219
+ - spec/support/result_hash_stub.rb