discorb 0.15.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/build_main.yml +2 -2
  4. data/.github/workflows/build_version.yml +1 -1
  5. data/.github/workflows/codeql-analysis.yml +1 -1
  6. data/.github/workflows/lint-push.yml +3 -5
  7. data/.github/workflows/lint.yml +1 -1
  8. data/.github/workflows/spec.yml +30 -0
  9. data/.lefthook/commit-msg/validator.rb +5 -0
  10. data/.rspec +2 -0
  11. data/.rspec_parallel +2 -0
  12. data/.rubocop.yml +49 -8
  13. data/Changelog.md +32 -1
  14. data/Gemfile +14 -8
  15. data/Rakefile +46 -25
  16. data/bin/console +3 -3
  17. data/docs/Examples.md +1 -1
  18. data/docs/application_command.md +138 -46
  19. data/docs/cli/irb.md +2 -2
  20. data/docs/cli/new.md +14 -9
  21. data/docs/cli/run.md +7 -11
  22. data/docs/cli.md +17 -10
  23. data/docs/events.md +257 -193
  24. data/docs/extension.md +1 -2
  25. data/docs/faq.md +0 -1
  26. data/docs/tutorial.md +12 -12
  27. data/docs/voice_events.md +106 -106
  28. data/examples/commands/message.rb +63 -0
  29. data/examples/commands/permission.rb +18 -0
  30. data/examples/commands/slash.rb +44 -0
  31. data/examples/commands/user.rb +51 -0
  32. data/examples/components/authorization_button.rb +2 -2
  33. data/examples/components/select_menu.rb +2 -2
  34. data/examples/extension/main.rb +1 -1
  35. data/examples/extension/message_expander.rb +5 -2
  36. data/examples/simple/eval.rb +2 -2
  37. data/examples/simple/ping_pong.rb +1 -1
  38. data/examples/simple/rolepanel.rb +2 -2
  39. data/examples/simple/shard.rb +17 -0
  40. data/examples/simple/wait_for_message.rb +1 -1
  41. data/exe/discorb +31 -16
  42. data/lefthook.yml +45 -0
  43. data/lib/discorb/allowed_mentions.rb +8 -0
  44. data/lib/discorb/app_command/command.rb +184 -60
  45. data/lib/discorb/app_command/common.rb +25 -0
  46. data/lib/discorb/app_command/handler.rb +116 -34
  47. data/lib/discorb/app_command.rb +2 -1
  48. data/lib/discorb/application.rb +17 -7
  49. data/lib/discorb/asset.rb +10 -2
  50. data/lib/discorb/attachment.rb +17 -2
  51. data/lib/discorb/audit_logs.rb +53 -12
  52. data/lib/discorb/channel/base.rb +108 -0
  53. data/lib/discorb/channel/category.rb +32 -0
  54. data/lib/discorb/channel/container.rb +44 -0
  55. data/lib/discorb/channel/dm.rb +28 -0
  56. data/lib/discorb/channel/guild.rb +245 -0
  57. data/lib/discorb/channel/stage.rb +140 -0
  58. data/lib/discorb/channel/text.rb +345 -0
  59. data/lib/discorb/channel/thread.rb +321 -0
  60. data/lib/discorb/channel/voice.rb +79 -0
  61. data/lib/discorb/channel.rb +2 -1126
  62. data/lib/discorb/client.rb +160 -64
  63. data/lib/discorb/common.rb +18 -3
  64. data/lib/discorb/components/button.rb +7 -7
  65. data/lib/discorb/components/select_menu.rb +6 -18
  66. data/lib/discorb/components/text_input.rb +12 -2
  67. data/lib/discorb/components.rb +1 -1
  68. data/lib/discorb/dictionary.rb +2 -0
  69. data/lib/discorb/embed.rb +55 -14
  70. data/lib/discorb/emoji.rb +59 -5
  71. data/lib/discorb/emoji_table.rb +4970 -4
  72. data/lib/discorb/error.rb +7 -1
  73. data/lib/discorb/event.rb +56 -21
  74. data/lib/discorb/exe/about.rb +1 -0
  75. data/lib/discorb/exe/irb.rb +2 -4
  76. data/lib/discorb/exe/new.rb +95 -28
  77. data/lib/discorb/exe/run.rb +9 -37
  78. data/lib/discorb/exe/setup.rb +25 -12
  79. data/lib/discorb/exe/show.rb +4 -3
  80. data/lib/discorb/extend.rb +1 -0
  81. data/lib/discorb/extension.rb +6 -3
  82. data/lib/discorb/flag.rb +11 -0
  83. data/lib/discorb/gateway.rb +312 -169
  84. data/lib/discorb/gateway_requests.rb +4 -7
  85. data/lib/discorb/guild.rb +255 -89
  86. data/lib/discorb/guild_template.rb +34 -7
  87. data/lib/discorb/http.rb +23 -11
  88. data/lib/discorb/integration.rb +27 -9
  89. data/lib/discorb/intents.rb +8 -8
  90. data/lib/discorb/interaction/autocomplete.rb +31 -19
  91. data/lib/discorb/interaction/command.rb +70 -17
  92. data/lib/discorb/interaction/components.rb +20 -4
  93. data/lib/discorb/interaction/modal.rb +0 -1
  94. data/lib/discorb/interaction/response.rb +73 -22
  95. data/lib/discorb/interaction/root.rb +29 -14
  96. data/lib/discorb/interaction.rb +1 -0
  97. data/lib/discorb/invite.rb +16 -9
  98. data/lib/discorb/member.rb +46 -5
  99. data/lib/discorb/message.rb +56 -15
  100. data/lib/discorb/message_meta.rb +39 -9
  101. data/lib/discorb/modules.rb +56 -14
  102. data/lib/discorb/permission.rb +14 -5
  103. data/lib/discorb/presence.rb +43 -10
  104. data/lib/discorb/rate_limit.rb +13 -3
  105. data/lib/discorb/reaction.rb +10 -4
  106. data/lib/discorb/role.rb +31 -4
  107. data/lib/discorb/shard.rb +74 -0
  108. data/lib/discorb/sticker.rb +30 -21
  109. data/lib/discorb/user.rb +13 -1
  110. data/lib/discorb/utils/colored_puts.rb +1 -0
  111. data/lib/discorb/voice_state.rb +30 -8
  112. data/lib/discorb/webhook.rb +88 -25
  113. data/lib/discorb.rb +10 -6
  114. data/po/yard.pot +9 -9
  115. data/sig/discorb.rbs +7232 -5837
  116. metadata +23 -6
  117. data/examples/commands/bookmarker.rb +0 -42
  118. data/examples/commands/hello.rb +0 -10
  119. data/examples/commands/inspect.rb +0 -25
  120. data/lib/discorb/log.rb +0 -81
