discorb 0.14.0 → 0.16.0

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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build_version.yml +1 -1
  3. data/.github/workflows/lint-push.yml +4 -2
  4. data/.rubocop.yml +6 -2
  5. data/Changelog.md +27 -0
  6. data/Rakefile +6 -0
  7. data/docs/events.md +71 -5
  8. data/docs/faq.md +8 -8
  9. data/examples/simple/rolepanel.rb +1 -1
  10. data/examples/simple/shard.rb +17 -0
  11. data/lib/discorb/allowed_mentions.rb +7 -0
  12. data/lib/discorb/app_command/command.rb +64 -2
  13. data/lib/discorb/app_command/handler.rb +1 -1
  14. data/lib/discorb/application.rb +16 -7
  15. data/lib/discorb/asset.rb +9 -0
  16. data/lib/discorb/{file.rb → attachment.rb} +55 -33
  17. data/lib/discorb/audit_logs.rb +42 -4
  18. data/lib/discorb/channel.rb +47 -12
  19. data/lib/discorb/client.rb +135 -51
  20. data/lib/discorb/common.rb +18 -4
  21. data/lib/discorb/components/button.rb +5 -6
  22. data/lib/discorb/components/select_menu.rb +2 -16
  23. data/lib/discorb/dictionary.rb +2 -0
  24. data/lib/discorb/embed.rb +71 -38
  25. data/lib/discorb/emoji.rb +29 -2
  26. data/lib/discorb/emoji_table.rb +1 -1
  27. data/lib/discorb/error.rb +7 -1
  28. data/lib/discorb/event.rb +27 -17
  29. data/lib/discorb/exe/new.rb +5 -5
  30. data/lib/discorb/exe/run.rb +1 -15
  31. data/lib/discorb/gateway.rb +262 -161
  32. data/lib/discorb/gateway_requests.rb +4 -7
  33. data/lib/discorb/guild.rb +67 -33
  34. data/lib/discorb/guild_template.rb +24 -3
  35. data/lib/discorb/http.rb +25 -3
  36. data/lib/discorb/integration.rb +23 -8
  37. data/lib/discorb/intents.rb +15 -10
  38. data/lib/discorb/interaction/autocomplete.rb +4 -4
  39. data/lib/discorb/interaction/command.rb +34 -5
  40. data/lib/discorb/interaction/components.rb +15 -2
  41. data/lib/discorb/interaction/response.rb +12 -0
  42. data/lib/discorb/interaction/root.rb +16 -1
  43. data/lib/discorb/invite.rb +11 -7
  44. data/lib/discorb/member.rb +21 -0
  45. data/lib/discorb/message.rb +59 -3
  46. data/lib/discorb/message_meta.rb +36 -55
  47. data/lib/discorb/modules.rb +38 -14
  48. data/lib/discorb/permission.rb +14 -5
  49. data/lib/discorb/presence.rb +41 -8
  50. data/lib/discorb/rate_limit.rb +7 -2
  51. data/lib/discorb/reaction.rb +6 -0
  52. data/lib/discorb/role.rb +12 -0
  53. data/lib/discorb/shard.rb +74 -0
  54. data/lib/discorb/sticker.rb +22 -14
  55. data/lib/discorb/user.rb +11 -0
  56. data/lib/discorb/voice_state.rb +20 -2
  57. data/lib/discorb/webhook.rb +53 -2
  58. data/lib/discorb.rb +5 -3
  59. data/sig/discorb.rbs +7234 -6714
  60. metadata +5 -4
  61. data/lib/discorb/log.rb +0 -81
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 810e9b14c77e49e9fca7afc4fe6b98389b26cb17dc1617213f38d7655b990a49
4
- data.tar.gz: bbaa999265ac212f90ab60d57ec772fe7ade0e47f264a136130c679b85a46952
3
+ metadata.gz: 6537aa3c45f64e6b0e8040a5a0d989934fb58d766ee6de305bf04132630a7b94
4
+ data.tar.gz: 68512bc0d2abd0738cc6e81ba2b794feb87480d6d84197a51a6deba739d31d5a
5
5
  SHA512:
