aliyun_green 0.1.1 → 0.1.4
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -2
- data/README.md +8 -3
- data/Rakefile +4 -0
- data/aliyun_green.gemspec +13 -12
- data/lib/aliyun_green/client.rb +36 -42
- data/lib/aliyun_green/image.rb +130 -0
- data/lib/aliyun_green/text.rb +30 -17
- data/lib/aliyun_green/version.rb +1 -1
- data/lib/aliyun_green.rb +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc37a068c947eb1e894dcaae9057e1ff450496d5ccb43791cbecd40c4a7e8bf5
|
4
|
+
data.tar.gz: 233a42a6e475f68000cf39ee12db7e4ba0c5d519e7b0f0cffb596d135be69072
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61eeb56ce1f7b582cc6b52ed02c64fd1e745676976acd9855f17e96ff8eedbf4c8ffbf6e3f67734ce170c0288e5aaf84cf63dc49a0908e21be3b28e6f84b3c6f
|
7
|
+
data.tar.gz: 0c98e28f2fe30c5ce639a842e242bde5a66d2cafc365ac99078c87a34388d65dc619ad5a95c7c8bfc3e370faeddc40ab12a0cc38763eb0030870b18bdcb9e1a1
|
data/Gemfile.lock
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
aliyun_green (0.1.
|
4
|
+
aliyun_green (0.1.4)
|
5
5
|
httpx
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
ast (2.4.2)
|
11
|
+
byebug (11.1.3)
|
11
12
|
coderay (1.1.3)
|
12
13
|
diff-lcs (1.4.4)
|
13
14
|
http-2-next (0.5.0)
|
14
|
-
httpx (0.
|
15
|
+
httpx (0.21.1)
|
15
16
|
http-2-next (>= 0.4.1)
|
16
17
|
method_source (1.0.0)
|
17
18
|
parallel (1.21.0)
|
@@ -53,10 +54,12 @@ GEM
|
|
53
54
|
|
54
55
|
PLATFORMS
|
55
56
|
x86_64-darwin-20
|
57
|
+
x86_64-darwin-21
|
56
58
|
|
57
59
|
DEPENDENCIES
|
58
60
|
aliyun_green!
|
59
61
|
bundler
|
62
|
+
byebug
|
60
63
|
pry (~> 0.14.1)
|
61
64
|
rake (~> 13.0)
|
62
65
|
rspec (~> 3.0)
|
data/README.md
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# AliyunGreen
|
2
2
|
|
3
|
-
|
3
|
+
基于 阿里云的 内容审核
|
4
|
+
|
5
|
+
具体参见 [阿里云内容审核](https://help.aliyun.com/document_detail/84456.html?spm=a2c4g.11186623.0.0.7662754aWakeeW)
|
6
|
+
|
7
|
+
记得在使用前, 请在阿里云的“内容安全” => “设置” => "机器审核" 的 default 场景中, 点击编辑
|
8
|
+
之后在图片和文字选项卡里, 开启各种识别类型, 并保存
|
9
|
+
|
4
10
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
11
|
|
7
12
|
## Installation
|
8
13
|
|
@@ -22,7 +27,7 @@ Or install it yourself as:
|
|
22
27
|
|
23
28
|
## Usage
|
24
29
|
|
25
|
-
|
30
|
+
具体可参见 spec/aliyun_green_spec.rb 的测试用例
|
26
31
|
|
27
32
|
## Development
|
28
33
|
|
data/Rakefile
CHANGED
data/aliyun_green.gemspec
CHANGED
@@ -3,15 +3,15 @@
|
|
3
3
|
require_relative "lib/aliyun_green/version"
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
|
-
spec.name
|
7
|
-
spec.version
|
8
|
-
spec.authors
|
9
|
-
spec.email
|
6
|
+
spec.name = "aliyun_green"
|
7
|
+
spec.version = AliyunGreen::VERSION
|
8
|
+
spec.authors = ["42up"]
|
9
|
+
spec.email = ["foobar@v2up.com"]
|
10
10
|
|
11
|
-
spec.summary
|
12
|
-
spec.description
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
11
|
+
spec.summary = "Write a short summary, because RubyGems requires one."
|
12
|
+
spec.description = "Write a longer description or delete this line."
|
13
|
+
spec.homepage = "https://github.com/42up/aliyun_green"
|
14
|
+
spec.license = "MIT"
|
15
15
|
spec.required_ruby_version = ">= 2.4.0"
|
16
16
|
|
17
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'https://mygemserver.com'"
|
@@ -27,9 +27,10 @@ Gem::Specification.new do |spec|
|
|
27
27
|
(f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
28
28
|
end
|
29
29
|
end
|
30
|
-
spec.bindir
|
31
|
-
spec.executables
|
30
|
+
spec.bindir = "exe"
|
31
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
|
-
spec.add_dependency
|
35
|
-
|
34
|
+
spec.add_dependency "httpx"
|
35
|
+
spec.add_development_dependency "byebug"
|
36
|
+
end
|
data/lib/aliyun_green/client.rb
CHANGED
@@ -6,39 +6,33 @@ require "time"
|
|
6
6
|
|
7
7
|
module AliyunGreen
|
8
8
|
class Client
|
9
|
-
attr_accessor :endpoint, :api_version, :access_key_id
|
9
|
+
attr_accessor :endpoint, :api_version, :access_key_id, :access_key_secret, :enable_internal
|
10
10
|
|
11
11
|
def initialize(config)
|
12
|
-
self.endpoint
|
13
|
-
self.api_version
|
14
|
-
self.access_key_id
|
12
|
+
self.endpoint = config[:endpoint]
|
13
|
+
self.api_version = config[:api_version]
|
14
|
+
self.access_key_id = config[:access_key_id]
|
15
15
|
self.access_key_secret = config[:access_key_secret]
|
16
|
-
self.enable_internal
|
16
|
+
self.enable_internal = config[:enable_internal]
|
17
17
|
end
|
18
18
|
|
19
|
-
def post(uri
|
20
|
-
payload = {
|
21
|
-
bizType: 'default',
|
22
|
-
scenes: ["antispam"],
|
23
|
-
tasks: tasks
|
24
|
-
}
|
25
|
-
|
19
|
+
def post(uri, payload, params = {})
|
26
20
|
url = "https://#{get_host(self.endpoint)}#{uri}"
|
27
21
|
|
28
22
|
mix_headers = default_headers
|
29
23
|
request_body = payload.to_json
|
30
24
|
|
31
|
-
mix_headers[
|
32
|
-
mix_headers[
|
25
|
+
mix_headers["content-md5"] = Digest::MD5.base64digest request_body
|
26
|
+
mix_headers["content-length"] = request_body.length.to_s
|
33
27
|
|
34
|
-
string2sign = string_to_sign(
|
28
|
+
string2sign = string_to_sign(uri, mix_headers, params)
|
35
29
|
mix_headers.merge!(authorization: authorization(string2sign))
|
36
30
|
|
37
31
|
response = HTTPX.with(headers: mix_headers).post(url, body: payload.to_json)
|
38
32
|
|
39
|
-
r =
|
33
|
+
r = JSON.parse(response)
|
40
34
|
|
41
|
-
raise AliyunGreen::Error::SignatureDoesNotMatchError if r["Code"] ==
|
35
|
+
raise AliyunGreen::Error::SignatureDoesNotMatchError if r["Code"] == "SignatureDoesNotMatch"
|
42
36
|
raise AliyunGreen::Error::ClientError.new(r["msg"], r["code"]) if r["code"] != 200
|
43
37
|
|
44
38
|
r
|
@@ -46,22 +40,22 @@ module AliyunGreen
|
|
46
40
|
|
47
41
|
def string_to_sign(uri, headers, query = {})
|
48
42
|
header_string = [
|
49
|
-
|
50
|
-
headers[
|
51
|
-
headers[
|
52
|
-
headers[
|
53
|
-
headers[
|
43
|
+
"POST",
|
44
|
+
headers["accept"],
|
45
|
+
headers["content-md5"] || "",
|
46
|
+
headers["content-type"] || "",
|
47
|
+
headers["date"],
|
54
48
|
].join("\n")
|
55
49
|
"#{header_string}\n#{canonicalized_headers(headers)}#{canonicalized_resource(uri, query)}"
|
56
50
|
end
|
57
51
|
|
58
52
|
def canonicalized_headers(headers)
|
59
|
-
headers.keys.select { |key| key.to_s.start_with?
|
53
|
+
headers.keys.select { |key| key.to_s.start_with? "x-acs-" }
|
60
54
|
.sort.map { |key| "#{key}:#{headers[key].strip}\n" }.join
|
61
55
|
end
|
62
56
|
|
63
57
|
def canonicalized_resource(uri, query_hash = {})
|
64
|
-
query_string = query_hash.sort.map { |key, value| "#{key}=#{value}" }.join(
|
58
|
+
query_string = query_hash.sort.map { |key, value| "#{key}=#{value}" }.join("&")
|
65
59
|
query_string.empty? ? uri : "#{uri}?#{query_string}"
|
66
60
|
end
|
67
61
|
|
@@ -70,35 +64,35 @@ module AliyunGreen
|
|
70
64
|
end
|
71
65
|
|
72
66
|
def signature(string_to_sign)
|
73
|
-
Base64.encode64(OpenSSL::HMAC.digest(
|
67
|
+
Base64.encode64(OpenSSL::HMAC.digest("sha1", self.access_key_secret, string_to_sign)).strip
|
74
68
|
end
|
75
69
|
|
76
70
|
def default_headers
|
77
71
|
default_headers = {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
72
|
+
"accept" => "application/json",
|
73
|
+
"content-type" => "application/json",
|
74
|
+
"date" => Time.now.httpdate,
|
75
|
+
"host" => get_host(self.endpoint),
|
76
|
+
"x-acs-version" => self.api_version,
|
77
|
+
"x-acs-signature-nonce" => SecureRandom.hex(16),
|
78
|
+
"x-acs-signature-version" => "1.0",
|
79
|
+
"x-acs-signature-method" => "HMAC-SHA1",
|
86
80
|
}
|
87
81
|
default_headers
|
88
82
|
end
|
89
83
|
|
90
84
|
def get_host(endpoint)
|
91
85
|
externals = {
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
86
|
+
"cn-shanghai" => "green.cn-shanghai.aliyuncs.com",
|
87
|
+
"cn-beijing" => "green.cn-beijing.aliyuncs.com",
|
88
|
+
"cn-shenzhen" => "green.cn-shenzhen.aliyuncs.com",
|
89
|
+
"ap-southeast-1" => "green.ap-southeast-1.aliyuncs.com",
|
96
90
|
}
|
97
91
|
internals = {
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
92
|
+
"cn-shanghai" => "green-vpc.cn-shanghai.aliyuncs.com",
|
93
|
+
"cn-beijing" => "green-vpc.cn-beijing.aliyuncs.com",
|
94
|
+
"cn-shenzhen" => "green-vpc.cn-shenzhen.aliyuncs.com",
|
95
|
+
"ap-southeast-1" => "green-vpc.ap-southeast-1.aliyuncs.com",
|
102
96
|
}
|
103
97
|
if self.enable_internal
|
104
98
|
internals[endpoint]
|
@@ -107,4 +101,4 @@ module AliyunGreen
|
|
107
101
|
end
|
108
102
|
end
|
109
103
|
end
|
110
|
-
end
|
104
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module AliyunGreen
|
2
|
+
module Image
|
3
|
+
class << self
|
4
|
+
def scan(tasks, **options)
|
5
|
+
check_tasks(tasks)
|
6
|
+
response = AliyunGreen.client.post("/green/image/scan", build_payload(tasks, options))
|
7
|
+
response
|
8
|
+
end
|
9
|
+
|
10
|
+
def scan_async(tasks, **options)
|
11
|
+
check_tasks(tasks)
|
12
|
+
callback_url = options[:callback_url]
|
13
|
+
payload = build_payload(tasks, options)
|
14
|
+
if callback_url
|
15
|
+
payload[:callback] = callback_url
|
16
|
+
payload[:seed] = SecureRandom.uuid
|
17
|
+
end
|
18
|
+
answer = AliyunGreen.client.post("/green/image/asyncscan", payload)
|
19
|
+
answer["seed"] = payload[:seed] if callback_url
|
20
|
+
|
21
|
+
answer
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_task_answer(task_ids)
|
25
|
+
response = AliyunGreen.client.post("/green/image/results", task_ids)
|
26
|
+
end
|
27
|
+
|
28
|
+
def feedback
|
29
|
+
end
|
30
|
+
|
31
|
+
def scene_dict
|
32
|
+
{
|
33
|
+
porn: "图片智能鉴黄",
|
34
|
+
terrorism: "图片暴恐涉政",
|
35
|
+
ad: "图文违规",
|
36
|
+
qrcode: "图片二维码",
|
37
|
+
live: "图片不良场景",
|
38
|
+
logo: "图片logo",
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
def scene_response_dict
|
43
|
+
{
|
44
|
+
porn: {
|
45
|
+
normal: "正常",
|
46
|
+
sexy: "性感",
|
47
|
+
porn: "色情",
|
48
|
+
},
|
49
|
+
terrorism: {
|
50
|
+
normal: "正常",
|
51
|
+
bloody: "血腥",
|
52
|
+
explosion: "爆炸烟光",
|
53
|
+
outfit: "特殊装束",
|
54
|
+
logo: "特殊标识",
|
55
|
+
weapon: "武器",
|
56
|
+
politics: "涉政",
|
57
|
+
violence: "打斗",
|
58
|
+
crowd: "聚众",
|
59
|
+
parade: "游行",
|
60
|
+
carcrash: "车祸现场",
|
61
|
+
flag: "旗帜",
|
62
|
+
location: "地标",
|
63
|
+
drug: "涉毒",
|
64
|
+
gamble: "赌博",
|
65
|
+
others: "其他",
|
66
|
+
},
|
67
|
+
ad: {
|
68
|
+
normal: "正常",
|
69
|
+
ad: "其他广告",
|
70
|
+
politics: "文字含涉政内容",
|
71
|
+
porn: "文字含涉黄内容",
|
72
|
+
abuse: "文字含辱骂内容",
|
73
|
+
terrorism: "文字含暴恐内容",
|
74
|
+
contraband: "文字含违禁内容",
|
75
|
+
spam: "文字含其他垃圾内容",
|
76
|
+
npx: "牛皮癣广告",
|
77
|
+
qrcode: "含二维码",
|
78
|
+
programCode: "含小程序码",
|
79
|
+
},
|
80
|
+
qrcode: {
|
81
|
+
normal: "正常",
|
82
|
+
qrcode: "含二维码",
|
83
|
+
programCode: "含小程序码",
|
84
|
+
},
|
85
|
+
live: {
|
86
|
+
normal: "正常",
|
87
|
+
meaningless: "图片中无内容(例如黑屏、白屏)",
|
88
|
+
PIP: "画中画",
|
89
|
+
smoking: "吸烟",
|
90
|
+
drivelive: "车内直播",
|
91
|
+
drug: "涉毒",
|
92
|
+
gamble: "赌博",
|
93
|
+
},
|
94
|
+
logo: {
|
95
|
+
normal: "正常",
|
96
|
+
TV: "含受管控的logo",
|
97
|
+
trademark: "含商标",
|
98
|
+
},
|
99
|
+
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
private
|
104
|
+
|
105
|
+
def check_tasks(tasks)
|
106
|
+
raise ArgumentError, "tasks must be an Array" unless tasks.is_a?(Array)
|
107
|
+
raise ArgumentError, "tasks size must no more than 100" unless tasks.size <= 100
|
108
|
+
raise ArgumentError, "tasks must be an Array of Hash with necessary key url" unless tasks.all? { |task| task.is_a?(Hash) || task.keys.include?(:url) }
|
109
|
+
end
|
110
|
+
|
111
|
+
def calc_valid_scenes(options)
|
112
|
+
scenes = options[:secnes] || options["secnes"] || []
|
113
|
+
|
114
|
+
valid_scenes = scenes.select { |x| scene_dict.keys.map(&:to_s).include? x.to_s }
|
115
|
+
valid_scenes = ["porn", "terrorism"] if valid_scenes.size == 0
|
116
|
+
end
|
117
|
+
|
118
|
+
# 需要先在内容安全/设置/机器审核/业务场景: default 中进行初始配置是
|
119
|
+
def build_payload(tasks, options)
|
120
|
+
scenes = calc_valid_scenes(options)
|
121
|
+
payload = {
|
122
|
+
bizType: "default",
|
123
|
+
scenes: scenes,
|
124
|
+
tasks: tasks,
|
125
|
+
}
|
126
|
+
payload
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
data/lib/aliyun_green/text.rb
CHANGED
@@ -1,24 +1,37 @@
|
|
1
1
|
module AliyunGreen
|
2
2
|
module Text
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
class << self
|
4
|
+
def scan(content, data_id = nil)
|
5
|
+
tasks = [
|
6
|
+
{
|
7
|
+
dataId: data_id,
|
8
|
+
content: content,
|
9
|
+
},
|
10
|
+
]
|
10
11
|
|
11
|
-
|
12
|
+
response = AliyunGreen.client.post("/green/text/scan", build_payload(tasks))
|
12
13
|
|
13
|
-
|
14
|
-
|
14
|
+
response
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
def bulk_scan
|
18
|
+
# TODO
|
19
|
+
end
|
20
|
+
|
21
|
+
def feedback
|
22
|
+
# TODO
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def build_payload(tasks)
|
28
|
+
payload = {
|
29
|
+
bizType: "default",
|
30
|
+
scenes: ["antispam"],
|
31
|
+
tasks: tasks,
|
32
|
+
}
|
33
|
+
payload
|
34
|
+
end
|
22
35
|
end
|
23
36
|
end
|
24
|
-
end
|
37
|
+
end
|
data/lib/aliyun_green/version.rb
CHANGED
data/lib/aliyun_green.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require_relative "aliyun_green/version"
|
3
3
|
require_relative "aliyun_green/text"
|
4
|
+
require_relative "aliyun_green/image"
|
4
5
|
require_relative "aliyun_green/error"
|
5
6
|
require_relative "aliyun_green/client"
|
6
7
|
require_relative "aliyun_green/configuration"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aliyun_green
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 42up
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-10-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpx
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: byebug
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
description: Write a longer description or delete this line.
|
28
42
|
email:
|
29
43
|
- foobar@v2up.com
|
@@ -46,6 +60,7 @@ files:
|
|
46
60
|
- lib/aliyun_green/client.rb
|
47
61
|
- lib/aliyun_green/configuration.rb
|
48
62
|
- lib/aliyun_green/error.rb
|
63
|
+
- lib/aliyun_green/image.rb
|
49
64
|
- lib/aliyun_green/text.rb
|
50
65
|
- lib/aliyun_green/version.rb
|
51
66
|
homepage: https://github.com/42up/aliyun_green
|