Skip to content

Commit

Permalink
Delete DeepAI provider (#128)
Browse files Browse the repository at this point in the history
* Delete DeepAI provider

* Decrease functiions threshold for tests

* Add triggers

* Verify image

* Debug 1

* Debug 2

* Debug 3

* Debug 4

* Debug 5

* Debug 6

* Debug 7

* Debug 8

* Debug 9

* Fix 2 providers

* Fix 2 providers

* Debug 10

* Debug 11

* Debug 12

* Debug 13

* Debug 14

* Debug 15

* Debug 16

* Debug 17

* Remove image

* Rollback changes

* Decrease threshold
  • Loading branch information
fabasoad authored Jan 3, 2025
1 parent a101e14 commit 4dc1d32
Show file tree
Hide file tree
Showing 19 changed files with 567 additions and 180 deletions.
37 changes: 18 additions & 19 deletions .github/workflows/functional-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@
name: Functional Tests

on: # yamllint disable-line rule:truthy
pull_request: {}
push:
branches:
- main
- "main"
pull_request:
paths:
- ".github/workflows/functional-tests.yml"
- "src/**"
- "!src/__tests__/**"
- "dist/**"
- "action.yml"
schedule:
# Every Friday at 09:00 JST
- cron: "0 0 * * 5"
workflow_dispatch: {}

jobs:
detect:
Expand All @@ -19,9 +29,6 @@ jobs:
- provider: cloudmersive
api-key: CLOUDMERSIVE_API_KEY
threshold: 0.32
- provider: deepai
api-key: DEEPAI_API_KEY
threshold: 0.39
- provider: picpurify
api-key: PICPURIFY_API_KEY
threshold: 0.97
Expand All @@ -32,22 +39,14 @@ jobs:
steps:
- name: Checkout ${{ github.repository }}
uses: actions/checkout@v4
- name: Prepare API key
id: secrets
run: |
if [ "${{ matrix.provider }}" = "sightengine" ]; then
echo "api-key=${{ secrets[matrix.api-user] }},${{ secrets[matrix.api-key] }}" >> $GITHUB_OUTPUT
else
echo "api-key=${{ secrets[matrix.api-key] }}" >> $GITHUB_OUTPUT
fi
- name: Download test file
run: |
curl https://images-na.ssl-images-amazon.com/images/I/91cDPlxcRiL._SL1500_.jpg --output test.jpg
git add test.jpg
# - name: Download test file
# run: |
# curl https://images-na.ssl-images-amazon.com/images/I/91cDPlxcRiL._SL1500_.jpg --output test.jpg
# git add test.jpg
- name: Detect NSFW content
uses: ./
with:
github_token: "${{ secrets.GITHUB_TOKEN }}"
github-token: "${{ secrets.GITHUB_TOKEN }}"
provider: "${{ matrix.provider }}"
api_key: "${{ steps.secrets.outputs.api-key }}"
api-key: "${{ matrix.provider == 'sightengine' && format('{0},{1}', secrets[matrix.api-user], secrets[matrix.api-key]) || secrets[matrix.api-key] }}"
threshold: "${{ matrix.threshold }}"
9 changes: 7 additions & 2 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
---
name: Unit Tests

on:
pull_request: {}
on: # yamllint disable-line rule:truthy
push:
branches:
- main
pull_request:
paths:
- .github/workflows/unit-tests.yml
- src/**
- jest.config.json
workflow_dispatch: {}

jobs:
jest:
Expand Down
47 changes: 23 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@ by chosen provider.

## Contents

- [Providers](#providers)
- [Cloudmersive](#cloudmersive)
- [DeepAI](#deepai)
- [PicPurify](#picpurify)
- [SightEngine](#sightengine)
- [Inputs](#inputs)
- [Example usage](#example-usage)
<!-- TOC -->
* [NSFW detection action](#nsfw-detection-action)
* [Contents](#contents)
* [Providers](#providers)
* [Cloudmersive](#cloudmersive)
* [PicPurify](#picpurify)
* [SightEngine](#sightengine)
* [Inputs](#inputs)
* [Example usage](#example-usage)
* [Workflow configuration](#workflow-configuration)
* [Result](#result)
<!-- TOC -->

## Providers

Expand All @@ -33,12 +38,6 @@ Identifier is `cloudmersive`. Sign up to [Cloudmersive](https://cloudmersive.com
official website. Then go to [API Keys](https://account.cloudmersive.com/keys)
page, create a new one and copy it.

### DeepAI

Identifier is `deepai`. Sign up to [DeepAI](https://deepai.org/) official website.
Then go to [Profile](https://deepai.org/dashboard/profile) page and copy `api-key`
that is located on the top of the page.

### PicPurify

Identifier is `picpurify`. Sign up to [PicPurify](https://www.picpurify.com/)
Expand All @@ -50,17 +49,17 @@ page and copy `API key` that is located on the top of the page.
Identifier is `sightengine`. Sign up to [SightEngine](https://sightengine.com/)
official website. Then go to [Get Started](https://dashboard.sightengine.com/getstarted)
page and copy API user and API secret from the examples provided. This provider
requires to provide 2 API identifiers, so please put them into `api_key` parameter
separated by comma. For example, your `api_user` is _123456_ and `api_secret` is
_abcdef_, so `api_key` should be _123456,abcdef_.
requires to provide 2 API identifiers, so please put them into `api-key` parameter
separated by comma. For example, `api-key` should be _123456,abcdef_ if your
`api_user` is _123456_ and `api_secret` is _abcdef_.

## Inputs

| Name | Required | Description | Default | Possible values |
|--------------|----------|-----------------------------------------------------------------------------------------------|----------------------------------|----------------------------------|
| github_token | Yes | GitHub token | | &lt;String&gt; |
| github-token | Yes | GitHub token | | &lt;String&gt; |
| provider | Yes | Provider identifier | | &lt;String&gt; |
| api_key | Yes | API key that should be used for chosen `provider` | | &lt;String&gt; |
| api-key | Yes | API key that should be used for chosen `provider` | | &lt;String&gt; |
| threshold | Yes | Action will be failed in case NSFW detection value will be greater or equal to this parameter | | &lt;Float&gt; |
| type | No | Type of committed files separated by comma | `modified,added,renamed` | `modified,added,renamed` |
| extensions | No | List of file extensions separated by comma | `jpeg,jpg,png,gif,webp,tiff,bmp` | `jpeg,jpg,png,gif,webp,tiff,bmp` |
Expand All @@ -76,18 +75,18 @@ on: push

jobs:
nsfw-detection:
name: Build
name: Verify files
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@main
- uses: fabasoad/nsfw-detection-action@main
- uses: actions/checkout@v4
- uses: fabasoad/nsfw-detection-action@v3
with:
provider: deepai
provider: picpurify
threshold: 0.9
type: modified,added,renamed
extensions: jpg,jpeg
github_token: ${{ secrets.GITHUB_TOKEN }}
api_key: ${{ secrets.DEEPAI_API_KEY }}
github-token: ${{ github.token }}
api-key: ${{ secrets.PICPURIFY_API_KEY }}
```
### Result
Expand Down
43 changes: 24 additions & 19 deletions action.yml
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
---
name: 'NSFW Detection Action'
name: NSFW Detection Action
author: Yevhen Fabizhevskyi
description: 'This GitHub action detects NSFW content in committed files.'
description: This GitHub Action detects NSFW content in committed files.
branding:
icon: alert-octagon
color: red
inputs:
github_token:
description: 'GitHub token'
required: true
type:
description: 'Type of committed files separated by comma.'
required: false
default: 'modified,added,renamed'
provider:
description: 'Provider identifier.'
description: Provider identifier.
required: true
api_key:
description: 'API key that should be used for chosen provider.'
api-key:
description: API key required for the selected provider.
required: true
extensions:
description: 'List of extensions separated by comma.'
required: false
default: 'jpeg,jpg,png,gif,webp,tiff,bmp'
threshold:
description: 'Action will be failed in case NSFW detection value will be greater or equal to this parameter.'
description: |
The action will fail if the NSFW detection value is greater than or equal
to this parameter.
required: true
extensions:
description: Comma-separated list of file extensions for NSFW detection.
required: false
default: jpeg,jpg,png,gif,webp,tiff,bmp
types:
description: Comma-separated types of changes made during work on the branch.
required: false
default: modified,added,renamed
github-token:
description: |
GitHub token that is used to send requests to GitHub API. Defaults to the
token provided by GitHub Actions environment.
required: false
default: ${{ github.token }}
runs:
using: 'node20'
main: 'dist/index.js'
using: node20
main: dist/index.js
16 changes: 11 additions & 5 deletions dist/index.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions jest.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
],
"coverageThreshold": {
"global": {
"branches": 10,
"functions": 35,
"branches": 5,
"functions": 25,
"lines": 25,
"statements": 25
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nsfw-detection-action",
"version": "2.0.4",
"version": "3.0.0",
"description": "This GitHub action detects nsfw content in committed files.",
"main": "dist/index.js",
"repository": {
Expand All @@ -21,6 +21,7 @@
"dependencies": {
"@actions/core": "1.11.1",
"@actions/github": "6.0.0",
"cloudmersive-image-api-client": "1.3.5",
"form-data": "4.0.1",
"winston": "3.17.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@ import {
import {
CloudmersiveNsfwDetectionProvider
} from '../../detection/providers/CloudmersiveNsfwDetectionProvider'
import {
DeepaiNsfwDetectionProvider
} from '../../detection/providers/DeepaiNsfwDetectionProvider'
import {
PicPurifyNsfwDetectionProvider
} from '../../detection/providers/PicPurifyNsfwDetectionProvider'
Expand All @@ -26,7 +23,6 @@ describe(NsfwDetectionProviderFactory.name, () => {
className: CloudmersiveNsfwDetectionProvider.name,
paramName: 'cloudmersive'
},
{ className: DeepaiNsfwDetectionProvider.name, paramName: 'deepai' },
{ className: PicPurifyNsfwDetectionProvider.name, paramName: 'picpurify' },
{
className: SightEngineNsfwDetectionProvider.name,
Expand All @@ -43,5 +39,5 @@ describe(NsfwDetectionProviderFactory.name, () => {
const name = 'randomstring'
expect(() => NsfwDetectionProviderFactory.getProvider(name))
.toThrow(`${name} provider is not supported`)
});
})
})
6 changes: 1 addition & 5 deletions src/detection/NsfwDetectionProviderFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import fs from 'fs'
import {
CloudmersiveNsfwDetectionProvider
} from './providers/CloudmersiveNsfwDetectionProvider'
import {
DeepaiNsfwDetectionProvider
} from './providers/DeepaiNsfwDetectionProvider'
import {
PicPurifyNsfwDetectionProvider
} from './providers/PicPurifyNsfwDetectionProvider'
Expand All @@ -13,14 +10,13 @@ import {
} from './providers/SightEngineNsfwDetectionProvider'

export interface INsfwDetectionProvider {
getScore(apiKey: string, file: fs.PathLike): Promise<number>
getScore(apiKey: string, file: fs.PathLike): Promise<number | null>
}

export class NsfwDetectionProviderFactory {
public static getProvider(name: string): INsfwDetectionProvider {
switch (name) {
case 'cloudmersive': return new CloudmersiveNsfwDetectionProvider()
case 'deepai': return new DeepaiNsfwDetectionProvider()
case 'picpurify': return new PicPurifyNsfwDetectionProvider()
case 'sightengine': return new SightEngineNsfwDetectionProvider()
default:
Expand Down
49 changes: 33 additions & 16 deletions src/detection/providers/CloudmersiveNsfwDetectionProvider.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,42 @@
import FormData from 'form-data'
import fs from 'fs'
import NsfwDetectionProviderBase from './NsfwDetectionProviderBase'
import CloudmersiveImageApiClient from 'cloudmersive-image-api-client'
import { Logger } from 'winston'
import { getLogger } from '../../logging/LoggerFactory'
import { INsfwDetectionProvider } from '../NsfwDetectionProviderFactory'

type CloudmersiveResponse = {
Score: number
Score: number,
Successful: boolean,
ClassificationOutcome: string
}

export class CloudmersiveNsfwDetectionProvider
extends NsfwDetectionProviderBase {
constructor() {
super('https://api.cloudmersive.com/image/nsfw/classify')
}

public async getScore(apiKey: string, file: fs.PathLike): Promise<number> {
const body = new FormData()
body.append('imageFile', fs.createReadStream(file))

const headers = body.getHeaders()
headers['apikey'] = apiKey
implements INsfwDetectionProvider {
private readonly logger: Logger = getLogger()

const resp = await this.request<CloudmersiveResponse>(body, headers)
return resp.Score
public async getScore(apiKey: string, file: fs.PathLike): Promise<number | null> {
const defaultClient = CloudmersiveImageApiClient.ApiClient.instance
const Apikey = defaultClient.authentications['Apikey']
Apikey.apiKey = apiKey
const apiInstance = new CloudmersiveImageApiClient.NsfwApi()
const imageFile = Buffer.from(fs.readFileSync(file).buffer)
return new Promise<number | null>((resolve, reject) => {
const callback = (error, { Successful, Score }: CloudmersiveResponse, response) => {
if (error) {
if (!response.ok) {
this.logger.error(`Status: ${response.status}. Reason: ${response.statusText}`)
}
reject(error)
} else {
if (!Successful) {
this.logger.warning(`There was a problem during ${file} file classification`)
resolve(null)
} else {
resolve(Score)
}
}
}
apiInstance.nsfwClassify(imageFile, callback)
})
}
}
26 changes: 0 additions & 26 deletions src/detection/providers/DeepaiNsfwDetectionProvider.ts

This file was deleted.

Loading

0 comments on commit 4dc1d32

Please sign in to comment.