picguard 1.0.0 → 1.0.1

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