@@ -1,9 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Discorb
4
- #
5
- # Handles application commands.
6
- #
7
4
  module ApplicationCommand
8
5
  #
9
6
  # Module to handle application commands.
@@ -12,44 +9,83 @@ module Discorb
12
9
  #
13
10
  # Add new top-level command.
14
11
  #
15
- # @param [String] command_name Command name.
16
- # @param [String] description Command description.
17
- # @param [Hash{String => Hash{:description => String, :optional => Boolean, :type => Object}}] options Command options.
12
+ # @param [String, Hash{Symbol => String}] command_name Command name.
13
+ # If hash is passed, it must be a pair of Language code and Command name, and `:default` key is required.
14
+ # You can use `_` instead of `-` in language code.
15
+ # @param [String, Hash{Symbol => String}] description Command description.
16
+ # If hash is passed, it must be a pair of Language code and Command description, and `:default` key is required.
17
+ # You can use `_` instead of `-` in language code.
18
+ # @param [Hash{String => Hash{:description => String, :optional => Boolean, :type => Object}}] options
19
+ # Command options.
18
20
  # The key is the option name, the value is a hash with the following keys:
19
21
  #
20
22
  # | Key | Type | Description |
21
23
  # | --- | --- | --- |
22
- # | `:description` | `String` | Description of the option. |
23
- # | `:required` | Whether the argument is required. `optional` will be used if not specified. |
24
- # | `:optional` | Whether the argument is optional. `required` will be used if not specified. |
24
+ # | `:description` | `String` \| `Hash{Symbol => String}` |
25
+ # Description of the option. If hash is passed, it must be a pair of Language code and description,
26
+ # and `:default` key is required. You can use `_` instead of `-` in language code. |
27
+ # | `:required` | Boolean(true | false) |
28
+ # Whether the argument is required. `optional` will be used if not specified. |
29
+ # | `:optional` | Boolean(true | false) |
30
+ # Whether the argument is optional. `required` will be used if not specified. |
25
31
  # | `:type` | `Object` | Type of the option. |