6
- metadata.gz: 120828736edcf7eef9d78410914651edeb41ae85eadef012050b105b03c80f07f835d812105d3cfe954c7237e344b3bbc540af8840a7dde1a69f590b008a759e
7
- data.tar.gz: f29b0399c65f180b05bf6c0c3d5f253689ff08c734f60ee7681b57c060d99e36dd85fc275f9652354933478b8139aa76c8ad854f6963fd1c074a8a260ffb6bde
6
+ metadata.gz: 239e4658a2ade0ea8382655970a1eecbb3c62c7c3619e3de8fdf932c1c0a4053e35b722bef5dcdbd67477754388cc3c157c9be6360ef7625fe9f84504b5ecf90
7
+ data.tar.gz: d830a06c7a505ee31aeb3242e7aa59dadf6abab24a26c357b9e29e5f94d5fef7a889b114d4b7793ffda3f50b19a6be0c3f87921934393b03e71c5f50bfa96de4
@@ -33,7 +33,7 @@ jobs:
33
33
  git clone git@github.com:discorb-lib/discorb-lib.github.io /tmp/pages
34
34
  - name: Install dependencies
35
35
  run: |
36
- bundle config --local with 'docs development'
36
+ bundle config --local with 'docs development lint'
37
37
  bundle install
38
38
  gem update uri
39
39
  - name: Generate document
@@ -1,6 +1,8 @@
1
1
  name: Lint with RuboCop
2
2
  on:
3
- - push
3
+ push:
4
+ branches:
5
+ - main
4
6
  jobs:
5
7
  rubocop:
6
8
  runs-on: ubuntu-latest
@@ -15,4 +17,4 @@ jobs:
15
17
  gem install rubocop
16
18
  - name: Run rubocop
17
19
  run: |
18
- rubocop lib
20
+ rubocop lib
data/.rubocop.yml CHANGED
@@ -10,10 +10,14 @@ Metrics:
10
10
  Enabled: false
11
11
 
12
12
  Style/TrailingCommaInHashLiteral: # Disabled for rufo
13
- Enabled: false
13
+ EnforcedStyleForMultiline: consistent_comma
14
+
15
+ Style/TrailingCommaInArrayLiteral: # Disabled for rufo
16
+ EnforcedStyleForMultiline: consistent_comma
14
17
 
15
18
  Style/StringLiterals: # Disabled for rufo
16
- Enabled: false
19
+ Enabled: true
20
+ EnforcedStyle: double_quotes
17
21
 
18
22
  Style/TrailingCommaInArguments: # Disabled for rufo
19
23
  Enabled: false
data/Changelog.md CHANGED
@@ -4,6 +4,33 @@
4
4
 
5
5
  # Changelog
6
6
 
7
+ ## v0.16
8
+
9
+ ### v0.16.0
10
+
11
+ - Change!: Use built-in Logger instead of custom Logger.
12
+ - Delete!: `--log-level`, `--[no-]log-color` is deleted.
13
+ - Add: Support sharding
14
+ - Add: Use Mutex for preventing connection duplications.
15
+
16
+ ## v0.15
17
+
18
+ ### v0.15.1
19
+
20
+ - Add: Add `Member#can_manage?`
21
+ - Add: Add `Discorb::VERSION_ARRAY`
22
+ - Fix: `Snowflake#timestamp` includes milliseconds now
23
+ - Fix: `TextChannel#create_invite` will no longer return `ArgumentError`
24
+ - Fix: Connection will not closed with 4001 when `Client#update_presence`
25
+ is called
26
+
27
+ ### v0.15.0
28
+
29
+ - Add: Migrate to API v10
30
+ - Add: Add `TextChannel#threads`
31
+ - Add: Support editing attachments
32
+ - Delete!: Delete File class - Use Attachment class instead
33
+
7
34
  ## v0.14
8
35
 
9
36
  ### v0.14.0
data/Rakefile CHANGED
@@ -320,6 +320,12 @@ end
320
320
 
321
321
  task document: %i[document:yard document:replace]
322
322
 
323
+ desc "Lint code with rubocop"
323
324
  task :lint do
324
325
  sh "rubocop lib"
325
326
  end
327
+
328
+ desc "Autofix code with rubocop"
329
+ task "lint:fix" do
330
+ sh "rubocop lib -A"
331
+ end
data/docs/events.md CHANGED
@@ -30,13 +30,13 @@ class << client
30
30
  end
