slk 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +22 -1
- data/README.md +5 -5
- data/bin/slk +3 -3
- data/lib/{slack_cli → slk}/api/activity.rb +10 -11
- data/lib/{slack_cli → slk}/api/bots.rb +5 -4
- data/lib/slk/api/client.rb +51 -0
- data/lib/{slack_cli → slk}/api/conversations.rb +14 -13
- data/lib/slk/api/dnd.rb +41 -0
- data/lib/{slack_cli → slk}/api/emoji.rb +4 -3
- data/lib/{slack_cli → slk}/api/threads.rb +13 -12
- data/lib/{slack_cli → slk}/api/usergroups.rb +2 -1
- data/lib/slk/api/users.rb +105 -0
- data/lib/slk/cli.rb +157 -0
- data/lib/slk/commands/activity.rb +152 -0
- data/lib/{slack_cli → slk}/commands/base.rb +67 -41
- data/lib/slk/commands/cache.rb +141 -0
- data/lib/slk/commands/catchup.rb +411 -0
- data/lib/slk/commands/config.rb +114 -0
- data/lib/slk/commands/dnd.rb +172 -0
- data/lib/slk/commands/emoji.rb +352 -0
- data/lib/slk/commands/help.rb +97 -0
- data/lib/slk/commands/messages.rb +299 -0
- data/lib/slk/commands/presence.rb +109 -0
- data/lib/slk/commands/preset.rb +231 -0
- data/lib/slk/commands/status.rb +223 -0
- data/lib/slk/commands/thread.rb +72 -0
- data/lib/slk/commands/unread.rb +305 -0
- data/lib/slk/commands/workspaces.rb +168 -0
- data/lib/slk/formatters/activity_formatter.rb +148 -0
- data/lib/slk/formatters/attachment_formatter.rb +65 -0
- data/lib/slk/formatters/block_formatter.rb +57 -0
- data/lib/{slack_cli → slk}/formatters/duration_formatter.rb +6 -5
- data/lib/slk/formatters/emoji_replacer.rb +141 -0
- data/lib/slk/formatters/json_message_formatter.rb +95 -0
- data/lib/slk/formatters/mention_replacer.rb +158 -0
- data/lib/slk/formatters/message_formatter.rb +174 -0
- data/lib/{slack_cli → slk}/formatters/output.rb +7 -6
- data/lib/slk/formatters/reaction_formatter.rb +87 -0
- data/lib/{slack_cli → slk}/models/channel.rb +12 -10
- data/lib/slk/models/duration.rb +94 -0
- data/lib/slk/models/message.rb +242 -0
- data/lib/slk/models/preset.rb +78 -0
- data/lib/{slack_cli → slk}/models/reaction.rb +6 -6
- data/lib/{slack_cli → slk}/models/status.rb +6 -6
- data/lib/slk/models/user.rb +55 -0
- data/lib/slk/models/workspace.rb +54 -0
- data/lib/{slack_cli → slk}/runner.rb +22 -19
- data/lib/slk/services/activity_enricher.rb +124 -0
- data/lib/slk/services/api_client.rb +145 -0
- data/lib/{slack_cli → slk}/services/cache_store.rb +20 -17
- data/lib/{slack_cli → slk}/services/configuration.rb +9 -8
- data/lib/slk/services/emoji_downloader.rb +103 -0
- data/lib/slk/services/emoji_searcher.rb +72 -0
- data/lib/{slack_cli → slk}/services/encryption.rb +11 -14
- data/lib/slk/services/gemoji_sync.rb +97 -0
- data/lib/{slack_cli → slk}/services/preset_store.rb +34 -33
- data/lib/slk/services/reaction_enricher.rb +82 -0
- data/lib/slk/services/setup_wizard.rb +131 -0
- data/lib/slk/services/target_resolver.rb +108 -0
- data/lib/{slack_cli → slk}/services/token_store.rb +11 -10
- data/lib/slk/services/unread_marker.rb +101 -0
- data/lib/{slack_cli → slk}/support/error_logger.rb +2 -1
- data/lib/{slack_cli → slk}/support/help_formatter.rb +36 -44
- data/lib/{slack_cli → slk}/support/inline_images.rb +28 -19
- data/lib/slk/support/interactive_prompt.rb +29 -0
- data/lib/{slack_cli → slk}/support/slack_url_parser.rb +15 -17
- data/lib/slk/support/text_wrapper.rb +57 -0
- data/lib/slk/support/user_resolver.rb +141 -0
- data/lib/{slack_cli → slk}/support/xdg_paths.rb +6 -5
- data/lib/slk/version.rb +5 -0
- data/lib/slk.rb +112 -0
- metadata +80 -59
- data/lib/slack_cli/api/client.rb +0 -49
- data/lib/slack_cli/api/dnd.rb +0 -40
- data/lib/slack_cli/api/users.rb +0 -101
- data/lib/slack_cli/cli.rb +0 -118
- data/lib/slack_cli/commands/activity.rb +0 -292
- data/lib/slack_cli/commands/cache.rb +0 -116
- data/lib/slack_cli/commands/catchup.rb +0 -484
- data/lib/slack_cli/commands/config.rb +0 -159
- data/lib/slack_cli/commands/dnd.rb +0 -143
- data/lib/slack_cli/commands/emoji.rb +0 -412
- data/lib/slack_cli/commands/help.rb +0 -76
- data/lib/slack_cli/commands/messages.rb +0 -317
- data/lib/slack_cli/commands/presence.rb +0 -107
- data/lib/slack_cli/commands/preset.rb +0 -239
- data/lib/slack_cli/commands/status.rb +0 -194
- data/lib/slack_cli/commands/thread.rb +0 -62
- data/lib/slack_cli/commands/unread.rb +0 -312
- data/lib/slack_cli/commands/workspaces.rb +0 -151
- data/lib/slack_cli/formatters/emoji_replacer.rb +0 -143
- data/lib/slack_cli/formatters/mention_replacer.rb +0 -154
- data/lib/slack_cli/formatters/message_formatter.rb +0 -429
- data/lib/slack_cli/models/duration.rb +0 -85
- data/lib/slack_cli/models/message.rb +0 -217
- data/lib/slack_cli/models/preset.rb +0 -73
- data/lib/slack_cli/models/user.rb +0 -56
- data/lib/slack_cli/models/workspace.rb +0 -52
- data/lib/slack_cli/services/api_client.rb +0 -149
- data/lib/slack_cli/services/reaction_enricher.rb +0 -87
- data/lib/slack_cli/support/user_resolver.rb +0 -114
- data/lib/slack_cli/version.rb +0 -5
- data/lib/slack_cli.rb +0 -91
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative '../support/help_formatter'
|
|
4
|
-
|
|
5
|
-
module SlackCli
|
|
6
|
-
module Commands
|
|
7
|
-
class Activity < Base
|
|
8
|
-
def execute
|
|
9
|
-
result = validate_options
|
|
10
|
-
return result if result
|
|
11
|
-
|
|
12
|
-
workspace = target_workspaces.first
|
|
13
|
-
api = runner.activity_api(workspace.name)
|
|
14
|
-
|
|
15
|
-
response = api.feed(limit: @options[:limit], types: activity_types)
|
|
16
|
-
|
|
17
|
-
unless response['ok']
|
|
18
|
-
error("Failed to fetch activity: #{response['error']}")
|
|
19
|
-
return 1
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
items = response['items'] || []
|
|
23
|
-
|
|
24
|
-
if @options[:json]
|
|
25
|
-
output_json(items)
|
|
26
|
-
else
|
|
27
|
-
display_activity(items, workspace)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
0
|
|
31
|
-
rescue ApiError => e
|
|
32
|
-
error("Failed to fetch activity: #{e.message}")
|
|
33
|
-
1
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
protected
|
|
37
|
-
|
|
38
|
-
def default_options
|
|
39
|
-
super.merge(
|
|
40
|
-
limit: 20,
|
|
41
|
-
filter: :all,
|
|
42
|
-
show_messages: false
|
|
43
|
-
)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def handle_option(arg, args, remaining)
|
|
47
|
-
case arg
|
|
48
|
-
when '-n', '--limit'
|
|
49
|
-
@options[:limit] = args.shift.to_i
|
|
50
|
-
when '--reactions'
|
|
51
|
-
@options[:filter] = :reactions
|
|
52
|
-
when '--mentions'
|
|
53
|
-
@options[:filter] = :mentions
|
|
54
|
-
when '--threads'
|
|
55
|
-
@options[:filter] = :threads
|
|
56
|
-
when '--show-messages', '-m'
|
|
57
|
-
@options[:show_messages] = true
|
|
58
|
-
else
|
|
59
|
-
super
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def help_text
|
|
64
|
-
help = Support::HelpFormatter.new('slk activity [options]')
|
|
65
|
-
help.description('Show recent activity from the activity feed.')
|
|
66
|
-
|
|
67
|
-
help.section('OPTIONS') do |s|
|
|
68
|
-
s.option('-n, --limit N', 'Number of items (default: 20, max: 50)')
|
|
69
|
-
s.option('--reactions', 'Show only reaction activity')
|
|
70
|
-
s.option('--mentions', 'Show only mentions')
|
|
71
|
-
s.option('--threads', 'Show only thread replies')
|
|
72
|
-
s.option('-m, --show-messages', 'Show the message content for each activity')
|
|
73
|
-
s.option('--json', 'Output as JSON')
|
|
74
|
-
s.option('-w, --workspace', 'Specify workspace')
|
|
75
|
-
s.option('-v, --verbose', 'Show debug information')
|
|
76
|
-
s.option('-q, --quiet', 'Suppress output')
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
help.render
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
private
|
|
83
|
-
|
|
84
|
-
def activity_types
|
|
85
|
-
case @options[:filter]
|
|
86
|
-
when :reactions
|
|
87
|
-
'message_reaction'
|
|
88
|
-
when :mentions
|
|
89
|
-
'at_user,at_user_group,at_channel,at_everyone'
|
|
90
|
-
when :threads
|
|
91
|
-
'thread_v2'
|
|
92
|
-
else
|
|
93
|
-
# All activity types that the Slack web UI uses
|
|
94
|
-
'thread_v2,message_reaction,bot_dm_bundle,at_user,at_user_group,at_channel,at_everyone'
|
|
95
|
-
end
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def display_activity(items, workspace)
|
|
99
|
-
return puts 'No activity found.' if items.empty?
|
|
100
|
-
|
|
101
|
-
items.each do |item|
|
|
102
|
-
display_activity_item(item, workspace)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def display_activity_item(item, workspace)
|
|
107
|
-
type = item.dig('item', 'type')
|
|
108
|
-
timestamp = format_activity_time(item['feed_ts'])
|
|
109
|
-
|
|
110
|
-
case type
|
|
111
|
-
when 'message_reaction'
|
|
112
|
-
display_reaction_activity(item, workspace, timestamp)
|
|
113
|
-
when 'at_user', 'at_user_group', 'at_channel', 'at_everyone'
|
|
114
|
-
display_mention_activity(item, workspace, timestamp)
|
|
115
|
-
when 'thread_v2'
|
|
116
|
-
display_thread_v2_activity(item, workspace, timestamp)
|
|
117
|
-
when 'bot_dm_bundle'
|
|
118
|
-
display_bot_dm_activity(item, workspace, timestamp)
|
|
119
|
-
else
|
|
120
|
-
# Unknown activity type - skip silently
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def display_reaction_activity(item, workspace, timestamp)
|
|
125
|
-
reaction_data = item.dig('item', 'reaction')
|
|
126
|
-
message_data = item.dig('item', 'message')
|
|
127
|
-
return unless reaction_data && message_data
|
|
128
|
-
|
|
129
|
-
user_id = reaction_data['user']
|
|
130
|
-
username = resolve_user(workspace, user_id)
|
|
131
|
-
emoji_name = reaction_data['name']
|
|
132
|
-
emoji = runner.emoji_replacer.lookup_emoji(emoji_name) || ":#{emoji_name}:"
|
|
133
|
-
channel_id = message_data['channel']
|
|
134
|
-
channel = resolve_channel(workspace, channel_id)
|
|
135
|
-
|
|
136
|
-
puts "#{output.blue(timestamp)} #{output.bold(username)} reacted #{emoji} in #{channel}"
|
|
137
|
-
|
|
138
|
-
if @options[:show_messages]
|
|
139
|
-
message = fetch_message(workspace, channel_id, message_data['ts'])
|
|
140
|
-
display_message_preview(message, workspace)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
def display_mention_activity(item, workspace, timestamp)
|
|
145
|
-
message_data = item.dig('item', 'message')
|
|
146
|
-
return unless message_data
|
|
147
|
-
|
|
148
|
-
user_id = message_data['author_user_id'] || message_data['user']
|
|
149
|
-
username = resolve_user(workspace, user_id)
|
|
150
|
-
channel_id = message_data['channel']
|
|
151
|
-
channel = resolve_channel(workspace, channel_id)
|
|
152
|
-
|
|
153
|
-
puts "#{output.blue(timestamp)} #{output.bold(username)} mentioned you in #{channel}"
|
|
154
|
-
|
|
155
|
-
if @options[:show_messages]
|
|
156
|
-
message = fetch_message(workspace, channel_id, message_data['ts'])
|
|
157
|
-
display_message_preview(message, workspace)
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
def display_thread_v2_activity(item, workspace, timestamp)
|
|
162
|
-
thread_entry = item.dig('item', 'bundle_info', 'payload', 'thread_entry')
|
|
163
|
-
return unless thread_entry
|
|
164
|
-
|
|
165
|
-
channel_id = thread_entry['channel_id']
|
|
166
|
-
channel = resolve_channel(workspace, channel_id)
|
|
167
|
-
|
|
168
|
-
puts "#{output.blue(timestamp)} Thread activity in #{channel}"
|
|
169
|
-
|
|
170
|
-
if @options[:show_messages] && thread_entry['thread_ts']
|
|
171
|
-
# Fetch the thread parent message
|
|
172
|
-
message = fetch_message(workspace, channel_id, thread_entry['thread_ts'])
|
|
173
|
-
display_message_preview(message, workspace)
|
|
174
|
-
end
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def display_bot_dm_activity(item, workspace, timestamp)
|
|
178
|
-
message_data = item.dig('item', 'bundle_info', 'payload', 'message')
|
|
179
|
-
return unless message_data
|
|
180
|
-
|
|
181
|
-
channel_id = message_data['channel']
|
|
182
|
-
message_ts = message_data['ts']
|
|
183
|
-
channel = resolve_channel(workspace, channel_id)
|
|
184
|
-
|
|
185
|
-
puts "#{output.blue(timestamp)} Bot message in #{channel}"
|
|
186
|
-
|
|
187
|
-
# Always try to fetch and show the message content (or when --show-messages is enabled)
|
|
188
|
-
if @options[:show_messages]
|
|
189
|
-
message = fetch_message(workspace, channel_id, message_ts)
|
|
190
|
-
display_message_preview(message, workspace) if message
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
def resolve_user(workspace, user_id)
|
|
195
|
-
# Try cache first
|
|
196
|
-
cached = cache_store.get_user(workspace.name, user_id)
|
|
197
|
-
return cached if cached
|
|
198
|
-
|
|
199
|
-
# Fall back to user ID
|
|
200
|
-
user_id
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def resolve_channel(workspace, channel_id)
|
|
204
|
-
# DMs and Group DMs - don't try to resolve
|
|
205
|
-
return 'DM' if channel_id.start_with?('D')
|
|
206
|
-
return 'Group DM' if channel_id.start_with?('G')
|
|
207
|
-
|
|
208
|
-
# Try cache first
|
|
209
|
-
cached = cache_store.get_channel_name(workspace.name, channel_id)
|
|
210
|
-
return "##{cached}" if cached
|
|
211
|
-
|
|
212
|
-
# Try to fetch from API
|
|
213
|
-
begin
|
|
214
|
-
api = runner.conversations_api(workspace.name)
|
|
215
|
-
response = api.info(channel: channel_id)
|
|
216
|
-
if response['ok'] && response['channel']
|
|
217
|
-
name = response['channel']['name']
|
|
218
|
-
cache_store.set_channel(workspace.name, name, channel_id)
|
|
219
|
-
return "##{name}"
|
|
220
|
-
end
|
|
221
|
-
rescue ApiError
|
|
222
|
-
# Fall back to channel ID if API call fails
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
# Fall back to channel ID
|
|
226
|
-
channel_id
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def fetch_message(workspace, channel_id, message_ts)
|
|
230
|
-
api = runner.conversations_api(workspace.name)
|
|
231
|
-
# Fetch a window of messages around the target timestamp
|
|
232
|
-
# Use oldest (exclusive) and latest (inclusive) to create a window
|
|
233
|
-
oldest_ts = (message_ts.to_f - 1).to_s # 1 second before
|
|
234
|
-
latest_ts = (message_ts.to_f + 1).to_s # 1 second after
|
|
235
|
-
|
|
236
|
-
response = api.history(
|
|
237
|
-
channel: channel_id,
|
|
238
|
-
limit: 10,
|
|
239
|
-
oldest: oldest_ts,
|
|
240
|
-
latest: latest_ts
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
return nil unless response['ok'] && response['messages']&.any?
|
|
244
|
-
|
|
245
|
-
# Find the exact message by timestamp
|
|
246
|
-
response['messages'].find { |msg| msg['ts'] == message_ts }
|
|
247
|
-
rescue ApiError
|
|
248
|
-
nil
|
|
249
|
-
end
|
|
250
|
-
|
|
251
|
-
def display_message_preview(message, workspace)
|
|
252
|
-
return unless message
|
|
253
|
-
|
|
254
|
-
# Get username
|
|
255
|
-
username = if message['user']
|
|
256
|
-
resolve_user(workspace, message['user'])
|
|
257
|
-
elsif message['bot_id']
|
|
258
|
-
'Bot'
|
|
259
|
-
else
|
|
260
|
-
'Unknown'
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
# Get text and replace mentions
|
|
264
|
-
text = message['text'] || ''
|
|
265
|
-
text = '[No text]' if text.empty?
|
|
266
|
-
text = runner.mention_replacer.replace(text, workspace) unless text == '[No text]'
|
|
267
|
-
|
|
268
|
-
# Format as indented preview
|
|
269
|
-
lines = text.lines
|
|
270
|
-
first_line = lines.first&.strip || text
|
|
271
|
-
first_line = "#{first_line[0..100]}..." if first_line.length > 100
|
|
272
|
-
|
|
273
|
-
puts " └─ #{username}: #{first_line}"
|
|
274
|
-
|
|
275
|
-
# Show additional lines if any
|
|
276
|
-
if lines.length > 1
|
|
277
|
-
remaining = lines[1..2].map(&:strip).reject(&:empty?)
|
|
278
|
-
remaining.each do |line|
|
|
279
|
-
line = "#{line[0..100]}..." if line.length > 100
|
|
280
|
-
puts " #{line}"
|
|
281
|
-
end
|
|
282
|
-
puts " [#{lines.length - 3} more lines...]" if lines.length > 3
|
|
283
|
-
end
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
def format_activity_time(slack_timestamp)
|
|
287
|
-
time = Time.at(slack_timestamp.to_f)
|
|
288
|
-
time.strftime('%b %d %-I:%M %p') # e.g., "Jan 13 2:45 PM"
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
end
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../support/help_formatter"
|
|
4
|
-
|
|
5
|
-
module SlackCli
|
|
6
|
-
module Commands
|
|
7
|
-
class Cache < Base
|
|
8
|
-
def execute
|
|
9
|
-
result = validate_options
|
|
10
|
-
return result if result
|
|
11
|
-
|
|
12
|
-
case positional_args
|
|
13
|
-
in ["status" | "info"] | []
|
|
14
|
-
show_status
|
|
15
|
-
in ["clear", *rest]
|
|
16
|
-
clear_cache(rest.first)
|
|
17
|
-
in ["populate" | "refresh", *rest]
|
|
18
|
-
populate_cache(rest.first)
|
|
19
|
-
else
|
|
20
|
-
error("Unknown action: #{positional_args.first}")
|
|
21
|
-
1
|
|
22
|
-
end
|
|
23
|
-
rescue ApiError => e
|
|
24
|
-
error("Failed: #{e.message}")
|
|
25
|
-
1
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
protected
|
|
29
|
-
|
|
30
|
-
def help_text
|
|
31
|
-
help = Support::HelpFormatter.new("slk cache <action> [workspace]")
|
|
32
|
-
help.description("Manage user and channel cache.")
|
|
33
|
-
|
|
34
|
-
help.section("ACTIONS") do |s|
|
|
35
|
-
s.action("status", "Show cache status")
|
|
36
|
-
s.action("clear [ws]", "Clear cache (all or specific workspace)")
|
|
37
|
-
s.action("populate [ws]", "Populate user cache from API")
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
help.section("OPTIONS") do |s|
|
|
41
|
-
s.option("-w, --workspace", "Specify workspace")
|
|
42
|
-
s.option("-q, --quiet", "Suppress output")
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
help.render
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
49
|
-
|
|
50
|
-
def show_status
|
|
51
|
-
target_workspaces.each do |workspace|
|
|
52
|
-
if target_workspaces.size > 1
|
|
53
|
-
puts output.bold(workspace.name)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
user_count = cache_store.user_cache_size(workspace.name)
|
|
57
|
-
channel_count = cache_store.channel_cache_size(workspace.name)
|
|
58
|
-
|
|
59
|
-
puts " Users cached: #{user_count}"
|
|
60
|
-
puts " Channels cached: #{channel_count}"
|
|
61
|
-
|
|
62
|
-
if cache_store.user_cache_file_exists?(workspace.name)
|
|
63
|
-
puts " User cache: #{output.green("present")}"
|
|
64
|
-
else
|
|
65
|
-
puts " User cache: #{output.yellow("not populated")}"
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
0
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def clear_cache(workspace_name)
|
|
73
|
-
if workspace_name
|
|
74
|
-
cache_store.clear_user_cache(workspace_name)
|
|
75
|
-
cache_store.clear_channel_cache(workspace_name)
|
|
76
|
-
success("Cleared cache for #{workspace_name}")
|
|
77
|
-
else
|
|
78
|
-
cache_store.clear_user_cache
|
|
79
|
-
cache_store.clear_channel_cache
|
|
80
|
-
success("Cleared all caches")
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
0
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def populate_cache(workspace_name)
|
|
87
|
-
workspaces = workspace_name ? [runner.workspace(workspace_name)] : target_workspaces
|
|
88
|
-
|
|
89
|
-
workspaces.each do |workspace|
|
|
90
|
-
puts "Populating user cache for #{workspace.name}..."
|
|
91
|
-
|
|
92
|
-
api = runner.users_api(workspace.name)
|
|
93
|
-
all_users = []
|
|
94
|
-
cursor = nil
|
|
95
|
-
|
|
96
|
-
loop do
|
|
97
|
-
response = api.list(cursor: cursor)
|
|
98
|
-
members = response["members"] || []
|
|
99
|
-
all_users.concat(members.map { |m| Models::User.from_api(m) })
|
|
100
|
-
|
|
101
|
-
cursor = response.dig("response_metadata", "next_cursor")
|
|
102
|
-
break if cursor.nil? || cursor.empty?
|
|
103
|
-
|
|
104
|
-
print "."
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
count = cache_store.populate_user_cache(workspace.name, all_users)
|
|
108
|
-
puts
|
|
109
|
-
success("Cached #{count} users for #{workspace.name}")
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
0
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|