26
- # | `:choice` | `Hash{String => String, Integer, Float}` | Type of the option. |
32
+ # | `:choices` | `Hash{String => String, Integer, Float}` | Type of the option. |
33
+ # | `:choices_localizations` | `Hash{String => Hash{Symbol => String}}` |
34
+ # Localization of the choice. Key must be the name of a choice. |
27
35
  # | `:default` | `Object` | Default value of the option. |
28
36
  # | `:channel_types` | `Array<Class<Discorb::Channel>>` | Type of the channel option. |
29
37
  # | `:autocomplete` | `Proc` | Autocomplete function. |
30
38
  # | `:range` | `Range` | Range of the option. Only valid for numeric options. (`:int`, `:float`) |
31
39
  #
32
- # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
40
+ # @param [Array<#to_s>, false, nil] guild_ids
41
+ # Guild IDs to set the command to. `false` to global command, `nil` to use default.
42
+ # @param [Boolean] dm_permission Whether the command is available in DM.
43
+ # @param [Discorb::Permission] default_permission The default permission of the command.
33
44
  # @param [Proc] block Command block.
34
45
  #
35
- # @return [Discorb::ApplicationCommand::Command::SlashCommand] Command object.
46
+ # @return [Discorb::ApplicationCommand::Command::ChatInputCommand] Command object.
36
47
  #
37
48
  # @see file:docs/application_command.md#register-slash-command Application Comamnds: Register Slash Command
38
49
  # @see file:docs/cli/setup.md CLI: setup
39
50
  #
40
- def slash(command_name, description, options = {}, guild_ids: nil, &block)
41
- command = Discorb::ApplicationCommand::Command::SlashCommand.new(command_name, description, options, guild_ids, block, 1, "")
51
+ def slash(
52
+ command_name,
53
+ description,
54
+ options = {},
55
+ guild_ids: nil,
56
+ dm_permission: true,
57
+ default_permission: nil,
58
+ &block
59
+ )
60
+ command_name = { default: command_name } if command_name.is_a?(String)
61
+ description = { default: description } if description.is_a?(String)
62
+ command_name = ApplicationCommand.modify_localization_hash(command_name)
63
+ description = ApplicationCommand.modify_localization_hash(description)
64
+ command = Discorb::ApplicationCommand::Command::ChatInputCommand.new(
65
+ command_name,
66
+ description,
67
+ options,
68
+ guild_ids,
69
+ block,
70
+ 1,
71
+ nil,
72
+ dm_permission,
73
+ default_permission
74
+ )
42
75
  @commands << command
43
- @bottom_commands << command
76
+ @callable_commands << command
44
77
  command
45
78
  end
46
79
 
47
80
  #
48
81
  # Add new command with group.
49
82
  #
50
- # @param [String] command_name Command name.
51
- # @param [String] description Command description.
52
- # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
83
+ # @param [String, Hash{Symbol => String}] command_name Command name.
84
+ # @param [String, Hash{Symbol => String}] description Command description.
85
+ # @param [Array<#to_s>, false, nil] guild_ids
86
+ # Guild IDs to set the command to. `false` to global command, `nil` to use default.
87
+ # @param [Boolean] dm_permission Whether the command is available in DM.
88
+ # @param [Discorb::Permission] default_permission The default permission of the command.
53
89
  #
54
90
  # @yield Block to yield with the command.
55
91
  # @yieldparam [Discorb::ApplicationCommand::Command::GroupCommand] group Group command.
@@ -59,9 +95,14 @@ module Discorb
59
95
  # @see file:docs/application_command.md Application Commands
60
96
  # @see file:docs/cli/setup.md CLI: setup
61
97
  #
62
- def slash_group(command_name, description, guild_ids: nil, &block)
63
- command = Discorb::ApplicationCommand::Command::GroupCommand.new(command_name, description, guild_ids, nil, self)
64
- command.yield_self(&block) if block_given?
98
+ def slash_group(command_name, description, guild_ids: nil, dm_permission: true, default_permission: nil, &block)
99
+ command_name = { default: command_name } if command_name.is_a?(String)
100
+ description = { default: description } if description.is_a?(String)
101
+ command_name = ApplicationCommand.modify_localization_hash(command_name)
102
+ description = ApplicationCommand.modify_localization_hash(description)
103
+ command = Discorb::ApplicationCommand::Command::GroupCommand.new(command_name, description, guild_ids, nil,
104
+ self, dm_permission, default_permission)
105
+ command.then(&block) if block_given?
65
106
  @commands << command
66
107
  command
67
108
  end
@@ -69,8 +110,11 @@ module Discorb
69
110
  #
