mij-discord 1.0.9 → 1.0.10

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.
@@ -1,176 +1,174 @@
1
- # frozen_string_literal: true
2
-
3
- module MijDiscord::Data
4
- class Member < DelegateClass(User)
5
- include PermissionObject
6
-
7
- attr_reader :bot
8
-
9
- attr_reader :joined_at
10
-
11
- attr_reader :nickname
12
- alias_method :nick, :nickname
13
-
14
- attr_reader :roles
15
-
16
- attr_reader :server
17
-
18
- def mute?
19
- voice_state_attribute(:mute)
20
- end
21
-
22
- def deaf?
23
- voice_state_attribute(:deaf)
24
- end
25
-
26
- def self_mute?
27
- voice_state_attribute(:self_mute)
28
- end
29
-
30
- def self_deaf?
31
- voice_state_attribute(:self_deaf)
32
- end
33
-
34
- def voice_channel
35
- voice_state_attribute(:voice_channel)
36
- end
37
-
38
- def initialize(data, server, bot)
39
- @bot = bot
40
-
41
- @user = @bot.cache.put_user(data['user'])
42
- super @user
43
-
44
- raise ArgumentError, 'Cannot create member with no server' unless server || data['guild_id']
45
- @server = server || @bot.servers(data['guild_id'])
46
-
47
- @joined_at = Time.parse(data['joined_at']).utc if data['joined_at']
48
-
49
- update_data(data)
50
- end
51
-
52
- def update_data(data)
53
- @user.update_data(data['user'])
54
-
55
- @nickname = data.fetch('nick', @nickname || '')
56
-
57
- if (roles = data['roles'])
58
- @roles = roles.map {|x| @server.role(x) }
59
- end
60
- end
61
-
62
- def member?
63
- true
64
- end
65
-
66
- def owner?
67
- @server.owner == self
68
- end
69
-
70
- def role?(role)
71
- role = role.to_id
72
- @roles.any? {|x| x.id == role }
73
- end
74
-
75
- def set_roles(roles, reason = nil)
76
- roles = roles.map(&:to_id)
77
- MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, roles: roles)
78
- end
79
-
80
- def modify_roles(add, remove, reason = nil)
81
- add, remove = add.map(&:to_id), remove.map(&:to_id)
82
- roles = (@roles.map(&:id) - remove + add).uniq
83
- MijDiscord::Core::API::Server.update_member(@bot.tolen, @server.id, @user.id, reason, roles: roles)
84
- end
85
-
86
- def add_role(role, reason = nil)
87
- if role.is_a?(Array)
88
- modify_roles(role, [], reason)
89
- else
90
- role = role.to_id
91
- MijDiscord::Core::API::Server.add_member_role(@bot.auth, @server.id, @user.id, role, reason)
92
- end
93
- end
94
-
95
- def remove_role(role, reason = nil)
96
- if role.is_a?(Array)
97
- modify_roles([], role, reason)
98
- else
99
- role = role.to_id
100
- MijDiscord::Core::API::Server.remove_member_role(@bot.auth, @server.id, @user.id, role, reason)
101
- end
102
- end
103
-
104
- def highest_role
105
- @roles.sort_by(&:position).last
106
- end
107
-
108
- def hoist_role
109
- roles = @roles.select(&:hoist)
110
- roles.sort_by(&:position).last
111
- end
112
-
113
- def color_role
114
- roles = @roles.select {|x| x.color.to_i.nonzero? }
115
- roles.sort_by(&:position).last
116
- end
117
-
118
- def color
119
- color_role&.color
120
- end
121
-
122
- def set_nickname(nick, reason = nil)
123
- nick ||= ''
124
-
125
- if @user.current_bot?
126
- MijDiscord::Core::API::User.change_own_nickname(@bot.auth, @server.id, nick, reason)
127
- else
128
- MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, nick: nick)
129
- end
130
- end
131
-
132
- alias_method :nickname=, :set_nickname
133
-
134
- def display_name
135
- nickname.empty? ? username : nickname
136
- end
137
-
138
- def inspect
139
- MijDiscord.make_inspect(self,
140
- :id, :username, :discriminator, :avatar_id, :bot_account, :joined_at, :nickname, :roles)
141
- end
142
-
143
- private
144
-
145
- def voice_state_attribute(key)
146
- @server.voice_states[@user.id]&.send(key)
147
- end
148
- end
149
-
150
- class Recipient < DelegateClass(User)
151
- attr_reader :joined_at
152
-
153
- attr_reader :nickname
154
- alias_method :nick, :nickname
155
-
156
- attr_reader :roles
157
-
158
- attr_reader :server
159
-
160
- def initialize(user, channel, bot)
161
- @bot, @channel, @user = bot, channel, user
162
- raise ArgumentError, 'Recipient for public channel' unless channel.private?
163
-
164
- super @user
165
-
166
- @mute = @deaf = @self_mute = @self_deaf = false
167
- @voice_channel, @server, @roles = nil, nil, []
168
- @nickname, @joined_at = '', @channel.creation_time
169
- end
170
-
171
- def inspect
172
- MijDiscord.make_inspect(self,
173
- :id, :username, :discriminator, :avatar_id, :bot_account, :joined_at)
174
- end
175
- end
1
+ # frozen_string_literal: true
2
+
3
+ module MijDiscord::Data
4
+ class Member < DelegateClass(User)
5
+ include PermissionObject
6
+
7
+ attr_reader :bot
8
+
9
+ attr_reader :joined_at
10
+
11
+ attr_reader :nickname
12
+ alias_method :nick, :nickname
13
+
14
+ attr_reader :roles
15
+
16
+ attr_reader :server
17
+
18
+ def mute?
19
+ voice_state_attribute(:mute)
20
+ end
21
+
22
+ def deaf?
23
+ voice_state_attribute(:deaf)
24
+ end
25
+
26
+ def self_mute?
27
+ voice_state_attribute(:self_mute)
28
+ end
29
+
30
+ def self_deaf?
31
+ voice_state_attribute(:self_deaf)
32
+ end
33
+
34
+ def voice_channel
35
+ voice_state_attribute(:voice_channel)
36
+ end
37
+
38
+ def initialize(data, server, bot)
39
+ @bot = bot
40
+
41
+ @user = @bot.cache.put_user(data['user'])
42
+ super @user
43
+
44
+ raise ArgumentError, 'Cannot create member with no server' unless server || data['guild_id']
45
+ @server = server || @bot.servers(data['guild_id'])
46
+
47
+ @joined_at = Time.parse(data['joined_at']).utc if data['joined_at']
48
+
49
+ update_data(data)
50
+ end
51
+
52
+ def update_data(data)
53
+ @user.update_data(data['user'])
54
+
55
+ @nickname = data.fetch('nick', @nickname || '')
56
+
57
+ if (roles = data['roles'])
58
+ @roles = roles.map {|x| @server.role(x) }
59
+ end
60
+ end
61
+
62
+ def member?
63
+ true
64
+ end
65
+
66
+ def owner?
67
+ @server.owner == self
68
+ end
69
+
70
+ def role?(role)
71
+ role = role.to_id
72
+ @roles.any? {|x| x.id == role }
73
+ end
74
+
75
+ def set_roles(roles, reason = nil)
76
+ roles = roles.map(&:to_id)
77
+ MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, roles: roles)
78
+ end
79
+
80
+ def modify_roles(add, remove, reason = nil)
81
+ add, remove = add.map(&:to_id), remove.map(&:to_id)
82
+ roles = (@roles.map(&:id) - remove + add).uniq
83
+ MijDiscord::Core::API::Server.update_member(@bot.tolen, @server.id, @user.id, reason, roles: roles)
84
+ end
85
+
86
+ def add_role(role, reason = nil)
87
+ if role.is_a?(Array)
88
+ modify_roles(role, [], reason)
89
+ else
90
+ role = role.to_id
91
+ MijDiscord::Core::API::Server.add_member_role(@bot.auth, @server.id, @user.id, role, reason)
92
+ end
93
+ end
94
+
95
+ def remove_role(role, reason = nil)
96
+ if role.is_a?(Array)
97
+ modify_roles([], role, reason)
98
+ else
99
+ role = role.to_id
100
+ MijDiscord::Core::API::Server.remove_member_role(@bot.auth, @server.id, @user.id, role, reason)
101
+ end
102
+ end
103
+
104
+ def highest_role
105
+ @roles.sort_by(&:position).last
106
+ end
107
+
108
+ def hoist_role
109
+ roles = @roles.select(&:hoist)
110
+ roles.sort_by(&:position).last
111
+ end
112
+
113
+ def color_role
114
+ roles = @roles.select {|x| x.color.to_i.nonzero? }
115
+ roles.sort_by(&:position).last
116
+ end
117
+
118
+ def color
119
+ color_role&.color
120
+ end
121
+
122
+ def set_nickname(nick, reason = nil)
123
+ nick ||= ''
124
+
125
+ if @user.current_bot?
126
+ MijDiscord::Core::API::User.change_own_nickname(@bot.auth, @server.id, nick, reason)
127
+ else
128
+ MijDiscord::Core::API::Server.update_member(@bot.auth, @server.id, @user.id, reason, nick: nick)
129
+ end
130
+ end
131
+
132
+ alias_method :nickname=, :set_nickname
133
+
134
+ def display_name
135
+ nickname.empty? ? username : nickname
136
+ end
137
+
138
+ def inspect
139
+ MijDiscord.make_inspect(self, :user, :joined_at, :nickname, :roles)
140
+ end
141
+
142
+ private
143
+
144
+ def voice_state_attribute(key)
145
+ @server.voice_states[@user.id]&.send(key)
146
+ end
147
+ end
148
+
149
+ class Recipient < DelegateClass(User)
150
+ attr_reader :joined_at
151
+
152
+ attr_reader :nickname
153
+ alias_method :nick, :nickname
154
+
155
+ attr_reader :roles
156
+
157
+ attr_reader :server
158
+
159
+ def initialize(user, channel, bot)
160
+ @bot, @channel, @user = bot, channel, user
161
+ raise ArgumentError, 'Recipient for public channel' unless channel.private?
162
+
163
+ super @user
164
+
165
+ @mute = @deaf = @self_mute = @self_deaf = false
166
+ @voice_channel, @server, @roles = nil, nil, []
167
+ @nickname, @joined_at = '', @channel.creation_time
168
+ end
169
+
170
+ def inspect
171
+ MijDiscord.make_inspect(self, :user, :joined_at)
172
+ end
173
+ end
176
174
  end
