Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Support timeouts #113

Merged
merged 2 commits into from Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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