Skip to content

Commit

Permalink
feat: Support timeouts (#113)
Browse files Browse the repository at this point in the history
  • Loading branch information
swarley committed Jan 7, 2022
1 parent f9a94c9 commit a1083b0
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 9 deletions.
8 changes: 5 additions & 3 deletions lib/discordrb/api/server.rb
Expand Up @@ -140,7 +140,8 @@ def resolve_members(token, server_id, limit, after = nil)

# Update a user properties
# https://discord.com/developers/docs/resources/guild#modify-guild-member
def update_member(token, server_id, user_id, nick: nil, roles: nil, mute: nil, deaf: nil, channel_id: nil, reason: nil)
def update_member(token, server_id, user_id, nick: :undef, roles: :undef, mute: :undef, deaf: :undef, channel_id: :undef,
communication_disabled_until: :undef, reason: nil)
Discordrb::API.request(
:guilds_sid_members_uid,
server_id,
Expand All @@ -150,8 +151,9 @@ def update_member(token, server_id, user_id, nick: nil, roles: nil, mute: nil, d
nick: nick,
mute: mute,
deaf: deaf,
channel_id: channel_id
}.compact.to_json,
channel_id: channel_id,
communication_disabled_until: communication_disabled_until
}.reject { |_, v| v == :undef }.to_json,
Authorization: token,
content_type: :json,
'X-Audit-Log-Reason': reason
Expand Down
1 change: 1 addition & 0 deletions lib/discordrb/bot.rb
Expand Up @@ -1047,6 +1047,7 @@ def update_guild_member(data)
member.update_roles(data['roles'])
member.update_nick(data['nick'])
member.update_boosting_since(data['premium_since'])
member.update_communication_disabled_until(data['communication_disabled_until'])
end

# Internal handler for GUILD_MEMBER_DELETE
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/commands/container.rb
Expand Up @@ -86,7 +86,7 @@ def remove_command(name)
# Adds all commands from another container into this one. Existing commands will be overwritten.
# @param container [Module] A module that `extend`s {CommandContainer} from which the commands will be added.
def include_commands(container)
handlers = container.instance_variable_get '@commands'
handlers = container.instance_variable_get :@commands
return unless handlers

@commands ||= {}
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/commands/rate_limiter.rb
Expand Up @@ -125,7 +125,7 @@ def clean
# Adds all the buckets from another RateLimiter onto this one.
# @param limiter [Module] Another {RateLimiter} module
def include_buckets(limiter)
buckets = limiter.instance_variable_get('@buckets') || {}
buckets = limiter.instance_variable_get(:@buckets) || {}
@buckets ||= {}
@buckets.merge! buckets
end
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/container.rb
Expand Up @@ -632,7 +632,7 @@ def add_handler(handler)
# @param container [Module] A module that `extend`s {EventContainer} from which the handlers will be added.
def include_events(container)
application_command_handlers = container.instance_variable_get(:@application_commands)
handlers = container.instance_variable_get '@event_handlers'
handlers = container.instance_variable_get :@event_handlers
return unless handlers || application_command_handlers

@event_handlers ||= {}
Expand Down
32 changes: 32 additions & 0 deletions lib/discordrb/data/member.rb
Expand Up @@ -18,6 +18,10 @@ module MemberAttributes

# @return [Server] the server this member is on.
attr_reader :server

# @return [Time] When the user's timeout will expire.
attr_reader :communication_disabled_until
alias_method :timeout, :communication_disabled_until
end

# A member is a user on a server. It differs from regular users in that it has roles, voice statuses and things like
Expand Down Expand Up @@ -70,6 +74,8 @@ def initialize(data, server, bot)
@nick = data['nick']
@joined_at = data['joined_at'] ? Time.parse(data['joined_at']) : nil
@boosting_since = data['premium_since'] ? Time.parse(data['premium_since']) : nil
timeout_until = data['communication_disabled_until']
@communication_disabled_until = timeout_until ? Time.parse(timeout_until) : nil
end

# @return [Server] the server this member is on.
Expand Down Expand Up @@ -116,6 +122,24 @@ def roles=(role)
set_roles(role)
end

# Check if the current user has communication disabled.
# @return [true, false]
def communication_disabled?
!@communication_disabled_until.nil? && @communication_disabled_until > Time.now
end

alias_method :timeout?, :communication_disabled?

# Set a user's timeout duration, or remove it by setting the timeout to `nil`.
# @param timeout_until [Time, nil] When the timeout will end.
def communication_disabled_until=(timeout_until)
raise ArgumentError, 'A time out cannot exceed 28 days' if timeout_until && timeout_until > (Time.now + 2_419_200)

API::Server.update_member(@bot.token, @server_id, @user.id, communication_disabled_until: timeout_until.iso8601)
end

alias_method :timeout=, :communication_disabled_until=

# Bulk sets a member's roles.
# @param role [Role, Array<Role>] The role(s) to set.
# @param reason [String] The reason the user's roles are being changed.
Expand Down Expand Up @@ -296,6 +320,12 @@ def update_boosting_since(time)
@boosting_since = time
end

# @!visibility private
def update_communication_disabled_until(time)
time = time ? Time.parse(time) : nil
@communication_disabled_until = time
end

# Update this member
# @note For internal use only.
# @!visibility private
Expand All @@ -306,6 +336,8 @@ def update_data(data)
@deaf = data['deaf'] if data.key?('deaf')

@joined_at = Time.parse(data['joined_at']) if data['joined_at']
timeout_until = data['communication_disabled_until']
@communication_disabled_until = timeout_until ? Time.parse(timeout_until) : nil
end

include PermissionCalculator
Expand Down
2 changes: 1 addition & 1 deletion lib/discordrb/errors.rb
Expand Up @@ -87,7 +87,7 @@ def flatten_errors(err, prev_key = nil)
# rubocop:disable Naming/MethodName
def self.Code(code)
classy = Class.new(CodeError)
classy.instance_variable_set('@code', code)
classy.instance_variable_set(:@code, code)

@code_classes ||= {}
@code_classes[code] = classy
Expand Down
4 changes: 2 additions & 2 deletions spec/permissions_spec.rb
Expand Up @@ -31,8 +31,8 @@
it 'sets an attribute for each flag' do
expect(
[
subject.instance_variable_get('@foo'),
subject.instance_variable_get('@bar')
subject.instance_variable_get(:@foo),
subject.instance_variable_get(:@bar)
]
).to eq [false, false]
end
Expand Down

0 comments on commit a1083b0

Please sign in to comment.