@@ -1,468 +1,405 @@
1
- # frozen_string_literal: true
2
-
3
- module MijDiscord::Data
4
- class Server
5
- VERIFICATION_LEVEL = {
6
- 0 => :none,
7
- 1 => :low,
8
- 2 => :medium,
9
- 3 => :high,
10
- 4 => :very_high,
11
- }.freeze
12
-
13
- CONTENT_FILTER_LEVEL = {
14
- 0 => :none,
15
- 1 => :no_roles,
16
- 2 => :all,
17
- }.freeze
18
-
19
- DEFAULT_NOTIFICATIONS = {
20
- 0 => :all,
21
- 1 => :mentions,
22
- }.freeze
23
-
24
- CHANNEL_TYPES = {
25
- :text => 0,
26
- :voice => 2,
27
- :category => 4,
28
- }.freeze
29
-
30
- include IDObject
31
-
32
- attr_reader :bot
33
-
34
- attr_reader :name
35
-
36
- attr_reader :icon_id
37
-
38
- attr_reader :owner
39
-
40
- attr_reader :large
41
- alias_method :large?, :large
42
-
43
- attr_reader :features
44
-
45
- attr_reader :embed_enabled
46
- alias_method :embed_enabled?, :embed_enabled
47
- alias_method :has_embed?, :embed_enabled
48
-
49
- attr_reader :member_count
50
-
51
- attr_reader :verification_level
52
-
53
- attr_reader :content_filter_level
54
- alias_method :content_filter, :content_filter_level
55
-
56
- attr_reader :default_notifications
57
-
58
- attr_reader :afk_timeout
59
-
60
- attr_reader :afk_channel
61
-
62
- attr_reader :cache
63
-
64
- def initialize(data, bot, invalid = false)
65
- @bot = bot
66
-
67
- @id = data['id'].to_i
68
- @large = data['large']
69
- @member_count = data['member_count']
70
- @members_chunked = 0
71
-
72
- @cache = MijDiscord::Cache::ServerCache.new(self, @bot)
73
-
74
- data['channels']&.each {|ch| @cache.put_channel(ch) }
75
-
76
- data['roles']&.each {|ro| @cache.put_role(ro) }
77
-
78
- update_synced_data(data)
79
-
80
- @voice_states = {}
81
- data['voice_states']&.each {|vs| update_voice_state(vs) }
82
-
83
- update_emojis(data)
84
- update_data(data)
85
-
86
- @owner = member(data['owner_id'])
87
- end
88
-
89
- def update_data(data)
90
- @name = data.fetch('name', @name)
91
- @region_id = data.fetch('region', @region_id)
92
- @icon_id = data.fetch('icon', @icon_id)
93
- @afk_timeout = data.fetch('afk_timeout', @afk_timeout)
94
- @embed_enabled = data.fetch('embed_enabled', @embed_enabled)
95
- @verification_level = VERIFICATION_LEVEL.fetch(data['verification_level'], @verification_level)
96
- @content_filter_level = CONTENT_FILTER_LEVEL.fetch(data['explicit_content_filter'], @content_filter_level)
97
- @default_notifications = DEFAULT_NOTIFICATIONS.fetch(data['default_message_notifications'], @default_notifications)
98
-
99
- begin
100
- if data.has_key?('afk_channel_id')
101
- id = data['afk_channel_id'].to_i
102
- @afk_channel = @bot.channel(id, self)
103
- end
104
- rescue MijDiscord::Errors::Forbidden
105
- @afk_channel = nil
106
- end
107
- end
108
-
109
- def update_emojis(data)
110
- @emojis = {}
111
- data['emojis'].each do |em|
112
- emoji = MijDiscord::Data::Emoji.new(em, self)
113
- @emojis[emoji.id] = emoji
114
- end
115
- end
116
-
117
- def update_voice_state(data)
118
- user = @cache.get_member(data['user_id'])
119
-
120
- if (chan_id = data['channel_id']&.to_i)
121
- state = (@voice_states[user.id] ||= VoiceState.new(user))
122
- channel = @cache.get_channel(chan_id)
123
-
124
- state.update_data(channel, data) if channel
125
- state
126
- else
127
- state = @voice_states.delete(user.id)
128
- state ||= VoiceState.new(user)
129
-
130
- state.update_data(nil, data)
131
- state
132
- end
133
- end
134
-
135
- def update_members_chunk(data)
136
- return if @members_chunked.nil?
137
-
138
- @members_chunked += data.length
139
- data.each {|mb| @cache.put_member(mb) }
140
-
141
- @members_chunked = nil if @members_chunked == @member_count
142
- end
143
-
144
- def update_synced_data(data)
145
- data['members']&.each {|mb| @cache.put_member(mb, update: true) }
146
-
147
- data['presences']&.each do |pr|
148
- next unless pr['user']
149
-
150
- user_id = pr['user']['id'].to_i
151
- user = @cache.get_member(user_id, local: true)
152
- user.update_presence(pr) if user
153
- end
154
- end
155
-
156
- def update_member(data, mode)
157
- case mode
158
- when :add
159
- @member_count += 1
160
- @cache.put_member(data)
161
- when :remove
162
- @member_count -= 1
163
- key = data['user']['id']
164
- @cache.remove_member(key)
165
- when :update
166
- @cache.put_member(data, update: true)
167
- end
168
- end
169
-
170
- def channels
171
- @cache.list_channels
172
- end
173
-
174
- def channel(id)
175
- @cache.get_channel(id)
176
- end
177
-
178
- def roles
179
- @cache.list_roles
180
- end
181
-
182
- def role(id)
183
- @cache.get_role(id)
184
- end
185
-
186
- def members
187
- unless @members_chunked.nil?
188
- @bot.gateway.send_request_members(@id, '', 0)
189
- sleep(0.05) while @members_chunked
190
- end
191
-
192
- @cache.list_members
193
- end
194
-
195
- def member(id)
196
- @cache.get_member(id)
197
- end
198
-
199
- def emojis
200
- @emojis.values
201
- end
202
-
203
- def emoji(id)
204
- @emojis[id&.to_id]
205
- end
206
-
207
- def everyone_role
208
- role(@id)
209
- end
210
-
211
- def voice_states
212
- @voice_states.values
213
- end
214
-
215
- def voice_state(id)
216
- @voice_states[id&.to_id]
217
- end
218
-
219
- def default_channel(can_send = false)
220
- text_channels.sort_by {|ch| [ch.position, ch.id] }.find do |ch|
221
- if (overwrite = ch.permission_overwrites[id])
222
- if can_send
223
- overwrite.allow.send_messages? || !overwrite.deny.send_messages?
224
- else
225
- overwrite.allow.read_messages? || !overwrite.deny.read_messages?
226
- end
227
- else
228
- if can_send
229
- everyone_role.permissions.send_messages
230
- else
231
- everyone_role.permissions.read_messages
232
- end
233
- end
234
- end
235
- end
236
-
237
- alias_method :general_channel, :default_channel
238
-
239
- def online_members(idle: true, bots: false)
240
- members.select! do |m|
241
- ((idle ? m.idle? : false) || m.online?) && (bots ? true : !m.bot_account?)
242
- end
243
- end
244
-
245
- def invites
246
- response = MijDiscord::Core::API::Server.invites(@bot.auth, @id)
247
- JSON.parse(response).map {|x| Invite.new(x, @bot) }
248
- end
249
-
250
- def webhooks
251
- response = MijDiscord::Core::API::Server.webhooks(@bot.auth, @id)
252
- JSON.parse(response).map {|x| Webhook.new(x, @bot) }
253
- end
254
-
255
- def prune_count(days)
256
- raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
257
-
258
- response = MijDiscord::Core::API::Server.prune_count(@bot.auth, @id, days)
259
- JSON.parse(response)['pruned']
260
- end
261
-
262
- def prune(days, reason = nil)
263
- raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
264
-
265
- response = MijDiscord::Core::API::Server.begin_prune(@bot.auth, @id, days, reason)
266
- JSON.parse(response)['pruned']
267
- end
268
-
269
- def text_channels
270
- channels.select!(&:text?)
271
- end
272
-
273
- def voice_channels
274
- channels.select!(&:voice?)
275
- end
276
-
277
- def create_channel(name, reason = nil, type: :text, bitrate: nil, user_limit: nil, permissions: [], nsfw: false)
278
- raise ArgumentError, 'Invalid channel type specified' unless CHANNEL_TYPES.has_key?(type)
279
-
280
- permissions = permissions.map {|x| x.is_a(Overwrite) ? x.to_hash : x }
281
- response = MijDiscord::Core::API::Server.create_channel(@bot.auth, @id,
282
- name, CHANNEL_TYPES[type], bitrate, user_limit, permissions, nsfw, reason)
283
- @cache.put_channel(JSON.parse(response))
284
- end
285
-
286
- def create_role(name, reason = nil, color: 0, hoist: false, mentionable: false, permissions: 104_324_161)
287
- response = MijDiscord::Core::API::Server.create_role(@bot.auth, @id,
288
- name, color.to_i, hoist, mentionable, permissions.to_i, reason)
289
- @cache.put_role(JSON.parse(response))
290
- end
291
-
292
- def bans
293
- response = MijDiscord::Core::API::Server.bans(@bot.auth, @id)
294
- JSON.parse(response).map {|x| @bot.cache.put_user(x['user']) }
295
- end
296
-
297
- def ban(user, message_days = 0, reason = nil)
298
- MijDiscord::Core::API::Server.ban_user(@bot.auth, @id, user.to_id, message_days, reason)
299
- nil
300
- end
301
-
302
- def unban(user, reason = nil)
303
- MijDiscord::Core::API::Server.unban_user(@bot.auth, @id, user.to_id, reason)
304
- nil
305
- end
306
-
307
- def kick(user, reason = nil)
308
- MijDiscord::Core::API::Server.remove_member(@bot.auth, @id, user.to_id, reason)
309
- nil
310
- end
311
-
312
- def leave
313
- MijDiscord::Core::API::User.leave_server(@bot.auth, @id)
314
- nil
315
- end
316
-
317
- def delete
318
- MijDiscord::Core::API::Server.delete(@bot.auth, @id)
319
- nil
320
- end
321
-
322
- def set_owner(user, reason = nil)
323
- MijDiscord::Core::API::Server.transfer_ownership(@bot.auth, @id, user.to_id, reason)
324
- end
325
-
326
- alias_method :owner=, :set_owner
327
-
328
- def set_options(reason = nil, name: nil, region: nil, icon: nil, afk_channel: nil, afk_timeout: nil)
329
- response = MijDiscord::Core::API::Server.update(@bot.auth, @id,
330
- name, region, icon, afk_channel&.to_id, afk_timeout, reason)
331
- @bot.cache.put_server(JSON.parse(response), update: true)
332
- end
333
-
334
- def set_name(name, reason = nil)
335
- set_options(reason, name: name)
336
- nil
337
- end
338
-
339
- alias_method :name=, :set_name
340
-
341
- def available_regions
342
- return @voice_regions if @voice_regions
343
-
344
- response = MijDiscord::Core::API::Server.regions(@bot.auth, @id)
345
- @voice_regions = JSON.parse(response).map {|x| VoiceRegion.new(x) }
346
- end
347
-
348
- def region
349
- available_regions.find {|x| x.id == @region_id }
350
- end
351
-
352
- def set_region(region, reason = nil)
353
- region = region.to_s
354
- raise ArgumentError, 'Invalid region' unless available_regions.find {|x| x.id == region }
355
-
356
- set_options(reason, region: region)
357
- nil
358
- end
359
-
360
- alias_method :region=, :set_region
361
-
362
- def set_icon(icon, reason = nil)
363
- if icon.respond_to?(:read)
364
- buffer = Base64.strict_encode64(icon.read)
365
- icon = "data:image/jpg;base64,#{buffer}"
366
- set_options(reason, icon: icon)
367
- else
368
- set_options(reason, icon: icon.to_s)
369
- end
370
- nil
371
- end
372
-
373
- alias_method :icon=, :set_icon
374
-
375
- def set_afk_channel(channel, reason = nil)
376
- set_options(reason, afk_channel: channel.to_id)
377
- nil
378
- end
379
-
380
- alias_method :afk_channel=, :set_afk_channel
381
-
382
- def set_afk_timeout(timeout, reason = nil)
383
- set_options(reason, afk_timeout: timeout)
384
- nil
385
- end
386
-
387
- alias_method :afk_timeout=, :set_afk_timeout
388
-
389
- def icon_url(format = :webp)
390
- return nil unless @icon_id
391
- MijDiscord::Core::API.icon_url(@id, @icon_id, format)
392
- end
393
-
394
- def embed_url(style = :shield)
395
- return nil unless @embed_enabled
396
- MijDiscord::Core::API.widget_url(@id, style)
397
- end
398
-
399
- def search_messages(limit: 25, offset: 0, sort_by: nil, sort_asc: false,
400
- nsfw: true, around: 2, content: nil, author: nil, channel: nil, mentions: nil,
401
- author_is: nil, author_not: nil, has: nil, has_not: nil, before: nil, after: nil)
402
- author = author ? [*author].map(&:to_id) : nil
403
- channel = channel ? [*channel].map(&:to_id) : nil
404
- mentions = mentions ? [*mentions].map(&:to_id) : nil
405
-
406
- has_not = has_not ? [*has_not].map {|x| "-#{x}" } : []
407
- author_not = author_not ? [*author_not].map {|x| "-#{x}" } : []
408
-
409
- has = has_not | (has ? [*has].map(&:to_s) : [])
410
- author_is = author_not | (author_is ? [*author_is].map(&:to_s) : [])
411
-
412
- before = before ? IDObject.synthesize(before) : nil
413
- after = after ? IDObject.synthesize(after) : nil
414
-
415
- options = {
416
- limit: limit,
417
- offset: offset,
418
- sort_by: sort_by,
419
- sort_order: sort_asc ? 'asc' : 'desc',
420
- context_size: around,
421
- include_nsfw: nsfw,
422
- author_id: author,
423
- author_type: author_is,
424
- channel_id: channel,
425
- mentions: mentions,
426
- max_id: before,
427
- min_id: after,
428
- content: content,
429
- has: has,
430
- }.delete_if {|_,v| v.nil? }
431
-
432
- response = MijDiscord::Core::API::Server.search_messages(@bot.auth, @id, options)
433
- SearchResults.new(JSON.parse(response), @bot)
434
- end
435
-
436
- def inspect
437
- MijDiscord.make_inspect(self,
438
- :id, :name, :owner, :member_count, :features, :embed_enabled, :verification_level,
439
- :content_filter_level, :default_notifications, :afk_timeout, :afk_channel)
440
- end
441
- end
442
-
443
- class SearchResults
444
- ResultData = Struct.new(:result, :context) do
445
- def inspect
446
- MijDiscord.make_inspect(self, :result, :context)
447
- end
448
- end
449
-
450
- attr_reader :total_count
451
-
452
- attr_reader :messages
453
-
454
- def initialize(data, bot)
455
- @total_count = data['total_results']
456
-
457
- @messages = data['messages'].map do |group|
458
- context = group.map {|x| Message.new(x, bot) }
459
- result = context.delete_at(context.length / 2)
460
- ResultData.new(result, context)
461
- end
462
- end
463
-
464
- def inspect
465
- MijDiscord.make_inspect(self, :total_count, :messages)
466
- end
467
- end
1
+ # frozen_string_literal: true
2
+
3
+ module MijDiscord::Data
4
+ class Server
5
+ VERIFICATION_LEVEL = {
6
+ 0 => :none,
7
+ 1 => :low,
8
+ 2 => :medium,
9
+ 3 => :high,
10
+ 4 => :very_high,
11
+ }.freeze
12
+
13
+ CONTENT_FILTER_LEVEL = {
14
+ 0 => :none,
15
+ 1 => :no_roles,
16
+ 2 => :all,
17
+ }.freeze
18
+
19
+ DEFAULT_NOTIFICATIONS = {
20
+ 0 => :all,
21
+ 1 => :mentions,
22
+ }.freeze
23
+
24
+ CHANNEL_TYPES = {
25
+ :text => 0,
26
+ :voice => 2,
27
+ :category => 4,
28
+ }.freeze
29
+
30
+ include IDObject
31
+
32
+ attr_reader :bot
33
+
34
+ attr_reader :name
35
+
36
+ attr_reader :icon_id
37
+
38
+ attr_reader :owner
39
+
40
+ attr_reader :large
41
+ alias_method :large?, :large
42
+
43
+ attr_reader :features
44
+
45
+ attr_reader :embed_enabled
46
+ alias_method :embed_enabled?, :embed_enabled
47
+ alias_method :has_embed?, :embed_enabled
48
+
49
+ attr_reader :member_count
50
+
51
+ attr_reader :verification_level
52
+
53
+ attr_reader :content_filter_level
54
+ alias_method :content_filter, :content_filter_level
55
+
56
+ attr_reader :default_notifications
57
+
58
+ attr_reader :afk_timeout
59
+
60
+ attr_reader :afk_channel
61
+
62
+ attr_reader :cache
63
+
64
+ def initialize(data, bot, invalid = false)
65
+ @bot = bot
66
+
67
+ @id = data['id'].to_i
68
+ @large = data['large']
69
+ @member_count = data['member_count']
70
+ @members_chunked = 0
71
+
72
+ @cache = MijDiscord::Cache::ServerCache.new(self, @bot)
73
+
74
+ data['channels']&.each {|ch| @cache.put_channel(ch) }
75
+
76
+ data['roles']&.each {|ro| @cache.put_role(ro) }
77
+
78
+ update_synced_data(data)
79
+
80
+ @voice_states = {}
81
+ data['voice_states']&.each {|vs| update_voice_state(vs) }
82
+
83
+ update_emojis(data)
84
+ update_data(data)
85
+
86
+ @owner = member(data['owner_id'])
87
+ end
88
+
89
+ def update_data(data)
90
+ @name = data.fetch('name', @name)
91
+ @region_id = data.fetch('region', @region_id)
92
+ @icon_id = data.fetch('icon', @icon_id)
93
+ @afk_timeout = data.fetch('afk_timeout', @afk_timeout)
94
+ @embed_enabled = data.fetch('embed_enabled', @embed_enabled)
95
+ @verification_level = VERIFICATION_LEVEL.fetch(data['verification_level'], @verification_level)
96
+ @content_filter_level = CONTENT_FILTER_LEVEL.fetch(data['explicit_content_filter'], @content_filter_level)
97
+ @default_notifications = DEFAULT_NOTIFICATIONS.fetch(data['default_message_notifications'], @default_notifications)
98
+
99
+ begin
100
+ if data.has_key?('afk_channel_id')
101
+ id = data['afk_channel_id'].to_i
102
+ @afk_channel = @bot.channel(id, self)
103
+ end
104
+ rescue MijDiscord::Errors::Forbidden
105
+ @afk_channel = nil
106
+ end
107
+ end
108
+
109
+ def update_emojis(data)
110
+ @emojis = {}
111
+ data['emojis'].each do |em|
112
+ emoji = MijDiscord::Data::Emoji.new(em, self)
113
+ @emojis[emoji.id] = emoji
114
+ end
115
+ end
116
+
117
+ def update_voice_state(data)
118
+ user = @cache.get_member(data['user_id'])
119
+
120
+ if (chan_id = data['channel_id']&.to_i)
121
+ state = (@voice_states[user.id] ||= VoiceState.new(user))
122
+ channel = @cache.get_channel(chan_id)
123
+
124
+ state.update_data(channel, data) if channel
125
+ state
126
+ else
127
+ state = @voice_states.delete(user.id)
128
+ state ||= VoiceState.new(user)
129
+
130
+ state.update_data(nil, data)
131
+ state
132
+ end
133
+ end
134
+
135
+ def update_members_chunk(data)
136
+ return if @members_chunked.nil?
137
+
138
+ @members_chunked += data.length
139
+ data.each {|mb| @cache.put_member(mb) }
140
+
141
+ @members_chunked = nil if @members_chunked == @member_count
142
+ end
143
+
144
+ def update_synced_data(data)
145
+ data['members']&.each {|mb| @cache.put_member(mb, update: true) }
146
+
147
+ data['presences']&.each do |pr|
148
+ next unless pr['user']
149
+
150
+ user_id = pr['user']['id'].to_i
151
+ user = @cache.get_member(user_id, local: true)
152
+ user.update_presence(pr) if user
153
+ end
154
+ end
155
+
156
+ def update_member(data, mode)
157
+ case mode
158
+ when :add
159
+ @member_count += 1
160
+ @cache.put_member(data)
161
+ when :remove
162
+ @member_count -= 1
163
+ key = data['user']['id']
164
+ @cache.remove_member(key)
165
+ when :update
166
+ @cache.put_member(data, update: true)
167
+ end
168
+ end
169
+
170
+ def channels
171
+ @cache.list_channels
172
+ end
173
+
174
+ def channel(id)
175
+ @cache.get_channel(id)
176
+ end
177
+
178
+ def roles
179
+ @cache.list_roles
180
+ end
181
+
182
+ def role(id)
183
+ @cache.get_role(id)
184
+ end
185
+
186
+ def members
187
+ unless @members_chunked.nil?
188
+ @bot.gateway.send_request_members(@id, '', 0)
189
+ sleep(0.05) while @members_chunked
190
+ end
191
+
192
+ @cache.list_members
193
+ end
194
+
195
+ def member(id)
196
+ @cache.get_member(id)
197
+ end
198
+
199
+ def emojis
200
+ @emojis.values
201
+ end
202
+
203
+ def emoji(id)
204
+ @emojis[id&.to_id]
205
+ end
206
+
207
+ def everyone_role
208
+ role(@id)
209
+ end
210
+
211
+ def voice_states
212
+ @voice_states.values
213
+ end
214
+
215
+ def voice_state(id)
216
+ @voice_states[id&.to_id]
217
+ end
218
+
219
+ def default_channel(can_send = false)
220
+ text_channels.sort_by {|ch| [ch.position, ch.id] }.find do |ch|
221
+ if (overwrite = ch.permission_overwrites[id])
222
+ if can_send
223
+ overwrite.allow.send_messages? || !overwrite.deny.send_messages?
224
+ else
225
+ overwrite.allow.read_messages? || !overwrite.deny.read_messages?
226
+ end
227
+ else
228
+ if can_send
229
+ everyone_role.permissions.send_messages
230
+ else
231
+ everyone_role.permissions.read_messages
232
+ end
233
+ end
234
+ end
235
+ end
236
+
237
+ alias_method :general_channel, :default_channel
238
+
239
+ def online_members(idle: true, bots: false)
240
+ members.select! do |m|
241
+ ((idle ? m.idle? : false) || m.online?) && (bots ? true : !m.bot_account?)
242
+ end
243
+ end
244
+
245
+ def invites
246
+ response = MijDiscord::Core::API::Server.invites(@bot.auth, @id)
247
+ JSON.parse(response).map {|x| Invite.new(x, @bot) }
248
+ end
249
+
250
+ def webhooks
251
+ response = MijDiscord::Core::API::Server.webhooks(@bot.auth, @id)
252
+ JSON.parse(response).map {|x| Webhook.new(x, @bot) }
253
+ end
254
+
255
+ def prune_count(days)
256
+ raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
257
+
258
+ response = MijDiscord::Core::API::Server.prune_count(@bot.auth, @id, days)
259
+ JSON.parse(response)['pruned']
260
+ end
261
+
262
+ def prune(days, reason = nil)
263
+ raise ArgumentError, 'Days must be between 1 and 30' unless days.between?(1, 30)
264
+
265
+ response = MijDiscord::Core::API::Server.begin_prune(@bot.auth, @id, days, reason)
266
+ JSON.parse(response)['pruned']
267
+ end
268
+
269
+ def text_channels
270
+ channels.select!(&:text?)
271
+ end
272
+
273
+ def voice_channels
274
+ channels.select!(&:voice?)
275
+ end
276
+
277
+ def create_channel(name, reason = nil, type: :text, bitrate: nil, user_limit: nil, permissions: [], nsfw: false)
278
+ raise ArgumentError, 'Invalid channel type specified' unless CHANNEL_TYPES.has_key?(type)
279
+
280
+ permissions = permissions.map {|x| x.is_a(Overwrite) ? x.to_hash : x }
281
+ response = MijDiscord::Core::API::Server.create_channel(@bot.auth, @id,
282
+ name, CHANNEL_TYPES[type], bitrate, user_limit, permissions, nsfw, reason)
283
+ @cache.put_channel(JSON.parse(response))
284
+ end
285
+
286
+ def create_role(name, reason = nil, color: 0, hoist: false, mentionable: false, permissions: 104_324_161)
287
+ response = MijDiscord::Core::API::Server.create_role(@bot.auth, @id,
288
+ name, color.to_i, hoist, mentionable, permissions.to_i, reason)
289
+ @cache.put_role(JSON.parse(response))
290
+ end
291
+
292
+ def bans
293
+ response = MijDiscord::Core::API::Server.bans(@bot.auth, @id)
294
+ JSON.parse(response).map {|x| @bot.cache.put_user(x['user']) }
295
+ end
296
+
297
+ def ban(user, message_days = 0, reason = nil)
298
+ MijDiscord::Core::API::Server.ban_user(@bot.auth, @id, user.to_id, message_days, reason)
299
+ nil
300
+ end
301
+
302
+ def unban(user, reason = nil)
303
+ MijDiscord::Core::API::Server.unban_user(@bot.auth, @id, user.to_id, reason)
304
+ nil
305
+ end
306
+
307
+ def kick(user, reason = nil)
308
+ MijDiscord::Core::API::Server.remove_member(@bot.auth, @id, user.to_id, reason)
309
+ nil
310
+ end
311
+
312
+ def leave
313
+ MijDiscord::Core::API::User.leave_server(@bot.auth, @id)
314
+ nil
315
+ end
316
+
317
+ def delete
318
+ MijDiscord::Core::API::Server.delete(@bot.auth, @id)
319
+ nil
320
+ end
321
+
322
+ def set_owner(user, reason = nil)
323
+ MijDiscord::Core::API::Server.transfer_ownership(@bot.auth, @id, user.to_id, reason)
324
+ end
325
+
326
+ alias_method :owner=, :set_owner
327
+
328
+ def set_options(reason = nil, name: nil, region: nil, icon: nil, afk_channel: nil, afk_timeout: nil)
329
+ response = MijDiscord::Core::API::Server.update(@bot.auth, @id,
330
+ name, region, icon, afk_channel&.to_id, afk_timeout, reason)
331
+ @bot.cache.put_server(JSON.parse(response), update: true)
332
+ end
333
+
334
+ def set_name(name, reason = nil)
335
+ set_options(reason, name: name)
336
+ nil
337
+ end
338
+
339
+ alias_method :name=, :set_name
340
+
341
+ def available_regions
342
+ return @voice_regions if @voice_regions
343
+
344
+ response = MijDiscord::Core::API::Server.regions(@bot.auth, @id)
345
+ @voice_regions = JSON.parse(response).map {|x| VoiceRegion.new(x) }
346
+ end
347
+
348
+ def region
349
+ available_regions.find {|x| x.id == @region_id }
350
+ end
351
+
352
+ def set_region(region, reason = nil)
353
+ region = region.to_s
354
+ raise ArgumentError, 'Invalid region' unless available_regions.find {|x| x.id == region }
355
+
356
+ set_options(reason, region: region)
357
+ nil
358
+ end
359
+
360
+ alias_method :region=, :set_region
361
+
362
+ def set_icon(icon, reason = nil)
363
+ if icon.respond_to?(:read)
364
+ buffer = Base64.strict_encode64(icon.read)
365
+ icon = "data:image/jpg;base64,#{buffer}"
366
+ set_options(reason, icon: icon)
367
+ else
368
+ set_options(reason, icon: icon.to_s)
369
+ end
370
+ nil
371
+ end
372
+
373
+ alias_method :icon=, :set_icon
374
+
375
+ def set_afk_channel(channel, reason = nil)
376
+ set_options(reason, afk_channel: channel.to_id)
377
+ nil
378
+ end
379
+
380
+ alias_method :afk_channel=, :set_afk_channel
381
+
382
+ def set_afk_timeout(timeout, reason = nil)
383
+ set_options(reason, afk_timeout: timeout)
384
+ nil
385
+ end
386
+
387
+ alias_method :afk_timeout=, :set_afk_timeout
388
+
389
+ def icon_url(format = :png)
390
+ return nil unless @icon_id
391
+ MijDiscord::Core::API.icon_url(@id, @icon_id, format)
392
+ end
393
+
394
+ def embed_url(style = :shield)
395
+ return nil unless @embed_enabled
396
+ MijDiscord::Core::API.widget_url(@id, style)
397
+ end
398
+
399
+ def inspect
400
+ MijDiscord.make_inspect(self,
401
+ :id, :name, :owner, :member_count, :features, :embed_enabled, :verification_level,
402
+ :content_filter_level, :default_notifications, :afk_timeout, :afk_channel)
403
+ end
404
+ end
468
405
  end