70
111
  # Add message context menu command.
71
112
  #
72
- # @param [String] command_name Command name.
73
- # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
113
+ # @param [String, Hash{Symbol => String}] command_name Command name.
114
+ # @param [Array<#to_s>, false, nil] guild_ids
115
+ # Guild IDs to set the command to. `false` to global command, `nil` to use default.
116
+ # @param [Boolean] dm_permission Whether the command is available in DM.
117
+ # @param [Discorb::Permission] default_permission The default permission of the command.
74
118
  # @param [Proc] block Command block.
75
119
  # @yield [interaction, message] Block to execute.
76
120
  # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] interaction Interaction object.
@@ -78,8 +122,11 @@ module Discorb
78
122
  #
79
123
  # @return [Discorb::ApplicationCommand::Command] Command object.
80
124
  #
81
- def message_command(command_name, guild_ids: nil, &block)
82
- command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 3)
125
+ def message_command(command_name, guild_ids: nil, dm_permission: true, default_permission: nil, &block)
126
+ command_name = { default: command_name } if command_name.is_a?(String)
127
+ command_name = ApplicationCommand.modify_localization_hash(command_name)
128
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 3, dm_permission,
129
+ default_permission)
83
130
  @commands << command
84
131
  command
85
132
  end
@@ -87,8 +134,11 @@ module Discorb
87
134
  #
88
135
  # Add user context menu command.
89
136
  #
90
- # @param [String] command_name Command name.
91
- # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to set the command to. `false` to global command, `nil` to use default.
137
+ # @param [String, Hash{Symbol => String}] command_name Command name.
138
+ # @param [Array<#to_s>, false, nil] guild_ids
139
+ # Guild IDs to set the command to. `false` to global command, `nil` to use default.
140
+ # @param [Boolean] dm_permission Whether the command is available in DM.
141
+ # @param [Discorb::Permission] default_permission The default permission of the command.
92
142
  # @param [Proc] block Command block.
93
143
  # @yield [interaction, user] Block to execute.
94
144
  # @yieldparam [Discorb::CommandInteraction::UserMenuCommand] interaction Interaction object.
@@ -96,8 +146,11 @@ module Discorb
96
146
  #
97
147
  # @return [Discorb::ApplicationCommand::Command] Command object.
98
148
  #
99
- def user_command(command_name, guild_ids: nil, &block)
100
- command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 2)
149
+ def user_command(command_name, guild_ids: nil, dm_permission: true, default_permission: nil, &block)
150
+ command_name = { default: command_name } if command_name.is_a?(String)
151
+ command_name = ApplicationCommand.modify_localization_hash(command_name)
152
+ command = Discorb::ApplicationCommand::Command.new(command_name, guild_ids, block, 2, dm_permission,
153
+ default_permission)
101
154
  @commands << command
102
155
  command
103
156
  end
@@ -108,7 +161,8 @@ module Discorb
108
161
  # @see Client#initialize
109
162
  #
110
163
  # @param [String] token Bot token.
111
- # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to use as default. If `false` is given, it will be global command.
164
+ # @param [Array<#to_s>, false, nil] guild_ids
165
+ # Guild IDs to use as default. If `false` is given, it will be global command.
112
166
  #
113
167
  # @note `token` parameter only required if you don't run client.
114
168
  #
@@ -139,10 +193,10 @@ module Discorb
139
193
  global_commands.map(&:to_hash)
140
194
  ).wait
141
195
  end
142
- if ENV["DISCORB_CLI_FLAG"] == "setup"
196
+ if ENV.fetch("DISCORB_CLI_FLAG", nil) == "setup"
143
197
  sputs "Registered commands for global:"
144
198
  global_commands.each do |command|
145
- iputs "- #{command.name}"
199
+ iputs "- #{command.name["default"]}"
146
200
  end
147
201
  end
148
202
  unless final_guild_ids.empty?
@@ -156,11 +210,39 @@ module Discorb
156
210
  ).wait
157
211
  sputs "Registered commands for #{guild_id}:"
158
212
  commands.each do |command|
159
- iputs "- #{command.name}"
213
+ iputs "- #{command.name["default"]}"
160
214
  end
161
215
  end
162
216
  end