31
31
  ```
32
32
 
33
- If you want to seperate event handlers from the client, consider using {Discorb::Extension}. {file:docs/extension.md Learn more about extensions}.
33
+ If you want to separate event handlers from the client, consider using {Discorb::Extension}. {file:docs/extension.md Learn more about extensions}.
34
34
 
35
- Since v0.6.1, you can set `:override` to `true` to register overridable event handlers.
35
+ Since v0.6.1, you can set `:override` to `true` to register event handlers that can be overridden.
36
36
 
37
37
  ```ruby
38
38
  client.on :message, override: true do |event|
39
- puts "This event handler is overrideable!"
39
+ puts "This event handler can be overridden."
40
40
  end
41
41
 
42
42
  client.on :message do |event|
@@ -44,8 +44,8 @@ client.on :message do |event|
44
44
  end
45
45
  ```
46
46
 
47
- This example will print `Override!`, but not `This event handler is overrideable!`.
48
- This is useful for registering event handlers as default behaviour, such as error handlers.
47
+ This example will print `Override!`, but not `This event handler can be overridden.`.
48
+ This is useful for registering event handlers as default behavior, such as error handlers.
49
49
 
50
50
  ```ruby
51
51
  # In the library...
@@ -95,6 +95,22 @@ Defaults to printing the error to stderr, override to handle it yourself.
95
95
  Fires when `discorb setup` is run.
96
96
  This is useful for setting up some dependencies, such as the database.
97
97
 
98
+ #### `shard_standby(shard)`
99
+
100
+ Fires when a shard is standby.
101
+
102
+ | Parameter | Type | Description |
103
+ | ---------- | ----- | ----------- |
104
+ |`shard` | {Discorb::Shard} | The shard that is standby. |
105
+
106
+ #### `shard_resumed(shard)`
107
+
108
+ Fires when a shard is resumed connection.
109
+
110
+ | Parameter | Type | Description |
111
+ | ---------- | ----- | ----------- |
112
+ |`shard` | {Discorb::Shard} | The shard that is standby. |
113
+
98
114
  ### Guild events
99
115
 
100
116
  #### `guild_join(guild)`
@@ -487,6 +503,46 @@ Fires when an invitation is deleted.
487
503
 
488
504
  ### Interaction events
489
505
 
506
+ #### `interaction_create(interaction)`
507
+
508
+ Fires when an interaction is created. This will fire for all interactions.
509
+
510
+ | Parameter | Type | Description |
511
+ | ---------- | ----- | ----------- |
512
+ | `interaction` | {Discorb::Interaction}| The created interaction. |
513
+
514
+ #### `application_command(interaction)`
515
+
516
+ Fires when an application command is used.
517
+
518
+ | Parameter | Type | Description |
519
+ | ---------- | ----- | ----------- |
520
+ | `interaction` | {Discorb::CommandInteraction}| The created interaction. |
521
+
522
+ #### `slash_command(interaction)`
523
+
524
+ Fires when a slash command is used.
525
+
526
+ | Parameter | Type | Description |
527
+ | ---------- | ----- | ----------- |
528
+ | `interaction` | {Discorb::CommandInteraction::SlashCommand}| The created interaction. |
529
+
530
+ #### `message_command(interaction)`
531
+
532
+ Fires when a message command is used.
533
+
534
+ | Parameter | Type | Description |
535
+ | ---------- | ----- | ----------- |
536
+ | `interaction` | {Discorb::CommandInteraction::MessageMenuCommand}| The created interaction. |
537
+
538
+ #### `user_command(interaction)`
539
+
540
+ Fires when a user command is used.
541
+
542
+ | Parameter | Type | Description |
543
+ | ---------- | ----- | ----------- |
544
+ | `interaction` | {Discorb::CommandInteraction::UserMenuCommand}| The created interaction. |
545
+
490
546
  #### `button_click(interaction)`
491
547
 
492
548
  Fires when a button is clicked.
@@ -503,6 +559,16 @@ Fires when a select menu is selected.
503
559
  | ---------- | ----- | ----------- |
504
560
  |`interaction`| {Discorb::MessageComponentInteraction::SelectMenu}| The interaction object. |
