slack-smart-bot 1.12.9 → 1.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +85 -12
- data/lib/slack/smart-bot/comm/respond.rb +1 -0
- data/lib/slack/smart-bot/comm/update.rb +13 -0
- data/lib/slack/smart-bot/comm.rb +1 -0
- data/lib/slack/smart-bot/commands/general/add_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general/add_vacation.rb +5 -0
- data/lib/slack/smart-bot/commands/general/allow_access.rb +1 -1
- data/lib/slack/smart-bot/commands/general/delete_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general/deny_access.rb +1 -1
- data/lib/slack/smart-bot/commands/general/public_holidays.rb +144 -0
- data/lib/slack/smart-bot/commands/general/see_announcements.rb +2 -2
- data/lib/slack/smart-bot/commands/general/see_memos_team.rb +202 -0
- data/lib/slack/smart-bot/commands/general/see_teams.rb +3 -175
- data/lib/slack/smart-bot/commands/general/see_vacations.rb +41 -21
- data/lib/slack/smart-bot/commands/general/set_public_holidays.rb +21 -0
- data/lib/slack/smart-bot/commands/general/update_team.rb +1 -0
- data/lib/slack/smart-bot/commands/general_bot_commands.rb +100 -8
- data/lib/slack/smart-bot/commands/on_bot/admin/add_routine.rb +27 -3
- data/lib/slack/smart-bot/commands/on_bot/admin/run_routine.rb +12 -8
- data/lib/slack/smart-bot/commands/on_bot/admin/see_routines.rb +33 -4
- data/lib/slack/smart-bot/commands/on_bot/admin/start_routine.rb +22 -1
- data/lib/slack/smart-bot/commands/on_bot/admin_master/send_message.rb +50 -4
- data/lib/slack/smart-bot/commands/on_bot/admin_master/update_message.rb +25 -0
- data/lib/slack/smart-bot/commands/on_bot/general/bot_stats.rb +6 -4
- data/lib/slack/smart-bot/commands/on_bot/repl.rb +55 -15
- data/lib/slack/smart-bot/commands/on_bot/ruby_code.rb +2 -1
- data/lib/slack/smart-bot/commands.rb +4 -0
- data/lib/slack/smart-bot/listen.rb +1 -1
- data/lib/slack/smart-bot/process.rb +36 -6
- data/lib/slack/smart-bot/process_first.rb +250 -188
- data/lib/slack/smart-bot/treat_message.rb +1 -1
- data/lib/slack/smart-bot/utils/build_help.rb +1 -1
- data/lib/slack/smart-bot/utils/create_routine_thread.rb +40 -4
- data/lib/slack/smart-bot/utils/decrypt.rb +15 -0
- data/lib/slack/smart-bot/utils/display_calendar.rb +86 -0
- data/lib/slack/smart-bot/utils/encrypt.rb +15 -0
- data/lib/slack/smart-bot/utils/encryption_get_key_iv.rb +29 -0
- data/lib/slack/smart-bot/utils/get_help.rb +1 -1
- data/lib/slack/smart-bot/utils/get_team_members.rb +39 -0
- data/lib/slack/smart-bot/utils/get_teams.rb +22 -16
- data/lib/slack/smart-bot/utils/get_vacations.rb +20 -15
- data/lib/slack/smart-bot/utils/save_stats.rb +2 -2
- data/lib/slack/smart-bot/utils/update_teams.rb +15 -9
- data/lib/slack/smart-bot/utils/update_vacations.rb +5 -3
- data/lib/slack/smart-bot/utils.rb +5 -0
- data/lib/slack-smart-bot.rb +9 -0
- data/lib/slack-smart-bot_general_commands.rb +33 -0
- data/lib/slack-smart-bot_general_rules.rb +2 -2
- data/whats_new.txt +15 -17
- metadata +27 -11
@@ -0,0 +1,202 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def see_memos_team(user, type: "all", name: nil, topic: "", add_stats: true, team: nil)
|
3
|
+
save_stats(__method__) if add_stats
|
4
|
+
|
5
|
+
get_teams()
|
6
|
+
type = "all" if type.match?(/all\s+memo/i)
|
7
|
+
message = []
|
8
|
+
if @teams.size > 0
|
9
|
+
if team.nil?
|
10
|
+
@teams.each do |team_name, teamv|
|
11
|
+
if (team_name.to_s == name.to_s) or (name.to_s.gsub("-", "").gsub("_", "") == team_name.to_s)
|
12
|
+
if teamv.key?(:memos) and teamv[:memos].size > 0
|
13
|
+
team = teamv.deep_copy
|
14
|
+
else
|
15
|
+
respond "There are no memos for the team #{name}." unless !add_stats
|
16
|
+
end
|
17
|
+
break
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
if team
|
22
|
+
all_memos = {}
|
23
|
+
assigned_members, unassigned_members, not_on_team_channel, channels_members, all_team_members = get_team_members(team)
|
24
|
+
users_link = (Thread.current[:dest][0] == "D")
|
25
|
+
memos_filtered = []
|
26
|
+
all_topics = []
|
27
|
+
team[:memos].each do |memo|
|
28
|
+
if (type == "all" or type.to_s == memo[:type].to_s or type == "") and (topic == "" or memo[:topic].to_s.downcase == topic.to_s.downcase)
|
29
|
+
memos_filtered << memo
|
30
|
+
all_topics << memo.topic
|
31
|
+
end
|
32
|
+
end
|
33
|
+
all_topics.uniq!
|
34
|
+
all_topics.delete(:no_topic)
|
35
|
+
if memos_filtered.size >= 10 and !add_stats
|
36
|
+
message << " > *_memos_*"
|
37
|
+
message << " There are too many memos to show. "
|
38
|
+
message << " Please use the `see MEMO_TYPE team #{team.name} TOPIC` command."
|
39
|
+
message << " Available topics: #{all_topics.join(", ")}" if all_topics.size > 0
|
40
|
+
message << " Examples: `see bugs #{team.name} team`, `see all memos #{team.name} team #{all_topics.sample}`, `see tasks #{team.name} team #{all_topics.sample}`"
|
41
|
+
elsif memos_filtered.size > 0
|
42
|
+
memos_filtered.each do |memo|
|
43
|
+
if memo.privacy.empty? or
|
44
|
+
(memo.privacy == "private" and (all_team_members.include?(user.name) and (users_link or channels_members.include?(Thread.current[:dest])))) or
|
45
|
+
(memo.privacy == "personal" and memo.user == user.name and users_link)
|
46
|
+
if memo.type == "jira" and config.jira.host != ""
|
47
|
+
http = NiceHttp.new(config.jira.host)
|
48
|
+
http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
|
49
|
+
if memo.message.match?(/^\w+\-\d+$/)
|
50
|
+
resp = http.get("/rest/api/latest/issue/#{memo.message}")
|
51
|
+
issues = [resp.data.json] if resp.code == 200
|
52
|
+
else
|
53
|
+
resp = http.get("/rest/api/latest/search/?jql=#{memo.message}")
|
54
|
+
issues = resp.data.json().issues if resp.code == 200
|
55
|
+
end
|
56
|
+
if resp.code == 200
|
57
|
+
unless issues.empty?
|
58
|
+
issues.each do |issue|
|
59
|
+
jira_memo = { jira: true, github: false, status: "", memo_id: memo.memo_id, topic: memo.topic, privacy: memo.privacy, user: memo.user, date: memo.date, message: "", type: memo.type }
|
60
|
+
jira_memo.message = issue.fields.summary
|
61
|
+
jira_memo.user = issue.fields.reporter.name
|
62
|
+
jira_memo.date = issue.fields.created
|
63
|
+
if memo.topic == :no_topic and !issue.fields.labels.empty?
|
64
|
+
jira_memo.topic = issue.fields.labels.sort.join("_").split(" ").join("_")
|
65
|
+
end
|
66
|
+
case issue.fields.issuetype.name
|
67
|
+
when "Story"; jira_memo.type = ":abc:"
|
68
|
+
when "Bug"; jira_memo.type = ":bug:"
|
69
|
+
when "Task"; jira_memo.type = ":clock1:"
|
70
|
+
when "New Feature", "Improvement"; jira_memo.type = ":sunny:"
|
71
|
+
else jira_memo.type = ":memo:"
|
72
|
+
end
|
73
|
+
case issue.fields.status.statusCategory.name
|
74
|
+
when "Done"; jira_memo.status = ":heavy_check_mark:"
|
75
|
+
when "To Do"; jira_memo.status = ":new:"
|
76
|
+
when "In Progress"; jira_memo.status = ":runner:"
|
77
|
+
else jira_memo.status = ":heavy_minus_sign:"
|
78
|
+
end
|
79
|
+
#todo: check if possible to add link to status instead of jira issue
|
80
|
+
#jira_memo.status = " <#{config.jira.host}/browse/#{issue[:key]}|#{jira_memo.status}> "
|
81
|
+
jira_memo.status += " <#{config.jira.host}/browse/#{issue[:key]}|#{issue[:key]}>"
|
82
|
+
|
83
|
+
all_memos[jira_memo.topic] ||= []
|
84
|
+
all_memos[jira_memo.topic] << jira_memo
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
http.close
|
89
|
+
elsif memo.type == "github" and config.github.host != ""
|
90
|
+
http = NiceHttp.new(config.github.host)
|
91
|
+
http.headers.authorization = "token #{config.github.token}"
|
92
|
+
memo.message += "?" unless memo.message.include?("?")
|
93
|
+
memo.message += "&per_page=50"
|
94
|
+
|
95
|
+
resp = http.get("/repos/#{memo.message}")
|
96
|
+
issues = resp.data.json()
|
97
|
+
issues = [issues] unless issues.is_a?(Array)
|
98
|
+
if resp.code == 200
|
99
|
+
unless issues.empty?
|
100
|
+
issues.each do |issue|
|
101
|
+
github_memo = { jira: false, github: true, status: "", memo_id: memo.memo_id, topic: memo.topic, privacy: memo.privacy, user: memo.user, date: memo.date, message: "", type: memo.type }
|
102
|
+
github_memo.message = issue.title
|
103
|
+
github_memo.user = issue.user.login
|
104
|
+
github_memo.date = issue.created_at
|
105
|
+
if issue.labels.empty?
|
106
|
+
labels = ""
|
107
|
+
else
|
108
|
+
labels = issue.labels.name.sort.join("_").split(" ").join("_")
|
109
|
+
end
|
110
|
+
if memo.topic == :no_topic and !issue.labels.empty?
|
111
|
+
github_memo.topic = labels
|
112
|
+
end
|
113
|
+
case labels
|
114
|
+
when /bug/i; github_memo.type = ":bug:"
|
115
|
+
when /docum/i; github_memo.type = ":abc:"
|
116
|
+
when /task/i; github_memo.type = ":clock1:"
|
117
|
+
when /enhancem/i, /improvement/i; github_memo.type = ":sunny:"
|
118
|
+
else github_memo.type = ":memo:"
|
119
|
+
end
|
120
|
+
if issue.key?(:events_url)
|
121
|
+
resp_events = http.get(issue.events_url)
|
122
|
+
events = resp_events.data.json(:event)
|
123
|
+
issue.state = "in progress" if events.include?("referenced")
|
124
|
+
end
|
125
|
+
case issue.state
|
126
|
+
when "closed"; github_memo.status = ":heavy_check_mark:"
|
127
|
+
when "open"; github_memo.status = ":new:"
|
128
|
+
when "in progress"; github_memo.status = ":runner:"
|
129
|
+
else github_memo.status = ":heavy_minus_sign:"
|
130
|
+
end
|
131
|
+
#todo: check if possible to add link to status instead of github issue
|
132
|
+
github_memo.status += " <#{issue.html_url}|##{issue.number}>"
|
133
|
+
|
134
|
+
all_memos[github_memo.topic] ||= []
|
135
|
+
all_memos[github_memo.topic] << github_memo
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
http.close
|
140
|
+
else
|
141
|
+
memo.jira = false
|
142
|
+
memo.github = false
|
143
|
+
all_memos[memo.topic] ||= []
|
144
|
+
case memo.type
|
145
|
+
when "memo"; memo.type = ":memo:"
|
146
|
+
when "note"; memo.type = ":abc:"
|
147
|
+
when "bug"; memo.type = ":bug:"
|
148
|
+
when "task"; memo.type = ":clock1:"
|
149
|
+
when "feature"; memo.type = ":sunny:"
|
150
|
+
when "issue"; memo.type = ":hammer:"
|
151
|
+
else memo.type = ":heavy_minus_sign:"
|
152
|
+
end
|
153
|
+
all_memos[memo.topic] << memo
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
if !add_stats
|
158
|
+
message << " > *_memos_*" unless all_memos.empty?
|
159
|
+
else
|
160
|
+
message << " > *_#{team.name} team #{type}_*"
|
161
|
+
end
|
162
|
+
|
163
|
+
if all_memos.key?(:no_topic)
|
164
|
+
all_memos[:no_topic].sort_by { |memo| memo[:date] }.each do |memo|
|
165
|
+
case memo.privacy
|
166
|
+
when "private"; priv = " `private`"
|
167
|
+
when "personal"; priv = " `personal`"
|
168
|
+
else priv = ""
|
169
|
+
end
|
170
|
+
message << " #{memo.type} #{memo.date.gsub("-", "/")[0..9]}: #{memo.status} #{memo.message} (#{memo.user} #{memo.memo_id})#{priv}"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
all_memos[:no_topic] = []
|
174
|
+
all_memos.each do |topic, mems|
|
175
|
+
unless mems.empty?
|
176
|
+
message << " _`#{topic}`_:"
|
177
|
+
mems.sort_by { |m| m[:date] }.each do |memo|
|
178
|
+
case memo.privacy
|
179
|
+
when "private"; priv = " `private`"
|
180
|
+
when "personal"; priv = " `personal`"
|
181
|
+
else priv = ""
|
182
|
+
end
|
183
|
+
message << " #{memo.type} #{memo.date.gsub("-", "/")[0..9]}: #{memo.status} #{memo.message} (#{memo.user} #{memo.memo_id})#{priv}"
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
else
|
188
|
+
message << "There are no memos #{type} #{topic}." unless !add_stats
|
189
|
+
end
|
190
|
+
else
|
191
|
+
respond "There is no team named #{name}." unless !add_stats
|
192
|
+
end
|
193
|
+
if add_stats
|
194
|
+
respond message.join("\n")
|
195
|
+
else
|
196
|
+
return message
|
197
|
+
end
|
198
|
+
else
|
199
|
+
respond "There are no teams added yet\. Use `add team` command to add a team" unless !add_stats
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
@@ -62,39 +62,8 @@ class SlackSmartBot
|
|
62
62
|
|
63
63
|
message << " > *_members_*"
|
64
64
|
|
65
|
-
assigned_members = team
|
66
|
-
|
67
|
-
assigned_members.dup.each do |m|
|
68
|
-
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) or u.name == m or (u.key?(:enterprise_user) and u.enterprise_user.name == m) }[-1]
|
69
|
-
assigned_members.delete(m) if user_info.nil? or user_info.deleted
|
70
|
-
end
|
71
|
-
channels_members = []
|
72
|
-
all_team_members = assigned_members.dup
|
73
|
-
if team.channels.key?("members")
|
74
|
-
team_members = []
|
75
|
-
team.channels["members"].each do |ch|
|
76
|
-
get_channels_name_and_id() unless @channels_id.key?(ch)
|
77
|
-
tm = get_channel_members(@channels_id[ch])
|
78
|
-
if tm.nil?
|
79
|
-
respond ":exclamation: Add the Smart Bot to *##{ch}* channel to be able to get the list of members.", dest
|
80
|
-
else
|
81
|
-
channels_members << @channels_id[ch]
|
82
|
-
tm.each do |m|
|
83
|
-
user_info = @users.select { |u| u.id == m or (u.key?(:enterprise_user) and u.enterprise_user.id == m) }[-1]
|
84
|
-
team_members << user_info.name unless user_info.is_app_user or user_info.is_bot
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
team_members.flatten!
|
89
|
-
team_members.uniq!
|
90
|
-
unassigned_members = team_members - assigned_members
|
91
|
-
unassigned_members.delete(config.nick)
|
92
|
-
not_on_team_channel = assigned_members - team_members
|
93
|
-
all_team_members += team_members
|
94
|
-
else
|
95
|
-
unassigned_members = []
|
96
|
-
not_on_team_channel = []
|
97
|
-
end
|
65
|
+
assigned_members, unassigned_members, not_on_team_channel, channels_members, all_team_members = get_team_members(team)
|
66
|
+
|
98
67
|
unless unassigned_members.empty?
|
99
68
|
um = unassigned_members.dup
|
100
69
|
um.each do |m|
|
@@ -217,148 +186,7 @@ class SlackSmartBot
|
|
217
186
|
end
|
218
187
|
|
219
188
|
unless !team.key?(:memos) or team.memos.empty? or (team_name.to_s == "" and search.to_s == "")
|
220
|
-
|
221
|
-
team.memos.each do |memo|
|
222
|
-
if memo.privacy.empty? or
|
223
|
-
(memo.privacy == "private" and (all_team_members.include?(user.name) and (users_link or channels_members.include?(Thread.current[:dest])))) or
|
224
|
-
(memo.privacy == "personal" and memo.user == user.name and users_link)
|
225
|
-
if memo.type == "jira" and config.jira.host != ""
|
226
|
-
http = NiceHttp.new(config.jira.host)
|
227
|
-
http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
|
228
|
-
if memo.message.match?(/^\w+\-\d+$/)
|
229
|
-
resp = http.get("/rest/api/latest/issue/#{memo.message}")
|
230
|
-
issues = [resp.data.json] if resp.code == 200
|
231
|
-
else
|
232
|
-
resp = http.get("/rest/api/latest/search/?jql=#{memo.message}")
|
233
|
-
issues = resp.data.json().issues if resp.code == 200
|
234
|
-
end
|
235
|
-
if resp.code == 200
|
236
|
-
unless issues.empty?
|
237
|
-
issues.each do |issue|
|
238
|
-
jira_memo = { jira: true, github: false, status: "", memo_id: memo.memo_id, topic: memo.topic, privacy: memo.privacy, user: memo.user, date: memo.date, message: "", type: memo.type }
|
239
|
-
jira_memo.message = issue.fields.summary
|
240
|
-
jira_memo.user = issue.fields.reporter.name
|
241
|
-
jira_memo.date = issue.fields.created
|
242
|
-
if memo.topic == :no_topic and !issue.fields.labels.empty?
|
243
|
-
jira_memo.topic = issue.fields.labels.sort.join("_").split(" ").join("_")
|
244
|
-
end
|
245
|
-
case issue.fields.issuetype.name
|
246
|
-
when "Story"; jira_memo.type = ":abc:"
|
247
|
-
when "Bug"; jira_memo.type = ":bug:"
|
248
|
-
when "Task"; jira_memo.type = ":clock1:"
|
249
|
-
when "New Feature", "Improvement"; jira_memo.type = ":sunny:"
|
250
|
-
else jira_memo.type = ":memo:"
|
251
|
-
end
|
252
|
-
case issue.fields.status.statusCategory.name
|
253
|
-
when "Done"; jira_memo.status = ":heavy_check_mark:"
|
254
|
-
when "To Do"; jira_memo.status = ":new:"
|
255
|
-
when "In Progress"; jira_memo.status = ":runner:"
|
256
|
-
else jira_memo.status = ":heavy_minus_sign:"
|
257
|
-
end
|
258
|
-
#todo: check if possible to add link to status instead of jira issue
|
259
|
-
#jira_memo.status = " <#{config.jira.host}/browse/#{issue[:key]}|#{jira_memo.status}> "
|
260
|
-
jira_memo.status += " <#{config.jira.host}/browse/#{issue[:key]}|#{issue[:key]}>"
|
261
|
-
|
262
|
-
all_memos[jira_memo.topic] ||= []
|
263
|
-
all_memos[jira_memo.topic] << jira_memo
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
http.close
|
268
|
-
elsif memo.type == "github" and config.github.host != ""
|
269
|
-
http = NiceHttp.new(config.github.host)
|
270
|
-
http.headers.authorization = "token #{config.github.token}"
|
271
|
-
memo.message+="?" unless memo.message.include?('?')
|
272
|
-
memo.message+="&per_page=50"
|
273
|
-
|
274
|
-
resp = http.get("/repos/#{memo.message}")
|
275
|
-
issues = resp.data.json()
|
276
|
-
issues = [issues] unless issues.is_a?(Array)
|
277
|
-
if resp.code == 200
|
278
|
-
unless issues.empty?
|
279
|
-
issues.each do |issue|
|
280
|
-
github_memo = { jira: false, github: true, status: "", memo_id: memo.memo_id, topic: memo.topic, privacy: memo.privacy, user: memo.user, date: memo.date, message: "", type: memo.type }
|
281
|
-
github_memo.message = issue.title
|
282
|
-
github_memo.user = issue.user.login
|
283
|
-
github_memo.date = issue.created_at
|
284
|
-
if issue.labels.empty?
|
285
|
-
labels = ''
|
286
|
-
else
|
287
|
-
labels = issue.labels.name.sort.join("_").split(" ").join("_")
|
288
|
-
end
|
289
|
-
if memo.topic == :no_topic and !issue.labels.empty?
|
290
|
-
github_memo.topic = labels
|
291
|
-
end
|
292
|
-
case labels
|
293
|
-
when /bug/i; github_memo.type = ":bug:"
|
294
|
-
when /docum/i; github_memo.type = ":abc:"
|
295
|
-
when /task/i; github_memo.type = ":clock1:"
|
296
|
-
when /enhancem/i, /improvement/i; github_memo.type = ":sunny:"
|
297
|
-
else github_memo.type = ":memo:"
|
298
|
-
end
|
299
|
-
if issue.key?(:events_url)
|
300
|
-
resp_events = http.get(issue.events_url)
|
301
|
-
events = resp_events.data.json(:event)
|
302
|
-
issue.state = "in progress" if events.include?('referenced')
|
303
|
-
end
|
304
|
-
case issue.state
|
305
|
-
when "closed"; github_memo.status = ":heavy_check_mark:"
|
306
|
-
when "open"; github_memo.status = ":new:"
|
307
|
-
when "in progress"; github_memo.status = ":runner:"
|
308
|
-
else github_memo.status = ":heavy_minus_sign:"
|
309
|
-
end
|
310
|
-
#todo: check if possible to add link to status instead of github issue
|
311
|
-
github_memo.status += " <#{issue.html_url}|##{issue.number}>"
|
312
|
-
|
313
|
-
all_memos[github_memo.topic] ||= []
|
314
|
-
all_memos[github_memo.topic] << github_memo
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
318
|
-
http.close
|
319
|
-
else
|
320
|
-
memo.jira = false
|
321
|
-
memo.github = false
|
322
|
-
all_memos[memo.topic] ||= []
|
323
|
-
case memo.type
|
324
|
-
when "memo"; memo.type = ":memo:"
|
325
|
-
when "note"; memo.type = ":abc:"
|
326
|
-
when "bug"; memo.type = ":bug:"
|
327
|
-
when "task"; memo.type = ":clock1:"
|
328
|
-
when "feature"; memo.type = ":sunny:"
|
329
|
-
when "issue"; memo.type = ":hammer:"
|
330
|
-
else memo.type = ":heavy_minus_sign:"
|
331
|
-
end
|
332
|
-
all_memos[memo.topic] << memo
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
message << " > *_memos_*" unless all_memos.empty?
|
337
|
-
|
338
|
-
if all_memos.key?(:no_topic)
|
339
|
-
all_memos[:no_topic].sort_by { |memo| memo[:date] }.each do |memo|
|
340
|
-
case memo.privacy
|
341
|
-
when "private"; priv = " `private`"
|
342
|
-
when "personal"; priv = " `personal`"
|
343
|
-
else priv = ""
|
344
|
-
end
|
345
|
-
message << " #{memo.type} #{memo.date.gsub("-", "/")[0..9]}: #{memo.status} #{memo.message} (#{memo.user} #{memo.memo_id})#{priv}"
|
346
|
-
end
|
347
|
-
end
|
348
|
-
all_memos[:no_topic] = []
|
349
|
-
all_memos.each do |topic, mems|
|
350
|
-
unless mems.empty?
|
351
|
-
message << " _`#{topic}`_:"
|
352
|
-
mems.sort_by { |m| m[:date] }.each do |memo|
|
353
|
-
case memo.privacy
|
354
|
-
when "private"; priv = " `private`"
|
355
|
-
when "personal"; priv = " `personal`"
|
356
|
-
else priv = ""
|
357
|
-
end
|
358
|
-
message << " #{memo.type} #{memo.date.gsub("-", "/")[0..9]}: #{memo.status} #{memo.message} (#{memo.user} #{memo.memo_id})#{priv}"
|
359
|
-
end
|
360
|
-
end
|
361
|
-
end
|
189
|
+
message += see_memos_team(user, type: "all", add_stats: false, team: team)
|
362
190
|
end
|
363
191
|
|
364
192
|
unless team.info.empty?
|
@@ -1,10 +1,11 @@
|
|
1
1
|
class SlackSmartBot
|
2
|
-
def see_vacations(user, from_user: '', add_stats: true)
|
2
|
+
def see_vacations(user, dest, from_user: '', add_stats: true, year: '')
|
3
3
|
save_stats(__method__) if add_stats
|
4
4
|
|
5
5
|
get_vacations()
|
6
6
|
|
7
7
|
from_user_name = ''
|
8
|
+
year = Date.today.year if year.to_s == ''
|
8
9
|
|
9
10
|
if from_user.empty?
|
10
11
|
from_user_name = user.name
|
@@ -13,8 +14,8 @@ class SlackSmartBot
|
|
13
14
|
user_info = @users.select{|u| u.id == from_user or (u.key?(:enterprise_user) and u.enterprise_user.id == from_user)}[-1]
|
14
15
|
from_user_name = user_info.name
|
15
16
|
end
|
16
|
-
|
17
|
-
if !@vacations.key?(from_user_name) or @vacations[from_user_name].periods.empty?
|
17
|
+
from_user = '' if from_user_name == user.name
|
18
|
+
if !@vacations.key?(from_user_name) or !@vacations[from_user_name].key?(:periods) or @vacations[from_user_name].periods.empty?
|
18
19
|
if from_user.empty?
|
19
20
|
respond "You didn't add any time off yet. Use `add vacation from YYYY/MM/DD to YYYY/MM/DD`"
|
20
21
|
else
|
@@ -22,36 +23,55 @@ class SlackSmartBot
|
|
22
23
|
end
|
23
24
|
else
|
24
25
|
messages = []
|
25
|
-
messages << "*Time off <@#{from_user}
|
26
|
+
messages << "*Time off <@#{from_user}> #{year}*" if !from_user.empty?
|
27
|
+
|
28
|
+
display_calendar(from_user_name, year) if from_user_name == user.name and dest[0] == 'D'
|
29
|
+
|
26
30
|
today = Date.today.strftime("%Y/%m/%d")
|
27
31
|
current_added = false
|
28
32
|
past_added = false
|
29
33
|
@vacations[from_user_name].periods.sort_by { |v| v[:from]}.reverse.each do |vac|
|
30
|
-
if !current_added and vac.to >= today
|
34
|
+
if !current_added and vac.to >= today
|
31
35
|
messages << "*Current and future periods*"
|
32
36
|
current_added = true
|
33
37
|
end
|
34
|
-
if !past_added and vac.to < today and from_user.empty?
|
35
|
-
|
36
|
-
|
38
|
+
if !past_added and vac.to < today and from_user.empty? and vac.to[0..3] == year
|
39
|
+
if dest[0]=='D'
|
40
|
+
messages << "\n*Past periods #{year}*"
|
41
|
+
past_added = true
|
42
|
+
else
|
43
|
+
messages << "To see past periods call me from a DM"
|
44
|
+
break
|
45
|
+
end
|
37
46
|
end
|
38
47
|
unless !from_user.empty? and vac.to < today
|
39
|
-
if
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
48
|
+
if vac.to[0..3] == year
|
49
|
+
if !from_user.empty?
|
50
|
+
icon = ":beach_with_umbrella:"
|
51
|
+
elsif vac.type == 'vacation'
|
52
|
+
icon = ':palm_tree:'
|
53
|
+
elsif vac.type == 'sick'
|
54
|
+
icon = ':face_with_thermometer:'
|
55
|
+
elsif vac.type == 'sick child'
|
56
|
+
icon = ':baby:'
|
57
|
+
end
|
58
|
+
if vac.from == vac.to
|
59
|
+
messages << " #{icon} #{vac.from} ##{vac.vacation_id}"
|
60
|
+
else
|
61
|
+
messages << " #{icon} #{vac.from} -> #{vac.to} ##{vac.vacation_id}"
|
62
|
+
end
|
52
63
|
end
|
53
64
|
end
|
54
65
|
end
|
66
|
+
if !past_added and !current_added and dest[0]=='D'
|
67
|
+
if from_user.empty?
|
68
|
+
messages << "No time off added yet for #{year}"
|
69
|
+
else
|
70
|
+
messages << "Not possible to see past periods for another user"
|
71
|
+
end
|
72
|
+
elsif !past_added and dest[0]=='D' and !from_user.empty? and from_user_name != user.name
|
73
|
+
messages << "Not possible to see past periods for another user"
|
74
|
+
end
|
55
75
|
respond messages.join("\n")
|
56
76
|
end
|
57
77
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class SlackSmartBot
|
2
|
+
def set_public_holidays(country, state, user)
|
3
|
+
save_stats(__method__)
|
4
|
+
|
5
|
+
result = public_holidays(country, state, Date.today.year.to_s, '', '', add_stats: false, publish_results: false)
|
6
|
+
if result == true
|
7
|
+
if state == ""
|
8
|
+
country_region = country
|
9
|
+
else
|
10
|
+
country_region = "#{country}/#{state}"
|
11
|
+
end
|
12
|
+
respond "Public holidays for *#{country_region}* set."
|
13
|
+
get_vacations()
|
14
|
+
@vacations[user.name] ||= {}
|
15
|
+
@vacations[user.name][:public_holidays] = country_region
|
16
|
+
update_vacations()
|
17
|
+
else
|
18
|
+
respond "Be sure the country and state are correct."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -32,6 +32,7 @@ class SlackSmartBot
|
|
32
32
|
team = @teams[team_name.to_sym].deep_copy
|
33
33
|
@teams[new_name.to_sym] = team
|
34
34
|
@teams.delete(team_name.to_sym)
|
35
|
+
File.delete(File.join(config.path, "teams", "t_#{team_name}.yaml"))
|
35
36
|
message = "The *#{team_name}* team has been renamed #{new_name}."
|
36
37
|
team_name = new_name
|
37
38
|
elsif new_info != ""
|