onyxcord 1.1.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.
- checksums.yaml +7 -0
- data/.devcontainer/Dockerfile +13 -0
- data/.devcontainer/devcontainer.json +29 -0
- data/.devcontainer/postcreate.sh +4 -0
- data/.github/CONTRIBUTING.md +13 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/pull_request_template.md +37 -0
- data/.github/workflows/ci.yml +78 -0
- data/.github/workflows/codeql.yml +65 -0
- data/.github/workflows/deploy.yml +54 -0
- data/.github/workflows/release.yml +51 -0
- data/.gitignore +16 -0
- data/.markdownlint.json +4 -0
- data/.overcommit.yml +7 -0
- data/.rspec +2 -0
- data/.rubocop.yml +129 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +305 -0
- data/Rakefile +17 -0
- data/bin/console +15 -0
- data/bin/setup +7 -0
- data/lib/onyxcord/allowed_mentions.rb +43 -0
- data/lib/onyxcord/api/application.rb +316 -0
- data/lib/onyxcord/api/channel.rb +700 -0
- data/lib/onyxcord/api/interaction.rb +67 -0
- data/lib/onyxcord/api/invite.rb +44 -0
- data/lib/onyxcord/api/server.rb +775 -0
- data/lib/onyxcord/api/user.rb +158 -0
- data/lib/onyxcord/api/webhook.rb +163 -0
- data/lib/onyxcord/api.rb +335 -0
- data/lib/onyxcord/await.rb +51 -0
- data/lib/onyxcord/bot.rb +1971 -0
- data/lib/onyxcord/cache.rb +326 -0
- data/lib/onyxcord/colour_rgb.rb +43 -0
- data/lib/onyxcord/commands/command_bot.rb +511 -0
- data/lib/onyxcord/commands/container.rb +112 -0
- data/lib/onyxcord/commands/events.rb +11 -0
- data/lib/onyxcord/commands/parser.rb +327 -0
- data/lib/onyxcord/commands/rate_limiter.rb +144 -0
- data/lib/onyxcord/configuration.rb +125 -0
- data/lib/onyxcord/container.rb +988 -0
- data/lib/onyxcord/data/activity.rb +271 -0
- data/lib/onyxcord/data/application.rb +341 -0
- data/lib/onyxcord/data/attachment.rb +91 -0
- data/lib/onyxcord/data/audit_logs.rb +438 -0
- data/lib/onyxcord/data/avatar_decoration.rb +26 -0
- data/lib/onyxcord/data/call.rb +22 -0
- data/lib/onyxcord/data/channel.rb +1355 -0
- data/lib/onyxcord/data/channel_tag.rb +69 -0
- data/lib/onyxcord/data/collectibles.rb +47 -0
- data/lib/onyxcord/data/component.rb +583 -0
- data/lib/onyxcord/data/embed.rb +258 -0
- data/lib/onyxcord/data/emoji.rb +123 -0
- data/lib/onyxcord/data/install_params.rb +24 -0
- data/lib/onyxcord/data/integration.rb +144 -0
- data/lib/onyxcord/data/interaction.rb +1141 -0
- data/lib/onyxcord/data/invite.rb +137 -0
- data/lib/onyxcord/data/member.rb +528 -0
- data/lib/onyxcord/data/message.rb +612 -0
- data/lib/onyxcord/data/message_activity.rb +41 -0
- data/lib/onyxcord/data/overwrite.rb +109 -0
- data/lib/onyxcord/data/poll.rb +365 -0
- data/lib/onyxcord/data/primary_server.rb +60 -0
- data/lib/onyxcord/data/profile.rb +79 -0
- data/lib/onyxcord/data/reaction.rb +64 -0
- data/lib/onyxcord/data/recipient.rb +34 -0
- data/lib/onyxcord/data/role.rb +449 -0
- data/lib/onyxcord/data/role_connection_data.rb +69 -0
- data/lib/onyxcord/data/role_subscription.rb +41 -0
- data/lib/onyxcord/data/scheduled_event.rb +513 -0
- data/lib/onyxcord/data/server.rb +1614 -0
- data/lib/onyxcord/data/server_preview.rb +68 -0
- data/lib/onyxcord/data/snapshot.rb +112 -0
- data/lib/onyxcord/data/team.rb +98 -0
- data/lib/onyxcord/data/timestamp.rb +69 -0
- data/lib/onyxcord/data/user.rb +324 -0
- data/lib/onyxcord/data/voice_region.rb +46 -0
- data/lib/onyxcord/data/voice_state.rb +41 -0
- data/lib/onyxcord/data/webhook.rb +238 -0
- data/lib/onyxcord/data.rb +57 -0
- data/lib/onyxcord/errors.rb +246 -0
- data/lib/onyxcord/event_executor.rb +80 -0
- data/lib/onyxcord/events/await.rb +48 -0
- data/lib/onyxcord/events/bans.rb +60 -0
- data/lib/onyxcord/events/channels.rb +225 -0
- data/lib/onyxcord/events/generic.rb +129 -0
- data/lib/onyxcord/events/guilds.rb +269 -0
- data/lib/onyxcord/events/integrations.rb +100 -0
- data/lib/onyxcord/events/interactions.rb +624 -0
- data/lib/onyxcord/events/invites.rb +127 -0
- data/lib/onyxcord/events/lifetime.rb +31 -0
- data/lib/onyxcord/events/members.rb +110 -0
- data/lib/onyxcord/events/message.rb +399 -0
- data/lib/onyxcord/events/polls.rb +118 -0
- data/lib/onyxcord/events/presence.rb +131 -0
- data/lib/onyxcord/events/raw.rb +74 -0
- data/lib/onyxcord/events/reactions.rb +218 -0
- data/lib/onyxcord/events/roles.rb +87 -0
- data/lib/onyxcord/events/scheduled_events.rb +171 -0
- data/lib/onyxcord/events/threads.rb +100 -0
- data/lib/onyxcord/events/typing.rb +73 -0
- data/lib/onyxcord/events/voice_server_update.rb +48 -0
- data/lib/onyxcord/events/voice_state_update.rb +106 -0
- data/lib/onyxcord/events/webhooks.rb +65 -0
- data/lib/onyxcord/gateway.rb +890 -0
- data/lib/onyxcord/id_object.rb +39 -0
- data/lib/onyxcord/light/data.rb +62 -0
- data/lib/onyxcord/light/integrations.rb +73 -0
- data/lib/onyxcord/light/light_bot.rb +58 -0
- data/lib/onyxcord/light.rb +8 -0
- data/lib/onyxcord/logger.rb +120 -0
- data/lib/onyxcord/message_components.rb +70 -0
- data/lib/onyxcord/paginator.rb +60 -0
- data/lib/onyxcord/permissions.rb +255 -0
- data/lib/onyxcord/rate_limiter/gateway.rb +42 -0
- data/lib/onyxcord/rate_limiter/rest.rb +89 -0
- data/lib/onyxcord/version.rb +7 -0
- data/lib/onyxcord/voice/encoder.rb +115 -0
- data/lib/onyxcord/voice/network.rb +380 -0
- data/lib/onyxcord/voice/opcodes.rb +29 -0
- data/lib/onyxcord/voice/sodium.rb +157 -0
- data/lib/onyxcord/voice/timer.rb +19 -0
- data/lib/onyxcord/voice/voice_bot.rb +386 -0
- data/lib/onyxcord/webhooks.rb +14 -0
- data/lib/onyxcord/websocket.rb +62 -0
- data/lib/onyxcord.rb +180 -0
- data/onyxcord-webhooks.gemspec +30 -0
- data/onyxcord.gemspec +50 -0
- metadata +421 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OnyxCord
|
|
4
|
+
# A scheduled event for an occurrence on a server.
|
|
5
|
+
class ScheduledEvent
|
|
6
|
+
include IDObject
|
|
7
|
+
|
|
8
|
+
# Map of status types.
|
|
9
|
+
STATUSES = {
|
|
10
|
+
scheduled: 1,
|
|
11
|
+
active: 2,
|
|
12
|
+
completed: 3,
|
|
13
|
+
canceled: 4
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
# Map of entity types.
|
|
17
|
+
ENTITY_TYPES = {
|
|
18
|
+
stage: 1,
|
|
19
|
+
voice: 2,
|
|
20
|
+
external: 3
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
# @return [String] the name of the scheduled event.
|
|
24
|
+
attr_reader :name
|
|
25
|
+
|
|
26
|
+
# @return [Integer] the current status of the scheduled event.
|
|
27
|
+
attr_reader :status
|
|
28
|
+
|
|
29
|
+
# @return [Time, nil] the time at when the scheduled event will end.
|
|
30
|
+
attr_reader :end_time
|
|
31
|
+
|
|
32
|
+
# @return [String, nil] the external location of the scheduled event.
|
|
33
|
+
attr_reader :location
|
|
34
|
+
|
|
35
|
+
# @return [String, nil] the image hash of the scheduled event's cover image.
|
|
36
|
+
attr_reader :cover_id
|
|
37
|
+
|
|
38
|
+
# @return [Integer, nil] the ID of the entity associated with the scheduled event.
|
|
39
|
+
attr_reader :entity_id
|
|
40
|
+
|
|
41
|
+
# @return [Time] the time at when the scheduled event has been scheduled to start.
|
|
42
|
+
attr_reader :start_time
|
|
43
|
+
|
|
44
|
+
# @return [Integer] the type of the entity that is assoicated with the scheduled event.
|
|
45
|
+
attr_reader :entity_type
|
|
46
|
+
|
|
47
|
+
# @return [String, nil] the description of the scheduled event. Between 1-1000 characters.
|
|
48
|
+
attr_reader :description
|
|
49
|
+
|
|
50
|
+
# @return [RecurrenceRule, nil] the definition for how often this scheduled event should repeat.
|
|
51
|
+
attr_reader :recurrence_rule
|
|
52
|
+
|
|
53
|
+
# @!visibility private
|
|
54
|
+
def initialize(data, server, bot)
|
|
55
|
+
@bot = bot
|
|
56
|
+
@server = server
|
|
57
|
+
@id = data['id'].to_i
|
|
58
|
+
@server_id = data['guild_id']&.to_i
|
|
59
|
+
@user_count = data['user_count']
|
|
60
|
+
@creator_id = data['creator_id']&.to_i
|
|
61
|
+
bot.ensure_user(data['creator']) if data['creator']
|
|
62
|
+
|
|
63
|
+
# Set the rest of the mutable attributes in the method.
|
|
64
|
+
update_data(data)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Get the server that the scheduled event originates from.
|
|
68
|
+
# @return [Server] The server that the scheduled event originates from.
|
|
69
|
+
def server
|
|
70
|
+
@server ||= @bot.server(@server_id)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Get the user who was responsible for the creation of the scheduled event.
|
|
74
|
+
# @return [User, nil] The user who was responsible for the creation of the scheduled event.
|
|
75
|
+
def creator
|
|
76
|
+
@bot.user(@creator_id) if @creator_id
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Get the channel in which the scheduled event will be hosted. This can be `nil` if the type is external.
|
|
80
|
+
# @return [Channel, nil] The channel where the scheduled event will take place, or `nil` if there isn't one.
|
|
81
|
+
def channel
|
|
82
|
+
@bot.channel(@channel_id) if @channel_id
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Get a URL that will display an embed in the Discord client containing information about the scheduled event.
|
|
86
|
+
# @return [String] A URL that will display an embed containing a brief overview about the scheduled event's information.
|
|
87
|
+
def url
|
|
88
|
+
"https://discord.com/events/#{@server_id}/#{@id}"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Utility method to get a scheduled event's cover image URL.
|
|
92
|
+
# @param format [String] The URL will default to `webp`. You can otherwise specify one of `jpg` or `png` to override this.
|
|
93
|
+
# @param size [Integer, nil] The URL will default to `4096`. You can otherwise specify any number that's a power of two to override this.
|
|
94
|
+
# @return [String, nil] The URL to the scheduled event's cover image, or `nil` if the scheduled event doesn't have a cover image set.
|
|
95
|
+
def cover_url(format: 'webp', size: 4096)
|
|
96
|
+
API.scheduled_event_cover_url(@id, @cover_id, format, size) if @cover_id
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# @!method scheduled?
|
|
100
|
+
# @return [true, false] whether the scheduled event has been scheduled to take place.
|
|
101
|
+
# @!method active?
|
|
102
|
+
# @return [true, false] whether the scheduled event is currently taking place.
|
|
103
|
+
# @!method completed?
|
|
104
|
+
# @return [true, false] whether the scheduled event has finished taking place.
|
|
105
|
+
# @!method canceled?
|
|
106
|
+
# @return [true, false] whether the scheduled event has been canceled.
|
|
107
|
+
STATUSES.each do |name, value|
|
|
108
|
+
define_method("#{name}?") do
|
|
109
|
+
@status == value
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# @!method stage?
|
|
114
|
+
# @return [true, false] whether the scheduled event will take place in a stage channel.
|
|
115
|
+
# @!method voice?
|
|
116
|
+
# @return [true, false] whether the scheduled event will take place in a voice channel.
|
|
117
|
+
# @!method external?
|
|
118
|
+
# @return [true, false] whether the scheduled event will take place in an external location.
|
|
119
|
+
ENTITY_TYPES.each do |name, value|
|
|
120
|
+
define_method("#{name}?") do
|
|
121
|
+
@entity_type == value
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Start the scheduled event.
|
|
126
|
+
# @param reason [String, nil] The reason for starting the event.
|
|
127
|
+
# @return [nil]
|
|
128
|
+
def start(reason: nil)
|
|
129
|
+
raise 'cannot start this event' unless scheduled?
|
|
130
|
+
|
|
131
|
+
modify(status: STATUSES[:active], reason: reason)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# Cancel the scheduled event. This cannot be undone.
|
|
135
|
+
# @param reason [String, nil] The reason for cancelling the event.
|
|
136
|
+
# @return [nil]
|
|
137
|
+
def cancel(reason: nil)
|
|
138
|
+
raise 'cannot cancel this event' unless scheduled?
|
|
139
|
+
|
|
140
|
+
modify(status: STATUSES[:canceled], reason: reason)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# End the scheduled event. This cannot be undone.
|
|
144
|
+
# @param reason [String, nil] The reason for ending the event.
|
|
145
|
+
# @return [nil]
|
|
146
|
+
def end(reason: nil)
|
|
147
|
+
raise 'cannot end this event' unless active?
|
|
148
|
+
|
|
149
|
+
modify(status: STATUSES[:completed], reason: reason)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Edit the properties of the scheduled event.
|
|
153
|
+
# @param name [String] The new 1-100 character name of the scheduled event.
|
|
154
|
+
# @param channel [Integer, Channel, String, nil] The new channel of the scheduled event.
|
|
155
|
+
# @param location [String, nil] The new location of the scheduled event.
|
|
156
|
+
# @param start_time [Time] The new start time of the scheduled event.
|
|
157
|
+
# @param end_time [Time] The new end time of the scheduled event.
|
|
158
|
+
# @param description [String, nil] The new 1-100 character description of the scheduled event.
|
|
159
|
+
# @param entity_type [Integer, Symbol] The new entity type of the scheduled event.
|
|
160
|
+
# @param status [Integer, Symbol] The new status of the scheduled event.
|
|
161
|
+
# @param cover [File, #read] The new cover image of the scheduled event.
|
|
162
|
+
# @param recurrence_rule [#to_h, nil] The new recurrence rule of the scheduled event.
|
|
163
|
+
# @param reason [String, nil] The audit log reason for updating the scheduled event.
|
|
164
|
+
# @yieldparam builder [RecurrenceRule::Builder] An optional reccurence rule builder.
|
|
165
|
+
# @return [nil]
|
|
166
|
+
def modify(
|
|
167
|
+
name: :undef, channel: :undef, location: :undef, start_time: :undef, end_time: :undef,
|
|
168
|
+
description: :undef, entity_type: :undef, status: :undef, cover: :undef,
|
|
169
|
+
recurrence_rule: :undef, reason: nil
|
|
170
|
+
)
|
|
171
|
+
data = {
|
|
172
|
+
name: name,
|
|
173
|
+
channel_id: channel == :undef ? channel : channel&.resolve_id,
|
|
174
|
+
entity_metadata: location == :undef ? location : { location: },
|
|
175
|
+
scheduled_end_time: end_time == :undef ? end_time : end_time&.iso8601,
|
|
176
|
+
scheduled_start_time: start_time == :undef ? start_time : start_time&.iso8601,
|
|
177
|
+
description: description,
|
|
178
|
+
entity_type: entity_type == :undef ? entity_type : ENTITY_TYPES[type] || type,
|
|
179
|
+
status: status == :undef ? status : STATUSES[status] || status,
|
|
180
|
+
image: cover.respond_to?(:read) ? OnyxCord.encode64(cover) : cover,
|
|
181
|
+
recurrence_rule: recurrence_rule == :undef ? recurrence_rule : recurrence_rule&.to_h,
|
|
182
|
+
reason: reason
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if block_given?
|
|
186
|
+
yield((builder = RecurrenceRule::Builder.new))
|
|
187
|
+
raise 'An `interval` must be provided' unless builder.interval?
|
|
188
|
+
raise 'A `frequency` must be provided' unless builder.frequency?
|
|
189
|
+
raise 'A `start_time` must be provided' unless builder.start_time?
|
|
190
|
+
|
|
191
|
+
builder[:recurrence_rule] = builder.to_h
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
update_data(JSON.parse(API::Server.update_scheduled_event(@bot.token, @server_id, @id, **data)))
|
|
195
|
+
nil
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
# Delete the scheduled event. Use this with caution, as it cannot be undone.
|
|
199
|
+
# @param reason [String, nil] The reason to show in the audit log for deleting the scheduled event.
|
|
200
|
+
# @return [nil]
|
|
201
|
+
def delete(reason: nil)
|
|
202
|
+
API::Server.delete_scheduled_event(@bot.token, @server_id, @id, reason: reason)
|
|
203
|
+
@server&.delete_scheduled_event(@id)
|
|
204
|
+
nil
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# Get the total amount of users who are subscribed to the scheduled event.
|
|
208
|
+
# @return [Integer] The total amount of users who are currently subscribed to the scheduled event.
|
|
209
|
+
def user_count
|
|
210
|
+
@user_count ||= JSON.parse(API::Server.get_scheduled_event(@bot.token, @server_id, @id, with_user_count: true))['user_count']
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
alias_method :subscriber_count, :user_count
|
|
214
|
+
|
|
215
|
+
# Get the users who are subscribed to the scheduled event.
|
|
216
|
+
# @param limit [Integer, nil] The limit (`nil` for no limit) of how many subscribers to return.
|
|
217
|
+
# @param member [true, false] Whether to return subscribers as server members, when applicable.
|
|
218
|
+
# @return [Array<User, Member>] the users or members that have subscribed to the scheduled event.
|
|
219
|
+
def users(limit: 100, member: false)
|
|
220
|
+
get_users = proc do |fetch_limit, after = nil|
|
|
221
|
+
response = JSON.parse(API::Server.get_scheduled_event_users(@bot.token, @server_id, @id, limit: fetch_limit, with_member: member, after: after))
|
|
222
|
+
response.map { |data| data['member'] ? Member.new(data['member'], server, @bot).tap { |member| server&.cache_member(member) } : User.new(data['user'], @bot) }
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Can be done without pagination.
|
|
226
|
+
return get_users.call(limit) if limit && limit <= 100
|
|
227
|
+
|
|
228
|
+
paginator = Paginator.new(limit, :down) do |last_page|
|
|
229
|
+
if last_page && last_page.count < 100
|
|
230
|
+
[]
|
|
231
|
+
else
|
|
232
|
+
get_users.call(100, last_page&.last&.id)
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
paginator.to_a
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
alias_method :subscribers, :users
|
|
240
|
+
|
|
241
|
+
# @!visibility private
|
|
242
|
+
def increment_user_count
|
|
243
|
+
@user_count += 1 if @user_count
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
# @!visibility private
|
|
247
|
+
def deincrement_user_count
|
|
248
|
+
@user_count -= 1 if @user_count
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# @!visibility private
|
|
252
|
+
def inspect
|
|
253
|
+
"<ScheduledEvent id=#{@id} name=\"#{@name}\" start_time=#{@start_time.inspect} end_time=#{@end_time.inspect}>"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# @!visibility private
|
|
257
|
+
def update_data(new_data)
|
|
258
|
+
@name = new_data['name']
|
|
259
|
+
@status = new_data['status']
|
|
260
|
+
@cover_id = new_data['image']
|
|
261
|
+
@entity_type = new_data['entity_type']
|
|
262
|
+
@description = new_data['description']
|
|
263
|
+
@entity_id = new_data['entity_id']&.to_i
|
|
264
|
+
@channel_id = new_data['channel_id']&.to_i
|
|
265
|
+
@start_time = Time.iso8601(new_data['scheduled_start_time'])
|
|
266
|
+
@location = new_data['entity_metadata'] ? new_data['entity_metadata']['location'] : nil
|
|
267
|
+
@end_time = new_data['scheduled_end_time'] ? Time.iso8601(new_data['scheduled_end_time']) : nil
|
|
268
|
+
@recurrence_rule = new_data['recurrence_rule'] ? RecurrenceRule.new(new_data['recurrence_rule'], @bot) : nil
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
# Represents how frequently a scheduled event will repeat.
|
|
272
|
+
class RecurrenceRule
|
|
273
|
+
# Map of weekdays.
|
|
274
|
+
WEEKDAYS = {
|
|
275
|
+
monday: 0,
|
|
276
|
+
tuesday: 1,
|
|
277
|
+
wednesday: 2,
|
|
278
|
+
thursday: 3,
|
|
279
|
+
friday: 4,
|
|
280
|
+
saturday: 5,
|
|
281
|
+
sunday: 6
|
|
282
|
+
}.freeze
|
|
283
|
+
|
|
284
|
+
# Map of frequencies.
|
|
285
|
+
FREQUENCIES = {
|
|
286
|
+
yearly: 0,
|
|
287
|
+
monthly: 1,
|
|
288
|
+
weekly: 2,
|
|
289
|
+
daily: 3
|
|
290
|
+
}.freeze
|
|
291
|
+
|
|
292
|
+
# Map of months.
|
|
293
|
+
MONTHS = {
|
|
294
|
+
january: 1,
|
|
295
|
+
february: 2,
|
|
296
|
+
march: 3,
|
|
297
|
+
april: 4,
|
|
298
|
+
may: 5,
|
|
299
|
+
june: 6,
|
|
300
|
+
july: 7,
|
|
301
|
+
august: 8,
|
|
302
|
+
september: 9,
|
|
303
|
+
october: 10,
|
|
304
|
+
november: 11,
|
|
305
|
+
december: 12
|
|
306
|
+
}.freeze
|
|
307
|
+
|
|
308
|
+
# @return [Integer, nil] the amount of times that the event can recur before stopping.
|
|
309
|
+
attr_reader :count
|
|
310
|
+
|
|
311
|
+
# @return [Array<Integer>] the specific months the event can recur on.
|
|
312
|
+
attr_reader :by_month
|
|
313
|
+
|
|
314
|
+
# @return [Time, nil] the time at when the reccurence interval will end.
|
|
315
|
+
attr_reader :end_time
|
|
316
|
+
|
|
317
|
+
# @return [Time] the time at when the reccurence interval will start.
|
|
318
|
+
attr_reader :start_time
|
|
319
|
+
|
|
320
|
+
# @return [Array<Integer>] the specific days of the week the event can recur on.
|
|
321
|
+
attr_reader :by_weekday
|
|
322
|
+
|
|
323
|
+
# @return [Integer] The spacing between the events, defined by the frequency.
|
|
324
|
+
attr_reader :interval
|
|
325
|
+
|
|
326
|
+
# @return [Integer] how often the reccurence interval will occur, e.g. yearly, monthly.
|
|
327
|
+
attr_reader :frequency
|
|
328
|
+
|
|
329
|
+
# @return [Array<Integer>] the specific days within the year (1-364) to recur on.
|
|
330
|
+
attr_reader :by_year_day
|
|
331
|
+
|
|
332
|
+
# @return [Array<WeeklyDay>] the specific days within a specific week to recur on.
|
|
333
|
+
attr_reader :by_n_weekday
|
|
334
|
+
|
|
335
|
+
# @return [Array<Integer>] the specific dates within a month to recur on.
|
|
336
|
+
attr_reader :by_month_day
|
|
337
|
+
|
|
338
|
+
# @!visibility private
|
|
339
|
+
def initialize(data, bot)
|
|
340
|
+
@bot = bot
|
|
341
|
+
@count = data['count']
|
|
342
|
+
@by_month = data['by_month'] || []
|
|
343
|
+
@end_time = Time.iso8601(data['end']) if data['end']
|
|
344
|
+
@start_time = Time.iso8601(data['start']) if data['start']
|
|
345
|
+
@by_weekday = data['by_weekday'] || []
|
|
346
|
+
@interval = data['interval']
|
|
347
|
+
@frequency = data['frequency']
|
|
348
|
+
@by_year_day = data['by_year_day'] || []
|
|
349
|
+
@by_n_weekday = data['by_n_weekday']&.map { |day| WeeklyDay.new(day, @bot) } || []
|
|
350
|
+
@by_month_day = data['by_month_day'] || []
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# @!visibility private
|
|
354
|
+
def to_h
|
|
355
|
+
{
|
|
356
|
+
count: @count,
|
|
357
|
+
interval: @interval,
|
|
358
|
+
frequency: @frequency,
|
|
359
|
+
end: @end_time&.iso8601,
|
|
360
|
+
start: @start_time&.iso8601,
|
|
361
|
+
by_month: @by_month.any? ? @by_month : nil,
|
|
362
|
+
by_weekday: @by_weekday.any? ? @by_weekday : nil,
|
|
363
|
+
by_year_day: @by_year_day.any? ? @by_year_day : nil,
|
|
364
|
+
by_month_day: @by_month_day.any? ? @by_month_day : nil,
|
|
365
|
+
by_n_weekday: @by_n_weekday.any? ? @by_n_weekday.map(&:to_h) : nil
|
|
366
|
+
}
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# @!method yearly?
|
|
370
|
+
# @return [true, false] whether the event repeat on a yearly basis.
|
|
371
|
+
# @!method monthly?
|
|
372
|
+
# @return [true, false] whether the event repeat on a monthly basis.
|
|
373
|
+
# @!method weekly?
|
|
374
|
+
# @return [true, false] whether the event repeat on a weekly basis.
|
|
375
|
+
# @!method daily?
|
|
376
|
+
# @return [true, false] whether the event repeat on a daily basis.
|
|
377
|
+
FREQUENCIES.each do |name, value|
|
|
378
|
+
define_method("#{name}?") do
|
|
379
|
+
@frequency == value
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
# The specific day within a specific week to recur on.
|
|
384
|
+
class WeeklyDay
|
|
385
|
+
# @return [Integer] the day (0-6) of the week to recur on.
|
|
386
|
+
attr_reader :day
|
|
387
|
+
|
|
388
|
+
# @return [Integer] the week (1-5) to recur on in the month.
|
|
389
|
+
attr_reader :week
|
|
390
|
+
|
|
391
|
+
# @!visibility private
|
|
392
|
+
def initialize(data, bot)
|
|
393
|
+
@bot = bot
|
|
394
|
+
@week = data['n']
|
|
395
|
+
@day = data['day']
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
# @!visibility private
|
|
399
|
+
def to_h
|
|
400
|
+
{ n: @week, day: @day }
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# @!method monday?
|
|
404
|
+
# @return [true, false] whether the day within the week is a monday.
|
|
405
|
+
# @!method tuesday?
|
|
406
|
+
# @return [true, false] whether the day within the week is a tuesday.
|
|
407
|
+
# @!method wednesday?
|
|
408
|
+
# @return [true, false] whether the day within the week is a wednesday.
|
|
409
|
+
# @!method thursday?
|
|
410
|
+
# @return [true, false] whether the day within the week is a thursday.
|
|
411
|
+
# @!method friday?
|
|
412
|
+
# @return [true, false] whether the day within the week is a friday.
|
|
413
|
+
# @!method saturday?
|
|
414
|
+
# @return [true, false] whether the day within the week is a saturday.
|
|
415
|
+
# @!method sunday?
|
|
416
|
+
# @return [true, false] whether the day within the week is a sunday.
|
|
417
|
+
WEEKDAYS.each do |name, value|
|
|
418
|
+
define_method("#{name}?") do
|
|
419
|
+
@day == value
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
# Builder for the reccurence rule.
|
|
425
|
+
class Builder
|
|
426
|
+
# @overload interval=(value)
|
|
427
|
+
# @param value [Integer] the spacing between the events, defined by the frequency.
|
|
428
|
+
# @return [void]
|
|
429
|
+
attr_writer :interval
|
|
430
|
+
|
|
431
|
+
# @overload frequency=(value)
|
|
432
|
+
# @param value [Integer, String] how frequently the scheduled event should occur.
|
|
433
|
+
# @return [void]
|
|
434
|
+
attr_writer :frequency
|
|
435
|
+
|
|
436
|
+
# @overload start_time=(value)
|
|
437
|
+
# @param value [Time, #iso8601] the time at when the reccurence interval will begin.
|
|
438
|
+
# @return [void]
|
|
439
|
+
attr_writer :start_time
|
|
440
|
+
|
|
441
|
+
# @!visibility private
|
|
442
|
+
def initialize
|
|
443
|
+
@interval = nil
|
|
444
|
+
@frequency = nil
|
|
445
|
+
@start_time = nil
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
# Set the the specific days within the month to recur on.
|
|
449
|
+
# @param monthly_days [Array<Integer>] The speific days within
|
|
450
|
+
# the month to recur on.
|
|
451
|
+
# @return [void]
|
|
452
|
+
def by_month_day=(monthly_days)
|
|
453
|
+
@by_month_day = Array(monthly_days).map(&:to_i)
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
# Set the the specific months of the year to recur on.
|
|
457
|
+
# @param months [Array<Integer, Symbol>, Integer, Symbol] The specific months
|
|
458
|
+
# of the year to recur on, e.g. `:april`, `:july`, `:june`, etc.
|
|
459
|
+
# @return [void]
|
|
460
|
+
def by_month=(months)
|
|
461
|
+
@by_month = Array(months).map { |month| MONTHS[month] || month }
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
# Set the specific days of the week to recur on.
|
|
465
|
+
# @param weekdays [Array<Symbol, Integer>, Symbol, Integer] The specific days
|
|
466
|
+
# of the week to recur on, e.g. `:tuesday`, `:saturday`, etc.
|
|
467
|
+
# @return [void]
|
|
468
|
+
def by_weekday=(weekdays)
|
|
469
|
+
@by_weekday = Array(weekdays).map { |day| WEEKDAYS[day] || day }
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
# Set the specific days for a specific week to recur on.
|
|
473
|
+
# @param week [Integer] The week of the month (1-5) to recur on.
|
|
474
|
+
# @param day [Integer, Symbol] The specific day of the week to recur on, e.g. `:april`.
|
|
475
|
+
# @return [void]
|
|
476
|
+
def by_n_weekday(week:, day:)
|
|
477
|
+
(@by_n_weekday ||= []) << { n: week, day: WEEKDAYS[day] || day }
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
# @!visibility private
|
|
481
|
+
# @return [true, false]
|
|
482
|
+
def interval?
|
|
483
|
+
!@interval.nil?
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
# @!visibility private
|
|
487
|
+
# @return [true, false]
|
|
488
|
+
def frequency?
|
|
489
|
+
!@frequency.nil?
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
# @!visibility private
|
|
493
|
+
# @return [true, false]
|
|
494
|
+
def start_time?
|
|
495
|
+
!@start_time.nil?
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
# @!visibility private
|
|
499
|
+
def to_h
|
|
500
|
+
{
|
|
501
|
+
by_month: @by_month,
|
|
502
|
+
by_weekday: @by_weekday,
|
|
503
|
+
interval: @interval.to_i,
|
|
504
|
+
by_n_weekday: @by_n_weekday,
|
|
505
|
+
by_month_day: @by_month_day,
|
|
506
|
+
start: @start_time.utc.iso8601,
|
|
507
|
+
frequency: FREQUENCIES[@frequency] || @frequency
|
|
508
|
+
}
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
end
|