505
561
 
562
+ #### `form_submit(interaction)`
563
+
564
+ Fires when a form is submitted.
565
+
566
+ | Parameter | Type | Description |
567
+ | ---------- | ----- | ----------- |
568
+ | `interaction` | {Discorb::ModalInteraction} | The interaction object. |
569
+
570
+ #### `slash_command
571
+
506
572
  ### Voice events
507
573
 
508
574
  Because it's big, it's documented in {file:docs/voice_events.md}.
data/docs/faq.md CHANGED
@@ -62,19 +62,19 @@ client.on :ready do
62
62
  end
63
63
  ```
64
64
 
65
- ### How can I send files?
65
+ ### How can I send attachments?
66
66
 
67
- Use {Discorb::File} class.
67
+ Use {Discorb::Attachment} class.
68
68
 
69
69
  ```ruby
70
- # Send a file
71
- message.channel.post file: Discorb::File.new(File.open("./README.md"))
70
+ # Send an attachment
71
+ message.channel.post attachment: Discorb::Attachment.new(File.open("./README.md"))
72
72
 
73
- # Send some files with text
74
- message.channel.post "File!", files: [Discorb::File.new(File.open("./README.md")), Discorb::File.new(File.open("./License.txt"))]
73
+ # Send some attachment with text
74
+ message.channel.post "File!", attachments: [Discorb::Attachment.new("./README.md"), Discorb::Attachment.new(File.open("./License.txt"))]
75
75
 