163
- @log.info "Successfully setup commands"
217
+ @logger.info "Successfully setup commands"
218
+ end
219
+ end
220
+
221
+ #
222
+ # Claer commands in specified guilds.
223
+ # @async
224
+ # @see Client#initialize
225
+ #
226
+ # @param [String] token Bot token.
227
+ # @param [Array<#to_s>, false, nil] guild_ids Guild IDs to clear.
228
+ #
229
+ # @note `token` parameter only required if you don't run client.
230
+ #
231
+ def clear_commands(token, guild_ids)
232
+ Async do
233
+ @token ||= token
234
+ @http = HTTP.new(self)
235
+ app_info = fetch_application.wait
236
+
237
+ guild_ids.each do |guild_id|
238
+ @http.request(
239
+ Route.new("/applications/#{app_info.id}/guilds/#{guild_id}/commands",
240
+ "//applications/:application_id/guilds/:guild_id/commands",
241
+ :put),
242
+ []
243
+ ).wait
244
+ end
245
+ sputs "Cleared commands for #{guild_ids.length} guilds." if ENV.fetch("DISCORB_CLI_FLAG", nil) == "setup"
164
246
  end
165
247
  end
166
248
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
- %w[command handler].each do |file|
2
+
3
+ %w[common command handler].each do |file|
3
4
  require_relative "app_command/#{file}.rb"
4
5
  end
@@ -29,7 +29,14 @@ module Discorb
29
29
  alias bot_require_code_grant? bot_require_code_grant
30
30
  # @return [Discorb::Application::Flag] The application's flags.
31
31
  attr_reader :flags
32
+
33
+ #
34
+ # Initializes a new instance of the Application class.
32
35
  # @private
36
+ #
37
+ # @param [Discorb::Client] client The client that instantiated the object.
38
+ # @param [Hash] data The data of the object.
39
+ #
33
40
  def initialize(client, data)
34
41
  @client = client
35
42
  @data = data
@@ -97,7 +104,13 @@ module Discorb
97
104
  # @return [Discorb::Application::Team::Member] The team's member.
98
105
  attr_reader :members
99
106
 
107
+ #
108
+ # Initializes a new instance of the Team class.
100
109
  # @private
110
+ #
111
+ # @param [Discorb::Client] client The client that instantiated the object.
112
+ # @param [Hash] data The data of the object.
113
+ #
101
114
  def initialize(client, data)
102
115
  @client = client
103
116
  @id = Snowflake.new(data[:id])
@@ -142,7 +155,9 @@ module Discorb
142
155
  # @!attribute [r] owner?
143
156
  # @return [Boolean] Whether the member is the team's owner.
144
157
 
