rubirai 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/docs.yml +1 -1
- data/.github/workflows/pull_request.yml +3 -1
- data/README.md +12 -0
- data/lib/rubirai/messages/interpolation.rb +115 -0
- data/lib/rubirai/messages/message_chain.rb +16 -10
- data/lib/rubirai/utils.rb +10 -0
- data/lib/rubirai/version.rb +1 -1
- data/spec/messages/interpolation_spec.rb +64 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b91aff486d51f20061c25e988fabfb4adcf34b765f30bdd6f118858faafcb693
|
4
|
+
data.tar.gz: 2508fa6974b69f487098972e89ba2fe04f32fe566f5e04a14aadb595653cabcd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9676cbb324b9aed4abaca4d69f1f58791d0edb11434cb90ebc0bb9f1677d18c61d82d3b0709c9b0fca0eda176e2bd924dcaf5bb894f992ed77b27d06385f818a
|
7
|
+
data.tar.gz: 92e5e0e168ec5b6834beb81d1398c64e5521b15adc869b95f12ea8e3e54e65f9f33f41e6e789377c710ad695357890da2b71a8ccc110327f956dd7195a177c87
|
data/.github/workflows/docs.yml
CHANGED
data/README.md
CHANGED
@@ -11,6 +11,18 @@ A light-weight Mirai QQ bot http interface lib for Ruby.
|
|
11
11
|
|
12
12
|
[中文][wiki] | [Rubydocs][rubydocs]
|
13
13
|
|
14
|
+
## Description
|
15
|
+
|
16
|
+
This library is designed specifically for integration with [mirai-api-http].
|
17
|
+
[Mirai][mirai] is a QQ bot framework. The relationship is like this:
|
18
|
+
|
19
|
+
```
|
20
|
+
mirai <-jvm-> mirai-console <-plugin-> mirai-api-http <-http-> rubirai
|
21
|
+
```
|
22
|
+
|
23
|
+
[mirai-api-http]: https://github.com/project-mirai/mirai-api-http
|
24
|
+
[mirai]: https://github.com/mamoe/mirai
|
25
|
+
|
14
26
|
## Usage
|
15
27
|
|
16
28
|
First, download the package using `gem`. In your `Gemfile`, add
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rubirai/utils'
|
4
|
+
|
5
|
+
module Rubirai
|
6
|
+
# @!attribute [r] has_interpolation
|
7
|
+
# @return [Boolean] if this message chain has interpolation called by {#interpolated_str}
|
8
|
+
class MessageChain
|
9
|
+
attr_reader :has_interpolation
|
10
|
+
|
11
|
+
# Convert the message chain to an interpolated string.
|
12
|
+
#
|
13
|
+
# @return [String]
|
14
|
+
def interpolated_str
|
15
|
+
return @interpolated_str if @has_interpolation
|
16
|
+
@interpolated_str = _gen_interp_str
|
17
|
+
@has_interpolation = true
|
18
|
+
@interpolated_str
|
19
|
+
end
|
20
|
+
|
21
|
+
# Get the interpolated object by given id
|
22
|
+
#
|
23
|
+
# @param obj_id [String] the object id
|
24
|
+
# @return [Message, nil] the message. `nil` if `obj_id` is malformed or not found.
|
25
|
+
def get_object(obj_id)
|
26
|
+
_get_object(obj_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Get a new chain from interpolated string generated from the original message chain.
|
30
|
+
# The given interpolated string can be a substring of original one so that elements
|
31
|
+
# can be extracted easily.
|
32
|
+
#
|
33
|
+
# @param str [String] the interpolated string
|
34
|
+
# @return [MessageChain] the message chain constructed
|
35
|
+
def chain_from_interpolated(str)
|
36
|
+
_interpolate_with_objects(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
OBJ_INTERP_CHAR = '%'
|
42
|
+
OBJ_INTERP_LEN = 6
|
43
|
+
|
44
|
+
def _gen_interp_str
|
45
|
+
result = +''
|
46
|
+
@messages.each do |msg|
|
47
|
+
result << case msg
|
48
|
+
when PlainMessage
|
49
|
+
_transform_plain_txt(msg.text)
|
50
|
+
else
|
51
|
+
_transform_object(msg)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def _transform_plain_txt(str)
|
58
|
+
str.gsub(OBJ_INTERP_CHAR, OBJ_INTERP_CHAR * 2)
|
59
|
+
end
|
60
|
+
|
61
|
+
def _transform_object(obj)
|
62
|
+
obj_id = Utils.random_str(OBJ_INTERP_LEN)
|
63
|
+
obj_id = Utils.random_str(OBJ_INTERP_LEN) while @ipl_objs_map.include?(obj_id)
|
64
|
+
@ipl_objs_map[obj_id] = obj
|
65
|
+
"#{OBJ_INTERP_CHAR}#{obj_id}#{OBJ_INTERP_CHAR}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def _get_object(obj_id)
|
69
|
+
return nil if obj_id.length != OBJ_INTERP_LEN && obj_id.length != (OBJ_INTERP_LEN + 2)
|
70
|
+
return @ipl_objs_map[obj_id] if obj_id.length == OBJ_INTERP_LEN
|
71
|
+
return nil if obj_id[0] != OBJ_INTERP_CHAR || obj_id[-1] != OBJ_INTERP_CHAR
|
72
|
+
|
73
|
+
@ipl_objs_map[obj_id[1...-1]]
|
74
|
+
end
|
75
|
+
|
76
|
+
# @private
|
77
|
+
# @param str [String]
|
78
|
+
def _interpolate_with_objects(str)
|
79
|
+
sb = +''
|
80
|
+
result = MessageChain.new(bot)
|
81
|
+
i = 0
|
82
|
+
while i < str.length
|
83
|
+
if i == str.length - 1
|
84
|
+
sb << str[i]
|
85
|
+
break
|
86
|
+
end
|
87
|
+
|
88
|
+
if str[i] != OBJ_INTERP_CHAR
|
89
|
+
sb << str[i]
|
90
|
+
i += 1
|
91
|
+
next
|
92
|
+
end
|
93
|
+
|
94
|
+
if str[i + 1] == OBJ_INTERP_CHAR
|
95
|
+
sb << OBJ_INTERP_CHAR
|
96
|
+
i += 1
|
97
|
+
else
|
98
|
+
result.append PlainMessage.from(text: sb) unless sb.empty?
|
99
|
+
sb = str[i...i + OBJ_INTERP_LEN + 2]
|
100
|
+
obj = _get_object(sb)
|
101
|
+
i += OBJ_INTERP_LEN + 1
|
102
|
+
unless obj.nil?
|
103
|
+
result.append obj
|
104
|
+
sb = +''
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
i += 1
|
109
|
+
end
|
110
|
+
|
111
|
+
result.append PlainMessage.from(text: sb) unless sb.nil? || sb.empty?
|
112
|
+
result
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -5,19 +5,20 @@ require 'rubirai/messages/message'
|
|
5
5
|
|
6
6
|
module Rubirai
|
7
7
|
# Message chain
|
8
|
+
#
|
9
|
+
# @!attribute [r] bot
|
10
|
+
# @return [Bot] the bot object
|
11
|
+
# @!attribute [r] id
|
12
|
+
# @return [Integer, nil] the message id, may be `nil`
|
13
|
+
# @!attribute [r] raw
|
14
|
+
# @return [Hash{String => Object}, nil] the raw message chain, may be `nil`
|
15
|
+
# @!attribute [r] send_time
|
16
|
+
# @return [Integer, nil] the send time of the message chain, may be `nil`
|
17
|
+
# @!attribute [r] messages
|
18
|
+
# @return [Array<Message>] the raw message array
|
8
19
|
class MessageChain
|
9
20
|
include Enumerable
|
10
21
|
|
11
|
-
# @!attribute [r] bot
|
12
|
-
# @return [Bot] the bot object
|
13
|
-
# @!attribute [r] id
|
14
|
-
# @return [Integer, nil] the message id, may be `nil`
|
15
|
-
# @!attribute [r] raw
|
16
|
-
# @return [Hash{String => Object}, nil] the raw message chain, may be `nil`
|
17
|
-
# @!attribute [r] send_time
|
18
|
-
# @return [Integer, nil] the send time of the message chain, may be `nil`
|
19
|
-
# @!attribute [r] messages
|
20
|
-
# @return [Array<Message>] the raw message array
|
21
22
|
attr_reader :bot, :id, :raw, :send_time, :messages
|
22
23
|
|
23
24
|
# Makes a message chain from a list of messages
|
@@ -92,6 +93,9 @@ module Rubirai
|
|
92
93
|
def initialize(bot = nil, source = nil)
|
93
94
|
@bot = bot
|
94
95
|
@messages = []
|
96
|
+
@has_interpolation = false
|
97
|
+
@interpolated_str = nil
|
98
|
+
@ipl_objs_map = {}
|
95
99
|
@raw = source
|
96
100
|
return unless source
|
97
101
|
raise(MiraiError, 'source is not array') unless source.is_a? Array
|
@@ -139,3 +143,5 @@ module Rubirai
|
|
139
143
|
MessageChain.make(*messages, bot: bot)
|
140
144
|
end
|
141
145
|
end
|
146
|
+
|
147
|
+
require 'rubirai/messages/interpolation'
|
data/lib/rubirai/utils.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'securerandom'
|
4
|
+
|
3
5
|
# @private
|
4
6
|
class Hash
|
5
7
|
def stringify_keys!
|
@@ -60,3 +62,11 @@ class Object
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
end
|
65
|
+
|
66
|
+
module Rubirai
|
67
|
+
module Utils
|
68
|
+
def self.random_str(len)
|
69
|
+
SecureRandom.alphanumeric len
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/rubirai/version.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
describe Rubirai::MessageChain do
|
4
|
+
before do
|
5
|
+
hash = {
|
6
|
+
"type": 'Quote',
|
7
|
+
"id": 123456,
|
8
|
+
"groupId": 123456789,
|
9
|
+
"senderId": 987654321,
|
10
|
+
"targetId": 9876543210,
|
11
|
+
"origin": [
|
12
|
+
{ "type": 'Plain', text: 'text' }.stringify_keys
|
13
|
+
]
|
14
|
+
}.stringify_keys
|
15
|
+
@obj = Rubirai::AtMessage.from(target: 114514)
|
16
|
+
@chain = Rubirai::MessageChain.make(
|
17
|
+
'hi%', 2, @obj, 3, 'great %%,', :good, hash
|
18
|
+
)
|
19
|
+
@expect_pattern = /^hi%%2%[a-zA-Z0-9]{6}%3great %%%%,good%[a-zA-Z0-9]{6}%$/
|
20
|
+
end
|
21
|
+
|
22
|
+
after do
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should convert message chains to strings correctly' do
|
26
|
+
expect(@chain.has_interpolation).to be_falsey
|
27
|
+
|
28
|
+
str = @chain.interpolated_str
|
29
|
+
expect(@chain.has_interpolation).to be_truthy
|
30
|
+
objs_map = @chain.instance_variable_get('@ipl_objs_map')
|
31
|
+
expect(objs_map.length).to be(2)
|
32
|
+
objs_map.each_key do |k|
|
33
|
+
expect(str.include?(k)).to be_truthy
|
34
|
+
end
|
35
|
+
expect(@expect_pattern.match?(str)).to be_truthy
|
36
|
+
expect(@chain.interpolated_str).to eq(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should get back the original object' do
|
40
|
+
str = @chain.interpolated_str
|
41
|
+
idx = 5
|
42
|
+
obj = @chain.get_object(str[idx...idx + 8])
|
43
|
+
expect(obj).to eq(@obj)
|
44
|
+
obj = @chain.get_object(str[idx + 1...idx + 7])
|
45
|
+
expect(obj).to eq(@obj)
|
46
|
+
expect(@chain.get_object(str[idx + 2...idx + 8])).to be_nil
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should construct new message chain for interpolated strings' do
|
50
|
+
str = @chain.interpolated_str[5...5 + 8 + 3]
|
51
|
+
chain = @chain.chain_from_interpolated(str)
|
52
|
+
expect(chain.length).to eq(2)
|
53
|
+
expect(chain[0]).to eq(@obj)
|
54
|
+
expect(chain[1]).to be_a(Rubirai::PlainMessage)
|
55
|
+
expect(chain[1].text).to eq('3gr')
|
56
|
+
|
57
|
+
chain = @chain.chain_from_interpolated(@chain.interpolated_str)
|
58
|
+
expect(chain.length).to eq(@chain.length)
|
59
|
+
expect(chain[0].text).to eq('hi%2')
|
60
|
+
expect(chain[1]).to eq(@obj)
|
61
|
+
expect(chain[2].text).to eq('3great %%,good')
|
62
|
+
expect(chain[3]).to be_a(Rubirai::QuoteMessage)
|
63
|
+
end
|
64
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubirai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rebuild
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|
@@ -73,6 +73,7 @@ files:
|
|
73
73
|
- lib/rubirai/listing.rb
|
74
74
|
- lib/rubirai/management.rb
|
75
75
|
- lib/rubirai/message.rb
|
76
|
+
- lib/rubirai/messages/interpolation.rb
|
76
77
|
- lib/rubirai/messages/message.rb
|
77
78
|
- lib/rubirai/messages/message_chain.rb
|
78
79
|
- lib/rubirai/multipart.rb
|
@@ -90,6 +91,7 @@ files:
|
|
90
91
|
- spec/error_spec.rb
|
91
92
|
- spec/events/event_spec.rb
|
92
93
|
- spec/message_spec.rb
|
94
|
+
- spec/messages/interpolation_spec.rb
|
93
95
|
- spec/messages/message_chain_spec.rb
|
94
96
|
- spec/messages/message_spec.rb
|
95
97
|
- spec/plugin_info_spec.rb
|