76
- # Send a string as a file
77
- message.channel.post file: Discorb::File.from_string("Hello world!", "hello.txt")
76
+ # Send a string as an attachment
77
+ message.channel.post attachments: Discorb::Attachment.from_string("Hello world!", "hello.txt")
78
78
  ```
79
79
 
80
80
  ### How can I add reactions?
@@ -2,7 +2,7 @@
2
2
  require "discorb"
3
3
  intents = Discorb::Intents.new
4
4
  intents.members = true
5
- client = Discorb::Client.new(intents: intents, log: $stdout, colorize_log: true)
5
+ client = Discorb::Client.new(intents: intents)
6
6
 
7
7
  def convert_role(guild, string)
8
8
  guild.roles.find do |role|
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+ require "discorb"
3
+
4
+ client = Discorb::Client.new(log: Logger.new($stdout))
5
+
6
+ client.once :standby do
7
+ puts "Logged in as #{client.user}"
8
+ end
9
+
10
+ client.on :message do |message|
11
+ next if message.author.bot?
12
+ next unless message.content == "!inspect"
13
+
14
+ message.channel.post("I'm #{client.user}, running on shard #{client.shard_id}!")
15
+ end
16
+
17
+ client.run(ENV["DISCORD_BOT_TOKEN"], shards: [0, 1], shard_count: 2)
@@ -32,7 +32,14 @@ module Discorb
32
32
  "#<#{self.class} @everyone=#{@everyone} @roles=#{@roles} @users=#{@users} @replied_user=#{@replied_user}>"
33
33
  end
34
34
 
35
+ #
36
+ # Converts the object to a hash.
35
37
  # @private
38
+ #
39
+ # @param [Discorb::AllowedMentions, nil] other The object to merge.
40
+ #
41
+ # @return [Hash] The hash.
42
+ #
36
43
  def to_hash(other = nil)
37
44
  payload = {
38
45
  parse: %w[everyone roles users],
@@ -23,24 +23,39 @@ module Discorb
23
23
  # @return [Discorb::Dictionary{Discorb::Snowflake, :global => Discorb::Snowflake}] The ID mapping.
24
24
  attr_reader :id_map
25
25
 
26
- @types = {
26
+ # @private
27
+ # @return [{Integer => Symbol}] The mapping of raw types to types.
28
+ TYPES = {
27
29
  1 => :chat_input,
28
30
  2 => :user,
29
31
  3 => :message,
30
32
  }.freeze
31
33
 
34
+ #
35
+ # Initialize a new command.
32
36
  # @private
37
+ #
38
+ # @param [String] name The name of the command.
39
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
40
+ # @param [Proc] block The block of the command.
41
+ # @param [:chat_input, :user, :message] type The type of the command.
42
+ #
33
43
  def initialize(name, guild_ids, block, type)
34
44
  @name = name
35
45
  @guild_ids = guild_ids&.map(&:to_s)
36
46
  @block = block
37
47
  @raw_type = type
38
- @type = Discorb::ApplicationCommand::Command.types[type]
48
+ @type = Discorb::ApplicationCommand::Command::TYPES[type]
39
49
  @type_raw = type
40
50
  @id_map = Discorb::Dictionary.new
41
51
  end
42
52
 
53
+ #
54
+ # Changes the self pointer to the given object.
43
55
  # @private
56
+ #
57
+ # @param [Object] instance The object to change the self pointer to.
58
+ #
44
59
  def replace_block(instance)
45
60
  current_block = @block.dup
46
61
  @block = proc do |*args|
@@ -48,7 +63,12 @@ module Discorb
48
63
  end
49
64
  end
50
65
 
66
+ #
67
+ # Converts the object to a hash.
51
68
  # @private
69
+ #
70
+ # @return [Hash] The hash represents the object.
71
+ #
52
72
  def to_hash
53
73
  {
54
74
  name: @name,
@@ -66,7 +86,18 @@ module Discorb
66
86
  # @return [Hash{String => Hash}] The options of the command.
67
87
  attr_reader :options
68
88
 
89
+ #
90
+ # Initialize a new slash command.
69
91
  # @private
92
+ #
93
+ # @param [String] name The name of the command.
94
+ # @param [String] description The description of the command.
95
+ # @param [Hash{String => Hash}] options The options of the command.
96
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
97
+ # @param [Proc] block The block of the command.
98
+ # @param [:chat_input, :user, :message] type The type of the command.
99
+ # @param [Discorb::ApplicationCommand::Command, nil] parent The parent command.
100
+ #
70
101
  def initialize(name, description, options, guild_ids, block, type, parent)
71
102
  super(name, guild_ids, block, type)
72
103
  @description = description
@@ -85,7 +116,12 @@ module Discorb
85
116
  (@parent + " " + @name).strip
86
117
  end
87
118
 
119
+ #
120
+ # Converts the object to a hash.
88
121
  # @private
122
+ #
123
+ # @return [Hash] The hash represents the object.
124
+ #
89
125
  def to_hash
90
126
  options_payload = options.map do |name, value|
91
127
  ret = {
@@ -145,7 +181,16 @@ module Discorb
145
181
  # @return [String] The description of the command.
146
182
  attr_reader :description
147
183
 
184
+ #
185
+ # Initialize a new group command.
148
186
  # @private
187
+ #
188
+ # @param [String] name The name of the command.
189
+ # @param [String] description The description of the command.
190
+ # @param [Array<#to_s>] guild_ids The guild ids that the command is enabled in.
191
+ # @param [:chat_input, :user, :message] type The type of the command.
192
+ # @param [Discorb::Client] client The client of the command.
193
+ #
149
194
  def initialize(name, description, guild_ids, type, client)
150
195
  super(name, guild_ids, block, type)
151
196
  @description = description
@@ -196,13 +241,23 @@ module Discorb
196
241
  @name
197
242
  end
198
243
 
244
+ #
245
+ # Changes the self pointer to the given object.
199
246
  # @private
247
+ #
248
+ # @param [Object] instance The object to change to.
249
+ #
200
250
  def block_replace(instance)
201
251
  super
202
252
  @commands.each { |c| c.replace_block(instance) }
203
253
  end
204
254
 
255
+ #
256
+ # Converts the object to a hash.
205
257
  # @private
258
+ #
259
+ # @return [Hash] The hash represents the object.
260
+ #
206
261
  def to_hash
207
262
  options_payload = @commands.map do |command|
208
263
  if command.is_a?(SlashCommand)
@@ -240,7 +295,14 @@ module Discorb
240
295
  # @return [Array<Discorb::ApplicationCommand::Command::SlashCommand>] The subcommands of the command.
241
296
  attr_reader :commands
242
297
 
298
+ #
299
+ # Initialize a new subcommand group.
243
300
  # @private
301
+ #
302
+ # @param [String] name The name of the command.
303
+ # @param [String] description The description of the command.
304
+ # @param [Discorb::ApplicationCommand::Command::GroupCommand] parent The parent command.
305
+ # @param [Discorb::Client] client The client.
244
306
  def initialize(name, description, parent, client)
245
307
  super(name, description, [], 1, client)
246
308
 
@@ -160,7 +160,7 @@ module Discorb
160
160
  end
161
161
  end
162
162
  end
163
- @log.info "Successfully setup commands"
163
+ @logger.info "Successfully setup commands"
164
164
  end
165
165
  end
166
166
  end
@@ -29,7 +29,13 @@ 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
+ # Initializes a new instance of the Application class.
32
34
  # @private
35
+ #
36
+ # @param [Discorb::Client] client The client that instantiated the object.
37
+ # @param [Hash] data The data of the object.
38
+ #
33
39
  def initialize(client, data)
34
40
  @client = client
35
41
  @data = data
@@ -97,7 +103,13 @@ module Discorb
97
103
  # @return [Discorb::Application::Team::Member] The team's member.
98
104
  attr_reader :members
99
105
 
106
+ #
107
+ # Initializes a new instance of the Team class.
100
108
  # @private
109
+ #
110
+ # @param [Discorb::Client] client The client that instantiated the object.
111
+ # @param [Hash] data The data of the object.
112
+ #
101
113
  def initialize(client, data)
102
114
  @client = client
103
115
  @id = Snowflake.new(data[:id])
@@ -142,7 +154,9 @@ module Discorb
142
154
  # @!attribute [r] owner?
143
155
  # @return [Boolean] Whether the member is the team's owner.
144
156
 
145
- @membership_state = {
157
+ # @private
158
+ # @return [{Integer => Symbol}] The permission map.
159
+ MEMBERSHIP_STATE = {
146
160
  1 => :invited,
147
161
  2 => :accepted,
148
162
  }.freeze
@@ -153,7 +167,7 @@ module Discorb
153
167
  @team = team
154
168
  @user = client.users[data[:user][:id]] || User.new(client, data[:user])
155
169
  @team_id = Snowflake.new(data[:team_id])
156
- @membership_state = self.class.membership_state[data[:membership_state]]
170
+ @membership_state = MEMBERSHIP_STATE[data[:membership_state]]
157
171
  @permissions = data[:permissions].map(&:to_sym)
158
172
  end
159
173
 
@@ -176,11 +190,6 @@ module Discorb
176
190
  def ==(other)
177
191
  super || @user == other
178
192
  end
179
-
180
- class << self
181
- # @private
182
- attr_reader :membership_state
183
- end
184
193
  end
185
194
  end
186
195
  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
@@ -63,7 +69,10 @@ module Discorb
63
69
  # @!attribute [r] animated?
64
70
  # @return [false] For compatibility with {Asset}, always `false`.
65
71
 
72
+ #
73
+ # Initialize a new instance of the DefaultAvatar class.
66
74
  # @private
75
+ #
67
76
  def initialize(discriminator)
68
77
  @discriminator = discriminator.to_s.rjust(4, "0")
69
78
  end
@@ -7,15 +7,17 @@ module Discorb
7
7
  #
8
8
  # Represents a attachment file.
9
9
  #
10
- class Attachment < DiscordModel
10
+ class Attachment
11
11
  # @return [#read] The file content.
12
12
  attr_reader :io
13
- # @return [Discorb::Snowflake] The attachment id.
14
- attr_reader :id
15
13
  # @return [String] The attachment filename.
16
14
  attr_reader :filename
17
15
  # @return [String] The attachment content type.
18
16
  attr_reader :content_type
17
+ # @return [String] The attachment description.
18
+ attr_reader :description
19
+ # @return [Discorb::Snowflake] The attachment id.
20
+ attr_reader :id
19
21
  # @return [Integer] The attachment size in bytes.
20
22
  attr_reader :size
21
23
  # @return [String] The attachment url.
@@ -28,12 +30,44 @@ module Discorb
28
30
  # @return [Integer] The image width.
29
31
  # @return [nil] If the attachment is not an image.
30
32
  attr_reader :width
33
+ # @return [:client, :discord] The attachment was created by.
34
+ attr_reader :created_by
35
+ # @private
36
+ # @return [Boolean] Whether the attachment will be closed after it is sent.
37
+ attr_reader :will_close
31
38
 
32
39
  # @!attribute [r] image?
33
40
  # @return [Boolean] whether the file is an image.
34
41
 
42
+ #
43
+ # Creates a new attachment.
44
+ #
45
+ # @param [#read, String] source The Source of the attachment.
46
+ # @param [String] filename The filename of the attachment. If not set, path or object_id of the IO is used.
47
+ # @param [String] description The description of the attachment.
48
+ # @param [String] content_type The content type of the attachment. If not set, it is guessed from the filename.
49
+ # If failed to guess, it is set to `application/octet-stream`.
50
+ # @param [Boolean] will_close Whether the IO will be closed after the attachment is sent.
51
+ #
52
+ def initialize(source, filename = nil, description: nil, content_type: nil, will_close: true)
53
+ @io = if source.respond_to?(:read)
54
+ source
55
+ else
56
+ File.open(source, "rb")
57
+ end
58
+ @filename = filename || (@io.respond_to?(:path) ? @io.path : @io.object_id)
59
+ @description = description
60
+ @content_type = content_type || MIME::Types.type_for(@filename.to_s)[0].to_s
61
+ @content_type = "application/octet-stream" if @content_type == ""
62
+ @will_close = will_close
63
+ @created_by = :client
64
+ end
65
+
66
+ #
67
+ # Initializes the object from a hash.
35
68
  # @private
36
- def initialize(data)
69
+ #
70
+ def initialize_hash(data)
37
71
  @id = Snowflake.new(data[:id])
38
72
  @filename = data[:filename]
39
73
  @content_type = data[:content_type]
@@ -42,37 +76,29 @@ module Discorb
42
76
  @proxy_url = data[:proxy_url]
43
77
  @height = data[:height]
44
78
  @width = data[:width]
79
+ @created_by = :discord
45
80
  end
46
81
 
47
82
  def image?
48
83
  @content_type.start_with? "image/"
49
84
  end
50
- end
51
85
 
52
- #
53
- # Represents a file to send as an attachment.
54
- #
55
- class File
56
- # @return [#read] The IO of the file.
57
- attr_accessor :io
58
- # @return [String] The filename of the file. If not set, path or object_id of the IO is used.
59
- attr_accessor :filename
60
- # @return [String] The content type of the file. If not set, it is guessed from the filename.
61
- attr_accessor :content_type
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
62
93
 
63
94
  #
64
- # Creates a new file from IO.
65
- #
66
- # @param [#read] io The IO of the file.
67
- # @param [String] filename The filename of the file. If not set, path or object_id of the IO is used.
68
- # @param [String] content_type The content type of the file. If not set, it is guessed from the filename.
69
- # If failed to guess, it is set to `application/octet-stream`.
95
+ # Creates a new file from a hash.
96
+ # @private
70
97
  #
71
- def initialize(io, filename = nil, content_type: nil)
72
- @io = io
73
- @filename = filename || (io.respond_to?(:path) ? io.path : io.object_id)
74
- @content_type = content_type || MIME::Types.type_for(@filename.to_s)[0].to_s
75
- @content_type = "application/octet-stream" if @content_type == ""
98
+ def self.from_hash(data)
99
+ inst = allocate
100
+ inst.initialize_hash(data)
101
+ inst
76
102
  end
77
103
 
78
104
  #
@@ -82,16 +108,12 @@ module Discorb
82
108
  # @param [String] filename The filename of the file. object_id of the string is used if not set.
83
109
  # @param [String] content_type The content type of the file. If not set, it is guessed from the filename.
84
110
  #
85
- # @return [File] The new file.
111
+ # @return [Discorb::Attachment] The new file.
86
112
  #
87
- def self.from_string(string, filename: nil, content_type: nil)
113
+ def self.from_string(string, filename = nil, content_type: nil, description: nil)
88
114
  io = StringIO.new(string)
89
115
  filename ||= string.object_id.to_s + ".txt"
90
- new(io, filename, content_type: content_type)
91
- end
92
-
93
- def inspect
94
- "#<#{self.class} filename=#{@filename} content_type=#{@content_type}>"
116
+ new(io, filename, content_type: content_type, description: description, will_close: true)
95
117
  end
96
118
  end
97
119
  end