One of the most useful and interesting features offered by the Vision API is Safe Search Detection (or Explicit Content Detection), which identifies and detects any explicit/adult content in an image.
This feature is particularly useful to keep a check on nudity or violence on the sites and avoid any such instances.
The Safe Search detection feature is implemented in such a way that it puts constraints on the image fields. If the user enables the Safe Search option for a particular image field, then the field is validated whenever an image file in uploaded in that field. If the file contains any explicit content which is not fit for display, the constraint message is displayed and the image would not be uploaded.
(This is one of my tasks of GSOC 2016 Project)
Comment | File | Size | Author |
---|---|---|---|
#30 | interdiff-29-30.txt | 7.43 KB | ajalan065 |
#30 | Service-mocked-2744845-8-30.patch | 17.63 KB | ajalan065 |
#29 | test-module-not-working.patch | 17.66 KB | ajalan065 |
#25 | interdiff-24-25.txt | 3.16 KB | ajalan065 |
#25 | Updated-schema-file-2744845-8-25.patch | 14.46 KB | ajalan065 |
Comments
Comment #2
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedComment #3
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHere is the patch for it.
Comment #4
penyaskitoThanks!
I appreciate this, but would love to give some direction. In my mind, this should be a Constraint that we can add to any field, check https://www.drupal.org/node/2015723 for (not a lot of :-( ) documentation
We could then configure each field (third party settings configuration), if we want to perform this check or not. Could you expend some time exploring this possibility?
Comment #5
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedSure!! I would work on following your directions :)
Comment #6
eugene.ilyin CreditAttribution: eugene.ilyin as a volunteer and at DrupalJedi commentedWe have two important things as a result of our discussion in hangouts:
1. We need to check type of entity and kind of file before than send this file to Cloud API
2. Would be nice be able enable this feature for specific field
Comment #7
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedThe previous patch implemented safe search as a function in the *.module file, however, this patch implements it as constraints and validators as was suggested in the above comments.
Summary of the work which the patch does:
If any content types have any image field, then for each image field, it adds the option to enable Safe Search Detection in the Edit form of the Image field.
If the Safe Search is off, then any image can be uploaded irrespective of whether it contains any violence or explicit contents.
If the Safe Search is on, it validates whether it contains the explicit content or not. If it contains any such content, constraints are implemented and an error message is shown.
Comment #8
penyaskitoThanks for working on this, looks much better now!
Some remarks:
The constraint shouldn't know about the entity field manager. Can we add the constraint to fields themselves instead of the entity? I think it's possible, but not 100% sure. This way we wouldn't depend on the field manager here.
This should be injected in the constructor.
Can we encapsulate this in the service? Something as \Drupal::service('google_vision.api')->hasExplicitContent($filepath)
Comment #9
penyaskitoBack to needs work.
Comment #10
eugene.ilyin CreditAttribution: eugene.ilyin as a volunteer and at DrupalJedi commentedGood job but with little remarks.
According to the Drupal Coding Standards you should use gap between "if" and condition and etc... https://www.drupal.org/coding-standards#controlstruct
Comment #11
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commented@penyaskito, the 3rd point in your above suggestions, you suggested moving that piece of code to the services. I had done that initially. But then I was convinced to keep all the functions in the service as they were, and manipulate the responses as and where we apply them. Hence, I coded that bit in the validators, which I felt would look better.
But if you are still convinced that we should move it to services, do let me know and I will implement that way. :)
Comment #12
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedThe constructor has been implemented in the ConstraintValidator file. Also, the spaces have been added after the if keyword.
However, the application of constraint directly over the fields is throwing "maximum function nested level reached" error.
Comment #13
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedAs far as I have noticed, the implementation of constraints over fields require two things:
1. the field name (which depends on the user who creates the field). To fetch this, we need to get the fields of the node, which would require entity field manager.
2. The file uri (in order to call the api). This uri needs to be present in the ConstraintValidator file, as the call is being made over there. I am not able to come up presently with any other way to get the uri, other than the method I implemented above, and that again needs to use the entity file manager.
Is there any way to fetch the uri other than the method above?
Presently, these two points are appearing on applying the constraint to fields directly.
Please guide me if I am going wrong. :)
Comment #14
eugene.ilyin CreditAttribution: eugene.ilyin as a volunteer and at DrupalJedi commentedMhh, I've applied your patch and it works for me without fatal error. How can I reproduce it?
Comment #15
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHere is the final patch, which applies the constraints to the fields successfully as was suggested in #8. The services have also been injected into the constructors.
The spaces are also taken care of as was suggested in #10.
Comment #16
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHi eugene.ilyin,
As I was getting the error, hence I did not upload the patch that reproduced the error. I was working on it, and after resolving the issue, I uploaded the fully functional patch. :) It works as expected
Comment #17
naveenvalechainject the "file_system" service
Comment #18
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedfile_system service injected.
Here is the patch.
Comment #19
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedUpdated the issue summary.
Comment #20
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedComment #21
naveenvalechalooks good. can we add tests here for testing this validation
Comment #22
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHere is the patch with two test files attached.
One is web tests which creates a custom content type along with an image field with constraint applied.
The only task remaining is to validate the constraint, where I am currently stuck.
Another is browser web test. The problem persisting here are the assertions. Each and every method,be it assertText() or drupalPostForm() requires custom coding, and can not be used directly.
Comment #23
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedThe progress of the web tests.
As mentioned in the above comments, the validate part is still to be implemented.
I am unable to get the answer to the question that the validate() method is a part of SafeSearchConstraintValidator.php which is called from the module when a particular bundle field(in this case image) is filled.
So, would this method be accessible inside the web test environment?
How can I make use of the validate() inside my webtest?
Comment #24
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHere is the patch with web tests working as per expected.
The Browser tests were removed after discussion with naveenvalecha on grounds that most of the assertions and methods required are not presently available in the BrowserTestBase, and writing custom codes for most of the assertions including assertResponse() and DrupalPostForm(), etc would not be feasible for simple browser tests. And the browser tests have been postponed to the future time when the assertions are committed to Core.
Comment #25
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedIn this patch, I have updated the schema.yml of the module and have also altered names to 'safe_search' at few places.
This patch is fully ready for review from my side :)
Comment #26
penyaskitoIs this your key? No way you want to share that.
We should mock the google service, we don't need to rely on it for running tests.
If we mock the service as said, we don't rely on having external images referenced in tests. Also, we don't want to ship with violent or nudity content for testing.
Comment #27
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedI could not get what you meant by this?
Comment #28
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedAs far as I had observed, mocking is only performed in unit and kernel tests.
I could not find any instance of mocking in webtests.
Please guide me on how to advance on it for webtests.
Comment #29
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedThe test module does not work and throws "SessionTestTrait not found " error.
Please have a look at it. I am unable to resolve where is the module going wrong?
Comment #30
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedHere is the patch which mocks the service, hence we neither relies on a google browser key for tests, nor on the external images for reference.
Here is the description of what I have done.
The google_vision.api service is mocked, and I have overridden the safeSearchDetection(). As there is no other way to detect whether the image has any explicit content without the use of API key, and the sole purpose of the test is to check whether the constraint applies correctly or not, I have passed the response which would be sent by the API if the image contains explicit content, taking the simpletest generated image.
And just to maintain the rhythm of the original function, I have just initialized the api_key with a test value, though it does not have any other work, except that the safe search would not be done if the key is not set.
Comment #32
eugene.ilyin CreditAttribution: eugene.ilyin as a volunteer and at DrupalJedi commentedCommitted.
This patch is already pretty big. If something is not in the best way, let's correct it later.
I have a question. Why do we need this?
Images can be not only in nodes.
Comment #33
naveenvalechaFiled a followup for this. #2756429: Remove the restriction of Label Detection/safe search detection feature from node entity
Fixed this issue.
Comment #34
ajalan065 CreditAttribution: ajalan065 at Google Summer of Code commentedI will do the follow up of this issue in the new issue created by naveenvalecha.
Unassigning it.