mij-discord 1.0.7 → 1.0.8
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/lib/mij-discord.rb +5 -10
- data/lib/mij-discord/bot.rb +32 -20
- data/lib/mij-discord/cache.rb +23 -8
- data/lib/mij-discord/core/api.rb +15 -4
- data/lib/mij-discord/core/api/channel.rb +0 -6
- data/lib/mij-discord/core/api/invite.rb +3 -2
- data/lib/mij-discord/core/api/webhook.rb +94 -0
- data/lib/mij-discord/data.rb +5 -1
- data/lib/mij-discord/data/application.rb +4 -0
- data/lib/mij-discord/data/channel.rb +34 -6
- data/lib/mij-discord/data/embed.rb +112 -0
- data/lib/mij-discord/data/emoji.rb +15 -2
- data/lib/mij-discord/data/invite.rb +20 -0
- data/lib/mij-discord/data/member.rb +10 -0
- data/lib/mij-discord/data/message.rb +25 -4
- data/lib/mij-discord/data/permissions.rb +16 -0
- data/lib/mij-discord/data/role.rb +5 -0
- data/lib/mij-discord/data/server.rb +22 -3
- data/lib/mij-discord/data/user.rb +43 -22
- data/lib/mij-discord/data/voice.rb +11 -0
- data/lib/mij-discord/data/webhook.rb +121 -0
- data/lib/mij-discord/errors.rb +44 -0
- data/lib/mij-discord/events.rb +4 -0
- data/lib/mij-discord/events/channel.rb +2 -0
- data/lib/mij-discord/extensions.rb +16 -0
- data/lib/mij-discord/logger.rb +9 -0
- data/lib/mij-discord/version.rb +1 -1
- metadata +6 -3
- data/lib/mij-discord/core/errors.rb +0 -106
@@ -41,6 +41,10 @@ module MijDiscord::Data
|
|
41
41
|
FLAGS.map {|bit, name| list.include?(name) ? bit : 0 }.reduce(&:|)
|
42
42
|
end
|
43
43
|
|
44
|
+
def self.flags(bits)
|
45
|
+
Set.new(FLAGS.map {|bit, name| (bits & bit).zero? ? nil : name }.reject(&:nil?))
|
46
|
+
end
|
47
|
+
|
44
48
|
FLAGS.each do |bit, name|
|
45
49
|
attr_reader name
|
46
50
|
alias_method :"#{name}?", name
|
@@ -71,6 +75,14 @@ module MijDiscord::Data
|
|
71
75
|
end
|
72
76
|
|
73
77
|
alias_method :bits=, :set_bits
|
78
|
+
|
79
|
+
def flags
|
80
|
+
Permissions.flags(@bits)
|
81
|
+
end
|
82
|
+
|
83
|
+
def inspect
|
84
|
+
%(#<Permissions #{flags.to_a}>)
|
85
|
+
end
|
74
86
|
end
|
75
87
|
|
76
88
|
class Overwrite
|
@@ -117,5 +129,9 @@ module MijDiscord::Data
|
|
117
129
|
def to_hash
|
118
130
|
{ id: @id, type: @type, allow: @allow.bits, deny: @deny.bits }
|
119
131
|
end
|
132
|
+
|
133
|
+
def inspect
|
134
|
+
MijDiscord.make_inspect(self, :id, :type, :allow, :deny)
|
135
|
+
end
|
120
136
|
end
|
121
137
|
end
|
@@ -93,5 +93,10 @@ module MijDiscord::Data
|
|
93
93
|
name, color&.to_i, hoist, mentionable, permissions&.to_i)
|
94
94
|
@server.cache.put_role(JSON.parse(response), update: true)
|
95
95
|
end
|
96
|
+
|
97
|
+
def inspect
|
98
|
+
MijDiscord.make_inspect(self,
|
99
|
+
:id, :name, :color, :position, :hoist, :mentionable, :managed, :permissions)
|
100
|
+
end
|
96
101
|
end
|
97
102
|
end
|
@@ -46,7 +46,7 @@ module MijDiscord::Data
|
|
46
46
|
alias_method :embed_enabled?, :embed_enabled
|
47
47
|
alias_method :has_embed?, :embed_enabled
|
48
48
|
|
49
|
-
|
49
|
+
attr_reader :member_count
|
50
50
|
|
51
51
|
attr_reader :verification_level
|
52
52
|
|
@@ -101,7 +101,7 @@ module MijDiscord::Data
|
|
101
101
|
id = data['afk_channel_id'].to_i
|
102
102
|
@afk_channel = @bot.channel(id, self)
|
103
103
|
end
|
104
|
-
rescue MijDiscord::Errors::
|
104
|
+
rescue MijDiscord::Errors::Forbidden
|
105
105
|
@afk_channel = nil
|
106
106
|
end
|
107
107
|
end
|
@@ -239,6 +239,11 @@ module MijDiscord::Data
|
|
239
239
|
JSON.parse(response).map {|x| Invite.new(x, @bot) }
|
240
240
|
end
|
241
241
|
|
242
|
+
def webhooks
|
243
|
+
response = MijDiscord::Core::API::Server.webhooks(@bot.auth, @id)
|
244
|
+
JSON.parse(response).map {|x| Webhook.new(x, @bot) }
|
245
|
+
end
|
246
|
+
|
242
247
|
def prune_count(days)
|
243
248
|
raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
|
244
249
|
|
@@ -419,10 +424,20 @@ module MijDiscord::Data
|
|
419
424
|
response = MijDiscord::Core::API::Server.search_messages(@bot.auth, @id, options)
|
420
425
|
SearchResults.new(JSON.parse(response), @bot)
|
421
426
|
end
|
427
|
+
|
428
|
+
def inspect
|
429
|
+
MijDiscord.make_inspect(self,
|
430
|
+
:id, :name, :owner, :member_count, :features, :embed_enabled, :verification_level,
|
431
|
+
:content_filter_level, :default_notifications, :afk_timeout, :afk_channel)
|
432
|
+
end
|
422
433
|
end
|
423
434
|
|
424
435
|
class SearchResults
|
425
|
-
ResultData = Struct.new(:result, :context)
|
436
|
+
ResultData = Struct.new(:result, :context) do
|
437
|
+
def inspect
|
438
|
+
MijDiscord.make_inspect(self, :result, :context)
|
439
|
+
end
|
440
|
+
end
|
426
441
|
|
427
442
|
attr_reader :total_count
|
428
443
|
|
@@ -437,5 +452,9 @@ module MijDiscord::Data
|
|
437
452
|
ResultData.new(result, context)
|
438
453
|
end
|
439
454
|
end
|
455
|
+
|
456
|
+
def inspect
|
457
|
+
MijDiscord.make_inspect(self, :total_count, :messages)
|
458
|
+
end
|
440
459
|
end
|
441
460
|
end
|
@@ -41,6 +41,7 @@ module MijDiscord::Data
|
|
41
41
|
@url = data['url']
|
42
42
|
@details = data['details']
|
43
43
|
@state = data['state']
|
44
|
+
@application = data['application_id']
|
44
45
|
|
45
46
|
if (start_time = data.dig('timestamps', 'start'))
|
46
47
|
@start_time = Time.at(start_time).utc
|
@@ -72,32 +73,40 @@ module MijDiscord::Data
|
|
72
73
|
url: @url,
|
73
74
|
details: @details,
|
74
75
|
state: @state,
|
76
|
+
application: @application,
|
75
77
|
})
|
76
78
|
end
|
77
79
|
|
80
|
+
def inspect
|
81
|
+
MijDiscord.make_inspect(self,
|
82
|
+
:type, :name, :url, :details, :state, :start_time, :end_time,
|
83
|
+
:application, :large_image, :large_text, :small_image, :small_text)
|
84
|
+
end
|
85
|
+
|
78
86
|
def self.construct(data)
|
79
87
|
data = {name: data} if data.is_a?(String)
|
80
88
|
|
81
89
|
times = {
|
82
|
-
start: data
|
83
|
-
end: data
|
90
|
+
start: data.try_keys(:start_time, 'start_time')&.to_i,
|
91
|
+
end: data.try_keys(:end_time, 'end_time')&.to_i,
|
84
92
|
}.delete_if {|_,v| v.nil? }
|
85
93
|
|
86
94
|
assets = {
|
87
|
-
large_image: data
|
88
|
-
large_text: data
|
89
|
-
small_image: data
|
90
|
-
small_text: data
|
95
|
+
large_image: data.try_keys(:large_image, 'large_image'),
|
96
|
+
large_text: data.try_keys(:large_text, 'large_text'),
|
97
|
+
small_image: data.try_keys(:small_image, 'small_image'),
|
98
|
+
small_text: data.try_keys(:small_text, 'small_text'),
|
91
99
|
}.delete_if {|_,v| v.nil? }
|
92
100
|
|
93
|
-
type = PLAYING_TYPE.index(data
|
101
|
+
type = PLAYING_TYPE.index(data.try_keys(:type, 'type'))
|
94
102
|
|
95
103
|
game = {
|
96
104
|
type: type || 0,
|
97
|
-
name: data
|
98
|
-
url: data
|
99
|
-
details: data
|
100
|
-
state: data
|
105
|
+
name: data.try_keys(:name, 'name'),
|
106
|
+
url: data.try_keys(:url, 'url'),
|
107
|
+
details: data.try_keys(:details, 'details'),
|
108
|
+
state: data.try_keys(:state, 'state'),
|
109
|
+
application_id: data.try_keys(:application, 'application'),
|
101
110
|
|
102
111
|
timestamps: times.empty? ? nil : times,
|
103
112
|
assets: assets.empty? ? nil : assets,
|
@@ -233,6 +242,27 @@ module MijDiscord::Data
|
|
233
242
|
end
|
234
243
|
|
235
244
|
alias_method :avatar, :avatar_url
|
245
|
+
|
246
|
+
def inspect
|
247
|
+
MijDiscord.make_inspect(self,
|
248
|
+
:id, :username, :discriminator, :avatar_id, :bot_account)
|
249
|
+
end
|
250
|
+
|
251
|
+
class << self
|
252
|
+
def process_avatar(data, format = :png, empty = false)
|
253
|
+
if data.is_a?(String)
|
254
|
+
"data:image/#{format};base64,#{data}"
|
255
|
+
elsif data.respond_to?(:read)
|
256
|
+
data.binmode if data.respond_to?(:binmode)
|
257
|
+
data = Base64.strict_encode64(data.read)
|
258
|
+
"data:image/#{format};base64,#{data}"
|
259
|
+
elsif empty && %i[none empty].include?(data)
|
260
|
+
nil
|
261
|
+
else
|
262
|
+
raise ArgumentError, 'Invalid avatar data provided'
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
236
266
|
end
|
237
267
|
|
238
268
|
class Profile < User
|
@@ -256,17 +286,8 @@ module MijDiscord::Data
|
|
256
286
|
alias_method :name=, :set_username
|
257
287
|
|
258
288
|
def set_avatar(data, format = :png)
|
259
|
-
|
260
|
-
|
261
|
-
elsif data.respond_to?(:read)
|
262
|
-
data.binmode if data.respond_to?(:binmode)
|
263
|
-
data = Base64.strict_encode64(data.read)
|
264
|
-
data = "data:image/#{format};base64,#{data}"
|
265
|
-
else
|
266
|
-
raise ArgumentError, 'Invalid avatar data provided'
|
267
|
-
end
|
268
|
-
|
269
|
-
response = MijDiscord::Core::API::User.update_profile(@bot.auth, @username, data)
|
289
|
+
data = User.process_avatar(data, format, false)
|
290
|
+
response = MijDiscord::Core::API::User.update_profile(@bot.auth, nil, data)
|
270
291
|
update_data(JSON.parse(response))
|
271
292
|
nil
|
272
293
|
end
|
@@ -31,6 +31,11 @@ module MijDiscord::Data
|
|
31
31
|
@self_mute = data.fetch('self_mute', @self_mute)
|
32
32
|
@self_deaf = data.fetch('self_deaf', @self_deaf)
|
33
33
|
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
MijDiscord.make_inspect(self,
|
37
|
+
:user, :mute, :deaf, :self_mute, :self_deaf, :voice_channel)
|
38
|
+
end
|
34
39
|
end
|
35
40
|
|
36
41
|
class VoiceRegion
|
@@ -64,5 +69,11 @@ module MijDiscord::Data
|
|
64
69
|
@deprecated = data['deprecated']
|
65
70
|
@custom = data['custom']
|
66
71
|
end
|
72
|
+
|
73
|
+
def inspect
|
74
|
+
MijDiscord.make_inspect(self,
|
75
|
+
:id, :name, :vip, :optimal, :deprecated, :custom,
|
76
|
+
:sample_hostname, :sample_port)
|
77
|
+
end
|
67
78
|
end
|
68
79
|
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MijDiscord::Data
|
4
|
+
class Webhook
|
5
|
+
include IDObject
|
6
|
+
|
7
|
+
attr_reader :bot
|
8
|
+
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
attr_reader :channel
|
12
|
+
|
13
|
+
attr_reader :token
|
14
|
+
|
15
|
+
attr_reader :avatar_id
|
16
|
+
|
17
|
+
attr_reader :owner
|
18
|
+
|
19
|
+
def initialize(data, bot)
|
20
|
+
@bot = bot
|
21
|
+
|
22
|
+
@id = data['id'].to_id
|
23
|
+
@token = data['token']
|
24
|
+
update_data(data)
|
25
|
+
|
26
|
+
if (user = data['user'])
|
27
|
+
unless (@owner = server.member(user['id']))
|
28
|
+
@owner = @bot.cache.put_user(user)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_data(data)
|
34
|
+
@name = data['name']
|
35
|
+
@channel = @bot.channel(data['channel_id'])
|
36
|
+
@avatar_id = data['avatar']
|
37
|
+
end
|
38
|
+
|
39
|
+
def via_token?
|
40
|
+
@owner.nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
def server
|
44
|
+
@channel.server
|
45
|
+
end
|
46
|
+
|
47
|
+
def avatar_url(format = nil)
|
48
|
+
return MijDiscord::Core::API::User.default_avatar(0) unless @avatar_id
|
49
|
+
MijDiscord::Core::API::User.avatar_url(@id, @avatar_id, format)
|
50
|
+
end
|
51
|
+
|
52
|
+
alias_method :avatar, :avatar_url
|
53
|
+
|
54
|
+
def set_options(reason = nil, name: nil, channel: nil, avatar: nil, format: :png)
|
55
|
+
data = {name: name, channel_id: channel&.to_id}
|
56
|
+
data[:avatar] = User.process_avatar(avatar, format, true) unless avatar.nil?
|
57
|
+
update_webhook(reason, **data.delete_if {|_,v| v.nil? })
|
58
|
+
end
|
59
|
+
|
60
|
+
def set_name(name, reason = nil)
|
61
|
+
update_webhook(reason, name: name)
|
62
|
+
end
|
63
|
+
|
64
|
+
alias_method :name=, :set_name
|
65
|
+
|
66
|
+
def set_channel(channel, reason = nil)
|
67
|
+
update_webhook(reason, channel_id: channel.to_id)
|
68
|
+
end
|
69
|
+
|
70
|
+
alias_method :channel=, :set_channel
|
71
|
+
|
72
|
+
def set_avatar(data, format = :png, reason = nil)
|
73
|
+
data = User.process_avatar(data, format, true)
|
74
|
+
update_webhook(reason, avatar: data)
|
75
|
+
end
|
76
|
+
|
77
|
+
alias_method :avatar=, :set_avatar
|
78
|
+
|
79
|
+
def delete(reason = nil)
|
80
|
+
if via_token?
|
81
|
+
MijDiscord::Core::API::Webhook.token_delete_webhook(@token, @id, reason)
|
82
|
+
else
|
83
|
+
MijDiscord::Core::API::Webhook.delete_webhook(@bot.auth, @id, reason)
|
84
|
+
end
|
85
|
+
|
86
|
+
nil
|
87
|
+
end
|
88
|
+
|
89
|
+
def execute(text: '', name: nil, avatar: nil, tts: false, embeds: [], file: nil, wait: true)
|
90
|
+
raise 'Not yet implemented' unless file.nil? # TODO: Implement
|
91
|
+
|
92
|
+
params = {
|
93
|
+
content: text,
|
94
|
+
username: name,
|
95
|
+
avatar_url: avatar,
|
96
|
+
tts: tts,
|
97
|
+
embeds: embeds.map(&:to_hash),
|
98
|
+
}.delete_if {|_,v| v.nil? }
|
99
|
+
|
100
|
+
response = MijDiscord::Core::API::Webhook.execute_json(@token, @id, params, wait)
|
101
|
+
wait ? Message.new(JSON.parse(response), @bot) : nil
|
102
|
+
end
|
103
|
+
|
104
|
+
def inspect
|
105
|
+
MijDiscord.make_inspect(self, :id, :name, :channel, :owner)
|
106
|
+
end
|
107
|
+
|
108
|
+
private
|
109
|
+
|
110
|
+
def update_webhook(reason, **data)
|
111
|
+
response = if via_token?
|
112
|
+
MijDiscord::Core::API::Webhook.token_update_webhook(@token, @id, data, reason)
|
113
|
+
else
|
114
|
+
MijDiscord::Core::API::Webhook.update_webhook(@bot.auth, @id, data, reason)
|
115
|
+
end
|
116
|
+
|
117
|
+
update_data(JSON.parse(response))
|
118
|
+
nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module MijDiscord::Errors
|
4
|
+
class DiscordError < RuntimeError
|
5
|
+
attr_reader :code
|
6
|
+
|
7
|
+
attr_reader :response
|
8
|
+
|
9
|
+
def initialize(code, message, response)
|
10
|
+
super(message || "(Error #{code})")
|
11
|
+
|
12
|
+
@code, @response = code, response
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class MessageTooLong < DiscordError
|
17
|
+
MATCH_PATTERNS = [['2000'], ['long', 'length', 'size'], ['fewer', 'maximum']]
|
18
|
+
|
19
|
+
# This is shitcode
|
20
|
+
def self.match_pattern?(error)
|
21
|
+
return false if error.nil?
|
22
|
+
MATCH_PATTERNS.reduce(true) {|a,x| a && x.reduce(false) {|b,y| b || error.include?(y) } }
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(message, response)
|
26
|
+
super(nil, message, response)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Unauthorized < DiscordError; end
|
31
|
+
|
32
|
+
class Forbidden < DiscordError; end
|
33
|
+
|
34
|
+
class BadRequest < DiscordError; end
|
35
|
+
|
36
|
+
class NotFound < DiscordError; end
|
37
|
+
|
38
|
+
HTTP_ERRORS = {
|
39
|
+
400 => BadRequest,
|
40
|
+
401 => Unauthorized,
|
41
|
+
403 => Forbidden,
|
42
|
+
404 => NotFound,
|
43
|
+
}.freeze
|
44
|
+
end
|
data/lib/mij-discord/events.rb
CHANGED
data/lib/mij-discord/logger.rb
CHANGED
@@ -17,4 +17,13 @@ module MijDiscord
|
|
17
17
|
|
18
18
|
"[#{sev}] [#{time}] #{prg.upcase}: #{text}\n"
|
19
19
|
end
|
20
|
+
|
21
|
+
def self.make_inspect(obj, *vars)
|
22
|
+
data = [obj.class.to_s.split('::').last]
|
23
|
+
data += vars.map do |x|
|
24
|
+
value = obj.instance_variable_get(:"@#{x}")
|
25
|
+
"#{x}=#{value.inspect}"
|
26
|
+
end
|
27
|
+
%(#<#{data.join(' ')}>)
|
28
|
+
end
|
20
29
|
end
|