145
- @membership_state = {
158
+ # @private
159
+ # @return [{Integer => Symbol}] The permission map.
160
+ MEMBERSHIP_STATE = {
146
161
  1 => :invited,
147
162
  2 => :accepted,
148
163
  }.freeze
@@ -153,7 +168,7 @@ module Discorb
153
168
  @team = team
154
169
  @user = client.users[data[:user][:id]] || User.new(client, data[:user])
155
170
  @team_id = Snowflake.new(data[:team_id])
156
- @membership_state = self.class.membership_state[data[:membership_state]]
171
+ @membership_state = MEMBERSHIP_STATE[data[:membership_state]]
157
172
  @permissions = data[:permissions].map(&:to_sym)
158
173
  end
159
174
 
@@ -176,11 +191,6 @@ module Discorb
176
191
  def ==(other)
177
192
  super || @user == other
178
193
  end
179
-
180
- class << self
181
- # @private
182
- attr_reader :membership_state
183
- end
184
194
  end
185
195
  end
186
196
  end
data/lib/discorb/asset.rb CHANGED
@@ -11,7 +11,13 @@ module Discorb
11
11
  # @!attribute [r] animated?
12
12
  # @return [Boolean] Whether the asset is animated.
13
13
 
14
+ #
15
+ # Initialize a new instance of the Asset class.
14
16
  # @private
17
+ #
18
+ # @param [Discorb::Client] client The client that instantiated the object.
19
+ # @param [Hash] data The data of the object.
20
+ #
15
21
  def initialize(target, hash, path: nil)
16
22
  @hash = hash
17
23
  @target = target
@@ -45,7 +51,7 @@ module Discorb
45
51
  case @target
46
52
  when User, Member, Webhook
47
53
  "avatars"
48
- when Guild, IncomingWebhook::Guild
54
+ when Guild, Webhook::FollowerWebhook::Guild
49
55
  "icons"
50
56
  when Application, Integration::Application
51
57
  "app-icons"
@@ -59,11 +65,13 @@ module Discorb
59
65
  # Represents a default avatar.
60
66
  #
61
67
  class DefaultAvatar < DiscordModel
62
-
63
68
  # @!attribute [r] animated?
64
69
  # @return [false] For compatibility with {Asset}, always `false`.
65
70
 
71
+ #
72
+ # Initialize a new instance of the DefaultAvatar class.
66
73
  # @private
74
+ #
67
75
  def initialize(discriminator)
68
76
  @discriminator = discriminator.to_s.rjust(4, "0")
69
77
  end
@@ -33,6 +33,7 @@ module Discorb
33
33
  # @return [:client, :discord] The attachment was created by.
34
34
  attr_reader :created_by
35
35
  # @private
36
+ # @return [Boolean] Whether the attachment will be closed after it is sent.
36
37
  attr_reader :will_close
37
38
 
38
39
  # @!attribute [r] image?
@@ -62,11 +63,14 @@ module Discorb
62
63
  @created_by = :client
63
64
  end
64
65
 
66
+ #
67
+ # Initializes the object from a hash.
65
68
  # @private
69
+ #
66
70
  def initialize_hash(data)
67
71
  @id = Snowflake.new(data[:id])
68
72
  @filename = data[:filename]
69
- @content_type = data[:content_type]
73
+ @content_type = data[:content_type] || "application/octet-stream"
70
74
  @size = data[:size]
71
75
  @url = data[:url]
72
76
  @proxy_url = data[:proxy_url]
@@ -79,7 +83,18 @@ module Discorb
79
83
  @content_type.start_with? "image/"
80
84
  end
81
85
 
86
+ def inspect
87
+ if @created_by == :discord
88
+ "<#{self.class} #{@id}: #{@filename}>"
89
+ else
90
+ "<#{self.class} #{io.fileno}: #{@filename}>"
91
+ end
92
+ end
93
+
94
+ #
95
+ # Creates a new file from a hash.
82
96
  # @private
97
+ #
83
98
  def self.from_hash(data)
84
99
  inst = allocate
85
100
  inst.initialize_hash(data)
@@ -93,7 +108,7 @@ module Discorb
93
108
  # @param [String] filename The filename of the file. object_id of the string is used if not set.
94
109
  # @param [String] content_type The content type of the file. If not set, it is guessed from the filename.
95
110
  #
96
- # @return [File] The new file.
111
+ # @return [Discorb::Attachment] The new file.
97
112
  #
98
113
  def self.from_string(string, filename = nil, content_type: nil, description: nil)
99
114
  io = StringIO.new(string)
@@ -14,16 +14,25 @@ module Discorb
14
14
  # @return [Array<Discorb::AuditLog::Entry>] The entries in this audit log.
15
15
  attr_reader :entries
16
16
 
17
+ #
18
+ # Initializes a new instance of the AuditLog class.
17
19
  # @private
20
+ #
18
21
  def initialize(client, data, guild)
19
22
  @client = client
20
23
  @guild = guild
21
- @webhooks = data[:webhooks].map { |webhook| Webhook.new([@client, webhook]) }
24
+ @webhooks = data[:webhooks].map { |webhook| Webhook.from_data(@client, webhook) }
22
25
  @users = data[:users].map { |user| client.users[user[:id]] || User.new(@client, user) }
23
- @threads = data[:threads].map { |thread| client.channels[thread[:id]] || Channel.make_channel(@client, thread, no_cache: true) }
26
+ @threads = data[:threads].map do |thread|
27
+ client.channels[thread[:id]] || Channel.make_channel(@client, thread, no_cache: true)
28
+ end
24
29
  @entries = data[:audit_log_entries].map { |entry| AuditLog::Entry.new(@client, entry, guild.id) }
25
30
  end
26
31
 
32
+ def inspect
33
+ "<#{self.class} #{@entries.length} entries>"
34
+ end
35
+
27
36
  #
28
37
  # Gets an entry from entries.
29
38
  #
@@ -99,7 +108,8 @@ module Discorb
99
108
  attr_reader :type
100
109
  # @return [Discorb::AuditLog::Entry::Changes] The changes in this entry.
101
110
  attr_reader :changes
102
- # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message] The target of the entry.
111
+ # @return [Discorb::Channel, Discorb::Role, Discorb::Member, Discorb::Guild, Discorb::Message]
112
+ # The target of the entry.
103
113
  attr_reader :target
104
114
  # @return [Hash{Symbol => Object}] The optional data for this entry.
105
115
  # @note You can use dot notation to access the data.
@@ -108,8 +118,11 @@ module Discorb
108
118
  # @!attribute [r] user
109
119
  # @return [Discorb::User] The user who performed the action.
110
120
 
121
+ #
122
+ # @return [{Integer => Symbol}] The map of events to their respective changes.
111
123
  # @private
112
- @events = {
124
+ #
125
+ EVENTS = {
113
126
  1 => :guild_update,
114
127
  10 => :channel_create,
115
128
  11 => :channel_update,
@@ -159,25 +172,31 @@ module Discorb
159
172
  112 => :thread_delete,
160
173
  }.freeze
161
174
 
175
+ #
176
+ # The converter for the change.
162
177
  # @private
163
- @converts = {
178
+ #
179
+ CONVERTERS = {
164
180
  channel: ->(client, id, _guild_id) { client.channels[id] },
165
181
  thread: ->(client, id, _guild_id) { client.channels[id] },
166
182
  role: ->(client, id, guild_id) { client.guilds[guild_id]&.roles&.[](id) },
167
183
  member: ->(client, id, guild_id) { client.guilds[guild_id]&.members&.[](id) },
168
184
  guild: ->(client, id, _guild_id) { client.guilds[id] },
169
185
  message: ->(client, id, _guild_id) { client.messages[id] },
170
- }
186
+ }.freeze
171
187
 
188
+ #
189
+ # Initializes a new AuditLog entry.
172
190
  # @private
191
+ #
173
192
  def initialize(client, data, guild_id)
174
193
  @client = client
175
194
  @guild_id = Snowflake.new(guild_id)
176
195
  @id = Snowflake.new(data[:id])
177
196
  @user_id = Snowflake.new(data[:user_id])
178
197
  @target_id = Snowflake.new(data[:target_id])
179
- @type = self.class.events[data[:action_type]]
180
- @target = self.class.converts[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
198
+ @type = EVENTS[data[:action_type]]
199
+ @target = CONVERTERS[@type.to_s.split("_")[0].to_sym]&.call(client, @target_id, @gui)
181
200
  @target ||= Snowflake.new(data[:target_id])
182
201
  @changes = data[:changes] && Changes.new(data[:changes])
183
202
  @reason = data[:reason]
@@ -185,7 +204,7 @@ module Discorb
185
204
  define_singleton_method(option) { value }
186
205
  if option.end_with?("_id")
187
206
  define_singleton_method(option.to_s.sub("_id", "")) do
188
- self.class.converts[option.to_s.split("_")[0].to_sym]&.call(client, value, @guild_id)
207
+ CONVERTERS[option.to_s.split("_")[0].to_sym]&.call(client, value, @guild_id)
189
208
  end
190
209
  end
191
210
  end
@@ -223,8 +242,11 @@ module Discorb
223
242
  attr_reader :data
224
243
 
225
244
  #
245
+ # Initializes a new changes object.
226
246
  # @private
227
247
  #
248
+ # @param [Hash] data The data to initialize with.
249
+ #
228
250
  def initialize(data)
229
251
  @data = data.to_h { |d| [d[:key].to_sym, d] }
230
252
  @data.each do |k, v|
@@ -232,6 +254,9 @@ module Discorb
232
254
  end
233
255
  end
234
256
 
257
+ #
258
+ # Formats the changes into a string.
259
+ #
235
260
  def inspect
236
261
  "#<#{self.class} #{@data.length} changes>"
237
262
  end
@@ -270,7 +295,10 @@ module Discorb
270
295
  # @return [Object] The new value of the change.
271
296
  attr_reader :new_value
272
297
 
298
+ #
299
+ # Initializes a new change object.
273
300
  # @private
301
+ #
274
302
  def initialize(data)
275
303
  @key = data[:key].to_sym
276
304
  method = case @key.to_s
@@ -279,11 +307,11 @@ module Discorb
279
307
  when "permissions"
280
308
  ->(v) { Discorb::Permission.new(v.to_i) }
281
309
  when "status"
282
- ->(v) { Discorb::ScheduledEvent.status[v] }
310
+ ->(v) { Discorb::ScheduledEvent::STATUS[v] }
283
311
  when "entity_type"
284
- ->(v) { Discorb::ScheduledEvent.entity_type[v] }
312
+ ->(v) { Discorb::ScheduledEvent::ENTITY_TYPE[v] }
285
313
  when "privacy_level"
286
- ->(v) { Discorb::StageInstance.privacy_level[v] || Discorb::ScheduledEvent.privacy_level[v] }
314
+ ->(v) { Discorb::StageInstance::PRIVACY_LEVEL[v] || Discorb::ScheduledEvent::PRIVACY_LEVEL[v] }
287
315
  else
288
316
  ->(v) { v }
289
317
  end
@@ -298,10 +326,20 @@ module Discorb
298
326
  @new_value.__send__(method, ...)
299
327
  end
300
328
 
329
+ #
330
+ # Format the change into a string.
331
+ #
332
+ # @return [String] The string representation of the change.
333
+ #
301
334
  def inspect
302
335
  "#<#{self.class} #{@key.inspect} #{@old_value.inspect} -> #{@new_value.inspect}>"
303
336
  end
304
337
 
338
+ #
339
+ # Whether the change responds to the given method.
340
+ #
341
+ # @return [Boolean] Whether the change responds to the given method.
342
+ #
305
343
  def respond_to_missing?(method, include_private = false)
306
344
  @new_value.respond_to?(method, include_private)
307
345
  end
@@ -321,7 +359,10 @@ module Discorb
321
359
  # @return [Discorb::Integration::Account] The account of the integration.
322
360
  attr_reader :account
323
361
 
362
+ #
363
+ # Initializes a new integration object.
324
364
  # @private
365
+ #
325
366
  def initialize(data)
326
367
  @id = Snowflake.new(data[:id])
327
368
  @type = data[:type].to_sym
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Discorb
4
+ #
5
+ # Represents a channel of Discord.
6
+ # @abstract
7
+ #
8
+ class Channel < DiscordModel
9
+ # @return [Discorb::Snowflake] The ID of the channel.
10
+ attr_reader :id
11
+ # @return [String] The name of the channel.
12
+ attr_reader :name
13
+
14
+ # @!attribute [r] type
15
+ # @return [Integer] The type of the channel as integer.
16
+
17
+ @channel_type = nil
18
+ @subclasses = []
19
+
20
+ #
21
+ # Initializes a new instance of the Channel class.
22
+ # @private
23
+ #
24
+ def initialize(client, data, no_cache: false)
25
+ @client = client
26
+ @data = {}
27
+ @no_cache = no_cache
28
+ _set_data(data)
29
+ end
30
+
31
+ #
32
+ # Checks if the channel is other channel.
33
+ #
34
+ # @param [Discorb::Channel] other The channel to check.
35
+ #
36
+ # @return [Boolean] True if the channel is other channel.
37
+ #
38
+ def ==(other)
39
+ return false unless other.respond_to?(:id)
40
+
41
+ @id == other.id
42
+ end
43
+
44
+ def inspect
45
+ "#<#{self.class} \"##{@name}\" id=#{@id}>"
46
+ end
47
+
48
+ #
49
+ # Returns the descendants of the Channel class.
50
+ # @private
51
+ #
52
+ def self.descendants
53
+ ObjectSpace.each_object(Class).select { |klass| klass < self }
54
+ end
55
+
56
+ #
57
+ # Creates a new instance of the Channel class or instance of its descendants.
58
+ # @private
59
+ #
60
+ # @param [Discorb::Client] client The client that instantiated the object.
61
+ # @param [Hash] data The data of the object.
62
+ # @param [Boolean] no_cache Whether to disable cache the object.
63
+ #
64
+ def self.make_channel(client, data, no_cache: false)
65
+ descendants.each do |klass|
66
+ if !klass.channel_type.nil? && klass.channel_type == data[:type]
67
+ return klass.new(client, data,
68
+ no_cache: no_cache)
69
+ end
70
+ end
71
+ client.logger.warn("Unknown channel type #{data[:type]}, initialized GuildChannel")
72
+ GuildChannel.new(client, data)
73
+ end
74
+
75
+ class << self
76
+ #
77
+ # @private
78
+ # @return [Integer] The type of the channel.
79
+ #
80
+ attr_reader :channel_type
81
+ end
82
+
83
+ def type
84
+ self.class.channel_type
85
+ end
86
+
87
+ #
88
+ # Returns the channel id to request.
89
+ # @private
90
+ #
91
+ # @return [Async::Task<Discorb::Snowflake>] A task that resolves to the channel id.
92
+ #
93
+ def channel_id
94
+ Async do
95
+ @id
96
+ end
97
+ end
98
+
99
+ private
100
+
101
+ def _set_data(data)
102
+ @id = Snowflake.new(data[:id])
103
+ @name = data[:name]
104
+ @client.channels[@id] = self if !@no_cache && !(data[:no_cache])
105
+ @data.update(data)
106
+ end
107
+ end
108
+ end