struggle 2.3.9 → 2.4.3
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 +5 -5
- data/README.md +0 -0
- data/lib/collection/chromedriver +0 -0
- data/lib/collection/taobao.rb +75 -0
- data/lib/collection.rb +10 -0
- data/lib/generators/struggle/backup_config_generator.rb +0 -0
- data/lib/generators/struggle/sql_config_generator.rb +0 -0
- data/lib/pay/jd_gateway.rb +0 -0
- data/lib/struggle/aes.rb +60 -58
- data/lib/struggle/backup.rb +0 -0
- data/lib/struggle/concerns/decimal_extend.rb +0 -0
- data/lib/struggle/concerns/int_extend.rb +0 -0
- data/lib/struggle/concerns/string_extend.rb +0 -0
- data/lib/struggle/concerns/time_extend.rb +0 -0
- data/lib/struggle/concerns/timestamps_format.rb +31 -0
- data/lib/struggle/font/ARIALNBI.TTF +0 -0
- data/lib/struggle/ftp_tool.rb +0 -0
- data/lib/struggle/getui.rb +72 -70
- data/lib/struggle/http.rb +16 -7
- data/lib/struggle/logistic.rb +3 -3
- data/lib/struggle/pager.rb +0 -0
- data/lib/struggle/rsa.rb +35 -33
- data/lib/struggle/sms.rb +27 -0
- data/lib/struggle/sql.rb +0 -0
- data/lib/struggle/tfile.rb +0 -0
- data/lib/struggle/tmagick.rb +0 -0
- data/lib/struggle/translate.rb +117 -0
- data/lib/struggle/zip_tool.rb +0 -0
- data/lib/struggle.rb +4 -0
- data/lib/templates/backup.yml +0 -0
- data/lib/templates/tsql_config.yml +0 -0
- metadata +37 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8fd0fe098d5b9742470ed55c764daced3c5101f14d7aa6248d330d2f6764a83
|
4
|
+
data.tar.gz: bd99a799faeabf1a42024f85847658d7461bfc715d0876b92b8eebaf12a03b51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7ae9954e08a7a3a9e3f1aeba53a3181bb35d7ff518b3d9d4293d2a5dcec15979052559ed937ab2652e1a5aa72a198ca488a79146e36baacafec8e5403a489219
|
7
|
+
data.tar.gz: ed35daa24d047b86fe4c6e1eab8b8bfc0f6c418eed8d0b3b0ed78e9c75c6398701accb939253b617ebf53c1fc5be541e327e6ca75104b27f8158bca136650c83
|
data/README.md
CHANGED
File without changes
|
Binary file
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# gem 'watir'
|
2
|
+
# gem 'selenium-webdriver'
|
3
|
+
module Collection
|
4
|
+
class Taobao
|
5
|
+
|
6
|
+
def self.run(url)
|
7
|
+
# 注释部分为浏览器驱动,可以隐藏运行浏览器。但是抓取淘宝失效,淘宝必须开启浏览器。
|
8
|
+
# filePath = File.expand_path(File.dirname(File.dirname(__FILE__)))
|
9
|
+
# chromedriverPath = File.expand_path("collection/chromedriver", filePath)
|
10
|
+
# Selenium::WebDriver::Chrome.driver_path = chromedriverPath
|
11
|
+
# options = Selenium::WebDriver::Chrome::Options.new
|
12
|
+
# options.add_argument("headless")
|
13
|
+
# browser = Watir::Browser.new :chrome, options: options
|
14
|
+
browser = Watir::Browser.new :chrome
|
15
|
+
browser.goto url
|
16
|
+
images = []
|
17
|
+
browser.div(id: "description").imgs.each do |img|
|
18
|
+
img.scroll_into_view
|
19
|
+
sleep 2
|
20
|
+
puts img.src
|
21
|
+
images << img.src
|
22
|
+
end
|
23
|
+
browser.close
|
24
|
+
{imgpath: down(images), text: get_text(images)}
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.get_text(urls)
|
28
|
+
gettoken = Struggle::Http.new("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=ob5etUcqOmPr7HA5co98yreC&client_secret=puRIlGWeOtaLbbPr5zZfeyNgLEC88wyF")
|
29
|
+
tokenresult = eval gettoken.post.body
|
30
|
+
token = tokenresult[:access_token]
|
31
|
+
words = []
|
32
|
+
urls.each do |url|
|
33
|
+
getText = Struggle::Http.new("https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic?access_token=" + token)
|
34
|
+
text = getText.post({url: url}, {"Content-Type" => "application/x-www-form-urlencoded"})
|
35
|
+
r = eval text.body
|
36
|
+
if r[:words_result] && r[:words_result].length > 0
|
37
|
+
words += r[:words_result].collect {|w| w[:words]}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
words.join("\r\n")
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.down(urls)
|
44
|
+
urls.each_with_index do |url, idx|
|
45
|
+
url = url[0..3] == "http" ? url : "https:#{url}"
|
46
|
+
data = open(url, 'User-Agent' => 'ruby') {|f| f.read}
|
47
|
+
fmidx = url.rindex(".")
|
48
|
+
fm = url[fmidx + 1, url.length - fmidx]
|
49
|
+
|
50
|
+
path = "#{Rails.root}/taobao"
|
51
|
+
FileUtils.mkdir(path) unless Dir.exists? path
|
52
|
+
file = File.new("#{path}/#{idx}.#{fm}", 'w+')
|
53
|
+
file.binmode
|
54
|
+
file << data
|
55
|
+
file.flush
|
56
|
+
file.close
|
57
|
+
end
|
58
|
+
merge_image
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.merge_image
|
62
|
+
images = []
|
63
|
+
Dir.foreach("#{Rails.root}/taobao").each do |file|
|
64
|
+
if file != "." and file != ".."
|
65
|
+
images << "#{Rails.root}/taobao/" + file
|
66
|
+
end
|
67
|
+
end
|
68
|
+
saveImgPath = "#{Rails.root}/taobao_img/#{Time.now.strftime "%Y%m%d%H%M%S"}.jpg"
|
69
|
+
system <<-EOF
|
70
|
+
convert -append #{images.join(" ")} #{saveImgPath}
|
71
|
+
EOF
|
72
|
+
saveImgPath
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/collection.rb
ADDED
File without changes
|
File without changes
|
data/lib/pay/jd_gateway.rb
CHANGED
File without changes
|
data/lib/struggle/aes.rb
CHANGED
@@ -1,76 +1,78 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
1
|
+
module Struggle
|
2
|
+
class Aes
|
3
|
+
# aes =
|
4
|
+
def initialize(key)
|
5
|
+
@@key = key
|
6
|
+
end
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
# 加密,key 秘钥, encrypted_string 需要加密的内容
|
9
|
+
def encrypt(encrypted_string)
|
10
|
+
aes = OpenSSL::Cipher::Cipher.new("AES-256-ECB").clone
|
11
|
+
aes.encrypt
|
12
|
+
aes.key = @@key
|
13
|
+
txt = aes.update(encrypted_string) << aes.final
|
14
|
+
txt.unpack('H*')[0].upcase
|
15
|
+
end
|
15
16
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
# 解密,key 秘钥, decrypted_string 需要解密的内容
|
18
|
+
def decrypt(decrypted_string)
|
19
|
+
aes = OpenSSL::Cipher::Cipher.new("AES-256-ECB").clone
|
20
|
+
aes.decrypt
|
21
|
+
aes.key = @@key
|
22
|
+
aes.update([decrypted_string].pack('H*')) << aes.final
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
# 文件内容加密并保存
|
26
|
+
def file_encrypt(filename)
|
27
|
+
if File.exist? filename
|
28
|
+
puts filename
|
29
|
+
content = File.read(filename)
|
30
|
+
unless content.blank?
|
31
|
+
File.write(filename, encrypt(Base64.encode64(content.force_encoding("UTF-8"))))
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
|
-
end
|
34
35
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
# 文件内容解密并保存
|
37
|
+
def file_decrypt(filename)
|
38
|
+
if File.exist? filename
|
39
|
+
puts filename
|
40
|
+
content = File.read(filename)
|
41
|
+
unless content.blank?
|
42
|
+
File.write(filename, Base64.decode64(decrypt(content)).force_encoding("UTF-8"))
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
44
|
-
end
|
45
46
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
# 目录递归所有文件加密
|
48
|
+
def dir_encrypt(path)
|
49
|
+
get_file_list(path).each do |fn|
|
50
|
+
file_encrypt(fn)
|
51
|
+
end
|
50
52
|
end
|
51
|
-
end
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
# 目录递归所有文件解密
|
55
|
+
def dir_decrypt(path)
|
56
|
+
get_file_list(path).each do |fn|
|
57
|
+
file_decrypt(fn)
|
58
|
+
end
|
57
59
|
end
|
58
|
-
end
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if
|
67
|
-
|
68
|
-
|
69
|
-
|
61
|
+
private
|
62
|
+
|
63
|
+
# 递归目录下所有文件
|
64
|
+
def get_file_list(path)
|
65
|
+
files = []
|
66
|
+
Dir.entries(path).each do |sub|
|
67
|
+
if sub != '.' && sub != '..'
|
68
|
+
if File.directory?("#{path}/#{sub}")
|
69
|
+
get_file_list("#{path}/#{sub}")
|
70
|
+
else
|
71
|
+
files << "#{path}/#{sub}"
|
72
|
+
end
|
70
73
|
end
|
71
74
|
end
|
75
|
+
files
|
72
76
|
end
|
73
|
-
files
|
74
77
|
end
|
75
|
-
|
76
78
|
end
|
data/lib/struggle/backup.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
module Struggle
|
3
|
+
module TimestampsFormat
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
# created_at updated_at 删除 '+0800'
|
8
|
+
# 删除集合中的created_at和updated_at的'+0800'
|
9
|
+
scope :to_hash, -> do
|
10
|
+
objs = []
|
11
|
+
each do |obj|
|
12
|
+
objs << obj.to_hash
|
13
|
+
end
|
14
|
+
objs
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
obj = self.serializable_hash
|
19
|
+
obj.each do |k, v|
|
20
|
+
if v.class == ActiveSupport::TimeWithZone
|
21
|
+
obj[k] = v.localtime.to_s(:db)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
obj
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
File without changes
|
data/lib/struggle/ftp_tool.rb
CHANGED
File without changes
|
data/lib/struggle/getui.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
require 'digest'
|
2
|
-
|
3
|
-
class
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
module Struggle
|
3
|
+
class Getui
|
4
|
+
class << self
|
5
|
+
AppID = "XxESwIkfcwAKhgIcQ0iyl8"
|
6
|
+
AppKey = "9WY9yq0cxj5O7kPJT72om9"
|
7
|
+
AppSecret = "RkZ9pNxnXl7hHYG4NX1s19"
|
8
|
+
MasterSecret = "ie5ftISOpv97cgTBsiigaA"
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
# 签权,获取权限。返回bool值,成功签权返回true,否则返回false。 @@auth_token 全局token
|
11
|
+
def sign
|
12
|
+
timestamp = "#{Time.now.to_i}000"
|
13
|
+
sign = Digest::SHA256.hexdigest(AppKey + timestamp + MasterSecret)
|
14
|
+
# sign = Digest::SHA256.base64digest sign
|
15
|
+
command = <<EOF
|
15
16
|
curl -H "Content-Type: application/json" \\
|
16
17
|
https://restapi.getui.com/v1/#{AppID}/auth_sign \\
|
17
18
|
-XPOST -d '{ "sign":"#{sign}",
|
@@ -19,28 +20,28 @@ curl -H "Content-Type: application/json" \\
|
|
19
20
|
"appkey":"#{AppKey}"
|
20
21
|
}'
|
21
22
|
EOF
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
r = JSON.parse `#{command}`
|
24
|
+
r["result"] == "ok" ? @@auth_token = r["auth_token"] : nil
|
25
|
+
end
|
25
26
|
|
26
|
-
|
27
|
-
|
28
|
-
|
27
|
+
# 关闭签权,return bool,success true, error false
|
28
|
+
def close
|
29
|
+
command = <<EOF
|
29
30
|
curl -H "authtoken: #{@@auth_token}" \
|
30
31
|
https://restapi.getui.com/v1/#{AppID}/auth_close \
|
31
32
|
-XPOST
|
32
33
|
EOF
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
r = JSON.parse `#{command}`
|
35
|
+
r["result"] == "ok"
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
# 单推
|
39
|
+
# 参数 cid:client_id, title: 标题, text: 消息内容, is_offline是否离线默认否。
|
40
|
+
# 返回值 bool,success true, error false
|
41
|
+
def onePush(cid, title, text, is_offline = false)
|
42
|
+
if sign
|
43
|
+
requestid = Random.new.rand(1000000000000000000000..99999999999999999999999)
|
44
|
+
command = <<EOF
|
44
45
|
curl -H "Content-Type: application/json" \
|
45
46
|
-H "authtoken:#{@@auth_token}" \
|
46
47
|
https://restapi.getui.com/v1/#{AppID}/push_single \
|
@@ -64,45 +65,45 @@ curl -H "Content-Type: application/json" \
|
|
64
65
|
"requestid": "#{requestid}"
|
65
66
|
}'
|
66
67
|
EOF
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
r = JSON.parse `#{command}`
|
69
|
+
close
|
70
|
+
return r["result"] == "ok"
|
71
|
+
else
|
72
|
+
return false
|
73
|
+
end
|
72
74
|
end
|
73
|
-
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
76
|
+
# 多推
|
77
|
+
# 参数 clients: 客户信息数组格式[{cid: "xxx", title: "xxx", text: "xxx", is_offline: false}],
|
78
|
+
# 具体组成 cid:client_id, title: 标题, text: 消息内容, is_offline是否离线默认否。
|
79
|
+
# 返回值 bool,success true, error false
|
80
|
+
def manyPush(clients)
|
81
|
+
if sign
|
82
|
+
msg_list = []
|
83
|
+
clients.each do |c|
|
84
|
+
requestid = Random.new.rand(1000000000000000000000..99999999999999999999999)
|
85
|
+
msg_list << {
|
86
|
+
"message": {
|
87
|
+
"appkey": "#{AppKey}",
|
88
|
+
"is_offline": c[:is_offline] || false,
|
89
|
+
"offline_expire_time": 100000000,
|
90
|
+
"msgtype": "notification"
|
91
|
+
},
|
92
|
+
"notification": {
|
93
|
+
"style": {
|
94
|
+
"type": 0,
|
95
|
+
"text": "#{c[:text]}",
|
96
|
+
"title": "#{c[:title]}"
|
97
|
+
},
|
98
|
+
"transmission_type": true,
|
99
|
+
"transmission_content": "透传内容"
|
100
|
+
},
|
101
|
+
"cid": "#{c[:cid]}",
|
102
|
+
"requestid": "#{requestid}"
|
103
|
+
}
|
104
|
+
end
|
104
105
|
|
105
|
-
|
106
|
+
command = <<EOF
|
106
107
|
curl -H "Content-Type: application/json" \
|
107
108
|
-H "authtoken:#{@@auth_token}" \
|
108
109
|
https://restapi.getui.com/v1/#{AppID}/push_single_batch \
|
@@ -111,13 +112,14 @@ curl -H "Content-Type: application/json" \
|
|
111
112
|
"need_detail":true
|
112
113
|
}'
|
113
114
|
EOF
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
r = JSON.parse `#{command}`
|
116
|
+
close
|
117
|
+
return r["result"] == "ok"
|
118
|
+
else
|
119
|
+
return false
|
120
|
+
end
|
119
121
|
end
|
120
|
-
end
|
121
122
|
|
123
|
+
end
|
122
124
|
end
|
123
125
|
end
|
data/lib/struggle/http.rb
CHANGED
@@ -9,14 +9,16 @@ module Struggle
|
|
9
9
|
def initialize(url)
|
10
10
|
@uri = URI.parse(url)
|
11
11
|
@http = Net::HTTP.new(@uri.host, @uri.port)
|
12
|
-
|
13
|
-
|
12
|
+
if @uri.scheme == 'https'
|
13
|
+
@http.use_ssl = true
|
14
|
+
@http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
15
|
+
end
|
14
16
|
end
|
15
17
|
|
16
18
|
# get请求,params为携带的参数,header为报文头数据,两个参数都是hash类型,示例
|
17
19
|
# http = Struggle::Http.new("http://xxx.com/xxx")
|
18
20
|
# result = http.post({name: 'lily', age: 18}).body
|
19
|
-
def get(params=nil, header=nil)
|
21
|
+
def get(params = nil, header = nil)
|
20
22
|
@request = Net::HTTP::Get.new(@uri.request_uri, header)
|
21
23
|
if !params.blank?
|
22
24
|
@request.form_data = params
|
@@ -26,16 +28,23 @@ module Struggle
|
|
26
28
|
|
27
29
|
# post请求,params为携带的参数为json类型,header为报文头数据为hash类型,示例:
|
28
30
|
# http = Struggle::Http.new("http://xxx.com/xxx")
|
29
|
-
# data = {name: 'lily', age: 18}
|
30
|
-
# result = http.post(data
|
31
|
+
# data = {name: 'lily', age: 18} || '{"aa":"bb"}'json类型(字符串)
|
32
|
+
# result = http.post(data, {'Content-Type' => 'application/json'}).body
|
31
33
|
# eval(result) => {status: 200, msg: 'success'}
|
32
|
-
def post(params=nil, header=nil)
|
34
|
+
def post(params = nil, header = nil)
|
33
35
|
@request = Net::HTTP::Post.new(@uri.request_uri, header)
|
34
36
|
if !params.blank?
|
35
|
-
|
37
|
+
if params.class == Hash
|
38
|
+
@request.set_form_data(params)
|
39
|
+
else
|
40
|
+
@request.body = params
|
41
|
+
end
|
36
42
|
end
|
37
43
|
@http.request(@request)
|
38
44
|
end
|
39
45
|
|
46
|
+
def encode(html)
|
47
|
+
html.force_encoding("gb2312").encode("utf-8")
|
48
|
+
end
|
40
49
|
end
|
41
50
|
end
|
data/lib/struggle/logistic.rb
CHANGED
@@ -7,17 +7,17 @@ module Struggle
|
|
7
7
|
URL_loophold = "http://www.kuaidi100.com/query"
|
8
8
|
|
9
9
|
def self.send(id, com, nu, show="json", muti=1, order="desc")
|
10
|
-
respond = Http.get(
|
10
|
+
respond = Http.new(URL).get({'id' => id, 'com' => com, 'nu' => nu, 'show' => show, 'muti' => muti, 'order' => order})
|
11
11
|
puts respond.body
|
12
12
|
return respond.body.blank? ? nil : JSON.parse(respond.body)
|
13
13
|
end
|
14
14
|
|
15
15
|
def self.sendByLoophold(type, postid)
|
16
|
-
respond = Http.post(
|
16
|
+
respond = Http.new(URL_loophold).post({'type' => type, 'postid' => postid})
|
17
17
|
return respond.body.blank? ? nil : JSON.parse(respond.body)
|
18
18
|
end
|
19
19
|
|
20
|
-
Company = {"anxindakuaixi" => "安信达",
|
20
|
+
Company = {"anxindakuaixi" => "安信达","huitongkuaidi" => "百世快递", "baifudongfang" => "百福东方", "bht" => "BHT", "bangsongwuliu" => "邦送物流",
|
21
21
|
"coe" => "中国东方(COE)", "chuanxiwuliu" => "传喜物流", "datianwuliu" => "大田物流",
|
22
22
|
"debangwuliu" => "德邦物流","dpex" => "DPEX", "dhl" => "DHL-中国件", "dsukuaidi" => "D速快递", "disifang" => "递四方",
|
23
23
|
"ems" => "EMS-(中国-中国)件", "feikangda" => "飞康达物流", "feikuaida" => "飞快达", "rufengda" => "凡客如风达",
|
data/lib/struggle/pager.rb
CHANGED
File without changes
|
data/lib/struggle/rsa.rb
CHANGED
@@ -1,43 +1,45 @@
|
|
1
1
|
# = RSA工具,基于openssl,功能包括,秘钥生成,加密解密
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
module Struggle
|
3
|
+
class Rsa
|
4
|
+
# 实例化Rsa类,keyfile是秘钥文件地址(公钥或私钥)文件格式pem
|
5
|
+
def initialize(keyfile)
|
6
|
+
keystr = File.read(keyfile)
|
7
|
+
if keystr
|
8
|
+
@@rsa = OpenSSL::PKey::RSA.new(keystr)
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
# Rsa.generate("/Users/apple/object") => /Users/apple/object/private_key.pem ,public_key.pem
|
13
|
+
# 创建2048位秘钥文件
|
14
|
+
def self.generate(dir)
|
15
|
+
pk = OpenSSL::PKey::RSA.generate(2048)
|
16
|
+
File.write(dir + "/private_key.pem", pk.to_pem)
|
17
|
+
File.write(dir + "/public_key.pem", pk.public_key.to_pem)
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# 私钥加密
|
21
|
+
def private_encrypt(value)
|
22
|
+
Base64.encode64(@@rsa.private_encrypt(value.force_encoding("UTF-8"))) unless value.blank?
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
# 私钥解密
|
26
|
+
def private_decrypt(value)
|
27
|
+
@@rsa.private_decrypt(Base64.decode64(value.force_encoding("UTF-8"))) unless value.blank?
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
# 公钥加密
|
31
|
+
def public_encrypt(value)
|
32
|
+
Base64.encode64(@@rsa.public_encrypt(value.force_encoding("UTF-8"))) unless value.blank?
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
# 公钥解密
|
36
|
+
def public_decrypt(value)
|
37
|
+
@@rsa.public_decrypt(Base64.decode64(value.force_encoding("UTF-8"))) unless value.blank?
|
38
|
+
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
# 签名
|
41
|
+
def sign(value)
|
42
|
+
@@rsa.sign("sha1", value)
|
43
|
+
end
|
42
44
|
end
|
43
45
|
end
|
data/lib/struggle/sms.rb
CHANGED
@@ -8,5 +8,32 @@ module Struggle
|
|
8
8
|
response = Http.post(URL, {'ac' => "send", 'uid' => uid, 'pwd' => pwd, 'mobile' => mobile, 'content' => content})
|
9
9
|
return response.body=="100"
|
10
10
|
end
|
11
|
+
|
12
|
+
# 腾讯短信单发接口
|
13
|
+
# 参数
|
14
|
+
# 1.sdkappid,请填写您在腾讯云上申请到的appid 示例:1400147773
|
15
|
+
# 2.appkey,sdkappid对应的的appkey 示例:f1c0cae4ee52489abe711d48a7e7789c
|
16
|
+
# 3.tpl_id,短信模板id 示例:205045
|
17
|
+
# 4.sign,开通得短信的应用名称,一般是公司名称缩写。 示例:微象科技
|
18
|
+
# 5.mobile,接收短信的手机号码
|
19
|
+
# 6.content,发送的变量内容,对应模板中的变量{0},类型为string数组
|
20
|
+
def Sms.tx_send(sdkappid, appkey, tpl_id, sign, mobile, content)
|
21
|
+
random = Random.new.rand(100000..999999)
|
22
|
+
time = Time.now.to_i
|
23
|
+
data = {:ext=>"", :extend=>"", :params=>content,
|
24
|
+
:sig=>Digest::SHA256.hexdigest("appkey=#{appkey}&random=#{random}&time=#{time}&mobile=#{mobile}"),
|
25
|
+
:sign=>sign, :tel=>{:mobile=>mobile, :nationcode=>"86"}, :time => time, :tpl_id=>tpl_id}
|
26
|
+
url = "https://yun.tim.qq.com/v5/tlssmssvr/sendsms?sdkappid=#{sdkappid}&random=#{random}"
|
27
|
+
body = Http.new(url).post(data.to_json).body
|
28
|
+
if !body.blank?
|
29
|
+
result = eval body
|
30
|
+
if result[:result] == 0
|
31
|
+
return {state: true}
|
32
|
+
else
|
33
|
+
return {state: false, msg: result[:errmsg]}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
return {state: false, msg:"腾讯短信平台无响应,发送失败。"}
|
37
|
+
end
|
11
38
|
end
|
12
39
|
end
|
data/lib/struggle/sql.rb
CHANGED
File without changes
|
data/lib/struggle/tfile.rb
CHANGED
File without changes
|
data/lib/struggle/tmagick.rb
CHANGED
File without changes
|
@@ -0,0 +1,117 @@
|
|
1
|
+
module Struggle
|
2
|
+
class Translate
|
3
|
+
require 'uri'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'rexml/document'
|
6
|
+
|
7
|
+
ICIBA_URL = "http://dict-co.iciba.com/api/dictionary.php"
|
8
|
+
ICIBA_KEY = "36CC7638D81785E7006BB5B29DBA1FEF"
|
9
|
+
|
10
|
+
BAIDU_URL = "http://api.fanyi.baidu.com/api/trans/vip/translate"
|
11
|
+
BAIDU_APPID = "20180719000186861"
|
12
|
+
BAIDU_KEY = "QvOMjlxoc3xY1ComqF7P"
|
13
|
+
|
14
|
+
YOUDAO_URL = "http://fanyi.youdao.com/openapi.do"
|
15
|
+
YOUDAO_KEY = "29324956"
|
16
|
+
YOUDAO_KEYFROM = "wordtest"
|
17
|
+
|
18
|
+
GOOGLE_URL = "https://translate.google.com.hk/translate_a/t"
|
19
|
+
|
20
|
+
def self.httpget(url)
|
21
|
+
content = ""
|
22
|
+
open(url) do |http|
|
23
|
+
content << http.read
|
24
|
+
end
|
25
|
+
return content
|
26
|
+
end
|
27
|
+
|
28
|
+
#获取爱词霸翻译结果
|
29
|
+
#参数: word => 单词
|
30
|
+
#返回: 成功返回hash, key:单词, ps:音标, pron:英语发音, pron2:美式发音, zn:翻译
|
31
|
+
def self.iciba(word)
|
32
|
+
begin
|
33
|
+
url = "#{self::ICIBA_URL}?w=#{URI.escape(word)}&key=#{self::ICIBA_KEY}"
|
34
|
+
content = self.httpget(url)
|
35
|
+
xml = REXML::Document.new(content)
|
36
|
+
key = xml.get_elements("/dict/key")[0]
|
37
|
+
if key && word == key.text #判断返回成功
|
38
|
+
psxml = xml.get_elements("/dict/ps")[0] #音标
|
39
|
+
ps = psxml.text if psxml
|
40
|
+
pronxml = xml.get_elements("/dict/pron")[0]
|
41
|
+
pron = pronxml.text if pronxml
|
42
|
+
pron2xml = xml.get_elements("/dict/pron")[1]
|
43
|
+
pron2 = pron2xml.text if pron2xml
|
44
|
+
acceptations = xml.get_elements("/dict/acceptation") #中文翻译
|
45
|
+
poses = xml.get_elements("/dict/pos") #动词,形容词。。
|
46
|
+
zn = ""
|
47
|
+
if poses && acceptations
|
48
|
+
1.upto(acceptations.count) do |i|
|
49
|
+
zn = zn + poses[i - 1].text + acceptations[i - 1].text + "|"
|
50
|
+
end
|
51
|
+
if ps && zn
|
52
|
+
return {key: key.text, ps: ps, pron: pron, pron2: pron2, zn: zn}
|
53
|
+
else
|
54
|
+
return nil
|
55
|
+
end
|
56
|
+
else
|
57
|
+
return nil
|
58
|
+
end
|
59
|
+
else
|
60
|
+
return nil
|
61
|
+
end
|
62
|
+
rescue
|
63
|
+
return nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#google翻译,eval出错,不能转换成数组,因为有存在俩个逗号中没有值的情况,可以替换双逗号解决,但是没有音标
|
68
|
+
#参数: word => 单词
|
69
|
+
#返回: string,翻译的中文结果
|
70
|
+
def self.google(word)
|
71
|
+
begin
|
72
|
+
url = "#{self::GOOGLE_URL}?client=t&sl=en&tl=zh-CN&hl=zh-CN&sc=2&ie=UTF-8&oe=UTF-8&oc=1&otf=2&ssel=0&tsel=0&q=#{URI.escape(word)}"
|
73
|
+
content = self.httpget(url)
|
74
|
+
if content
|
75
|
+
return eval(content.gsub(',,', ',').gsub(',,', ',').gsub(',,', ','))[0][0][0] #有没有值的,arr[0][0][0]是翻译,但是谷歌不支持音标,只支持翻译后的中文拼音
|
76
|
+
else
|
77
|
+
return nil
|
78
|
+
end
|
79
|
+
rescue
|
80
|
+
return nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
#百度翻译,同样没有音标,只返回翻译结果
|
85
|
+
#参数: word => 单词
|
86
|
+
#返回: string,翻译的中文结果
|
87
|
+
def self.baidu(word)
|
88
|
+
salt = Random.new.rand(10000..99999)
|
89
|
+
#appid+q+salt+密钥
|
90
|
+
sign = Digest::MD5.new.hexdigest "#{self::BAIDU_APPID}#{word}#{salt}#{self::BAIDU_KEY}"
|
91
|
+
begin
|
92
|
+
url = "#{self::BAIDU_URL}?appid=#{self::BAIDU_APPID}&q=#{URI.escape(word)}&from=auto&to=auto&salt=#{salt}&sign=#{sign}"
|
93
|
+
content = self.httpget(url)
|
94
|
+
contenthash = eval content.gsub(":", "=>")
|
95
|
+
return contenthash["trans_result"][0]["dst"]
|
96
|
+
rescue
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#有道翻译,只支持英文翻译
|
102
|
+
#参数: word => 单词
|
103
|
+
#返回: 成功返回hash, key:单词, ps:音标, zn:翻译;失败返回nil
|
104
|
+
def self.youdao(word)
|
105
|
+
begin
|
106
|
+
url = "#{self::YOUDAO_URL}?keyfrom=#{self::YOUDAO_KEYFROM}&key=#{self::YOUDAO_KEY}&type=data&doctype=json&version=1.1&q=#{URI.escape(word)}"
|
107
|
+
content = self.httpget(url)
|
108
|
+
contenthash = eval(content.gsub(":", "=>"))
|
109
|
+
return {'key' => contenthash["query"],
|
110
|
+
'ps' => contenthash["basic"]["phonetic"],
|
111
|
+
'zn' => contenthash["basic"]["explains"].join("|")}
|
112
|
+
rescue
|
113
|
+
return nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/struggle/zip_tool.rb
CHANGED
File without changes
|
data/lib/struggle.rb
CHANGED
@@ -20,11 +20,15 @@ require 'struggle/concerns/string_extend'
|
|
20
20
|
require 'struggle/concerns/int_extend'
|
21
21
|
require 'struggle/concerns/decimal_extend'
|
22
22
|
require 'struggle/concerns/time_extend'
|
23
|
+
require 'struggle/concerns/timestamps_format'
|
23
24
|
require "struggle/ftp_tool"
|
25
|
+
require "struggle/translate"
|
24
26
|
require "struggle/zip_tool"
|
25
27
|
require 'struggle/sql'
|
26
28
|
require 'struggle/backup'
|
27
29
|
require 'pay/jd_gateway'
|
30
|
+
|
31
|
+
ActiveRecord::Base.send :include, Struggle::TimestampsFormat
|
28
32
|
String.send :include, Struggle::StringExtend
|
29
33
|
Integer.send :include, Struggle::IntExtend
|
30
34
|
Numeric.send :include, Struggle::DecimalExtend
|
data/lib/templates/backup.yml
CHANGED
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: struggle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3
|
4
|
+
version: 2.4.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- lean
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: iconv
|
@@ -52,7 +52,35 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
-
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: watir
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: selenium-webdriver
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description: code,tfile,pager,http,logistic,pay,tmagick,class_extend,aes,rsa,ftp_tool,translate,zip_tool,sql,backup,collection;
|
56
84
|
email: 54850915@qq.com
|
57
85
|
executables: []
|
58
86
|
extensions: []
|
@@ -60,6 +88,9 @@ extra_rdoc_files:
|
|
60
88
|
- README.md
|
61
89
|
files:
|
62
90
|
- README.md
|
91
|
+
- lib/collection.rb
|
92
|
+
- lib/collection/chromedriver
|
93
|
+
- lib/collection/taobao.rb
|
63
94
|
- lib/generators/struggle/backup_config_generator.rb
|
64
95
|
- lib/generators/struggle/sql_config_generator.rb
|
65
96
|
- lib/pay/jd_gateway.rb
|
@@ -71,6 +102,7 @@ files:
|
|
71
102
|
- lib/struggle/concerns/int_extend.rb
|
72
103
|
- lib/struggle/concerns/string_extend.rb
|
73
104
|
- lib/struggle/concerns/time_extend.rb
|
105
|
+
- lib/struggle/concerns/timestamps_format.rb
|
74
106
|
- lib/struggle/font/ARIALNBI.TTF
|
75
107
|
- lib/struggle/font/font.ttf
|
76
108
|
- lib/struggle/ftp_tool.rb
|
@@ -83,6 +115,7 @@ files:
|
|
83
115
|
- lib/struggle/sql.rb
|
84
116
|
- lib/struggle/tfile.rb
|
85
117
|
- lib/struggle/tmagick.rb
|
118
|
+
- lib/struggle/translate.rb
|
86
119
|
- lib/struggle/zip_tool.rb
|
87
120
|
- lib/templates/backup.yml
|
88
121
|
- lib/templates/tsql_config.yml
|
@@ -106,7 +139,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
139
|
version: '0'
|
107
140
|
requirements: []
|
108
141
|
rubyforge_project:
|
109
|
-
rubygems_version: 2.
|
142
|
+
rubygems_version: 2.7.7
|
110
143
|
signing_key:
|
111
144
|
specification_version: 4
|
112
145
|
summary: struggle!
|