Module: SlackSmartBot::Commands::General::Teams::Memos

Included in:
SlackSmartBot
Defined in:
lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb,
lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb,
lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb,
lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb,
lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb,
lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb

Instance Method Summary collapse

Instance Method Details

#add_memo_team(user, privacy, team_name, topic, type, message) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/slack/smart-bot/commands/general/teams/memos/add_memo_team.rb', line 6

def add_memo_team(user, privacy, team_name, topic, type, message)
  save_stats(__method__)

  get_teams()
  if @teams.key?(team_name.to_sym)
    assigned_members = @teams[team_name.to_sym].members.values.flatten
    assigned_members.uniq!
    all_team_members = assigned_members.dup
    team_members = []
    if @teams[team_name.to_sym].channels.key?("members")
      @teams[team_name.to_sym].channels["members"].each do |ch|
        get_channels_name_and_id() unless @channels_id.key?(ch)
        tm = get_channel_members(@channels_id[ch])
        tm.each do |m|
           = find_user(m)
          team_members << "#{.team_id}_#{.name}" unless .is_app_user or .is_bot
        end
      end
    end
    team_members.flatten!
    team_members.uniq!
    all_team_members += team_members
    all_team_members.uniq!
  end
  search = false
  if type == "jira"
    able_to_connect_jira = false
    begin
      if config.jira.host == "" or config.jira.user == "" or config.jira.password == ""
        respond "You need to supply the correct credentials for JIRA on the SmartBot settings: `jira: { host: HOST, user: USER, password: PASSWORD }`"
      else
        http = NiceHttp.new(config.jira.host)
        http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
        message.gsub!(/^\s*</, "")
        message.gsub!(/\>$/, "")
        message.gsub!(/\|.+$/, "")
        message.gsub!(/^#{config.jira.host}/, "")
        if message.include?("/browse/")
          message = message.scan(/\/browse\/(.+)/).join
          resp = http.get("/rest/api/latest/issue/#{message}")
        else
          message.gsub!(/^\/issues\/\?jql=/, "")
          message.gsub!(" ", "%20")
          resp = http.get("/rest/api/latest/search/?jql=#{message}")
          search = true
        end
        if resp.code.to_s == '200'
          able_to_connect_jira = true
        else
          error_code = resp.code.to_s
          if resp.code.to_s == '400'
            error_message = resp.data.json(:errorMessages)[-1]
          else
            error_message = ""
          end
        end
        http.close
      end
    rescue => exception
      @logger.fatal exception
      respond "There was an error trying to connect to JIRA. Please ask the admin to check the logs."
    end
  elsif type == "github"
    able_to_connect_github = false
    begin
      search = true if message.include?("?")
      http = NiceHttp.new(config.github.host)
      http.headers.authorization = "token #{config.github.token}"
      message.gsub!(/^\s*</, "")
      message.gsub!(/\>$/, "")
      message.gsub!(/\|.+$/, "")
      message.gsub!(/^#{config.github.host}/, "")
      message.gsub!("https://github.com", "")
      message.slice!(0) if message[0] == "/"
      resp = http.get("/repos/#{message}")
      if resp.code.to_s == '200'
        able_to_connect_github = true
      else
        error_code = resp.code.to_s
        if resp.code.to_s == '401'
          error_message = resp.data.json(:message)[-1]
        else
          error_message = ""
        end
      end
      http.close
    rescue => exception
      @logger.fatal exception
    end
  end

  if !@teams.key?(team_name.to_sym)
    respond "It seems like the team *#{team_name}* doesn't exist\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
  elsif !(all_team_members + config.team_id_masters).flatten.include?("#{user.team_id}_#{user.name}")
    respond "You have to be a member of the team or a Master admin to be able to add a memo to the team."
  elsif type == "jira" and !able_to_connect_jira
    if error_message == ""
      respond "You need to supply the correct credentials for JIRA on the SmartBot settings: `jira: { host: HOST, user: USER, password: PASSWORD }` and a correct JQL string or JQL url"
    else
      respond "You need to supply a correct JQL string or JQL url: #{error_message}"
    end
  else
    topic = :no_topic if topic == ""
    @teams[team_name.to_sym][:memos] ||= []
    if @teams[team_name.to_sym][:memos].empty? and !@teams[team_name.to_sym].key?(:last_memo_id)
      memo_id = 1
    else
      if @teams[team_name.to_sym].key?(:last_memo_id)
        memo_id = @teams[team_name.to_sym][:last_memo_id] + 1
      else
        memo_id = @teams[team_name.to_sym][:memos].memo_id.flatten.max + 1 #backwards compatibility
      end
    end
    @teams[team_name.to_sym][:last_memo_id] = memo_id
    @teams[team_name.to_sym][:memos] << {
      memo_id: memo_id,
      topic: topic,
      type: type,
      privacy: privacy,
      user: "#{user.team_id}_#{user.name}",
      date: Time.now.strftime("%Y-%m-%dT%H:%M:%S.000Z")[0..18],
      message: message,
      status: ":new: ",
      search: search,
      issues: [],
      comments: [],
    }
    update_teams()
    respond "The memo has been added to *#{team_name}* team. (#{memo_id})"
  end
end

#add_memo_team_comment(user, team_name, memo_id, message) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/slack/smart-bot/commands/general/teams/memos/add_memo_team_comment.rb', line 6

def add_memo_team_comment(user, team_name, memo_id, message)
  save_stats(__method__)

  get_teams()
  team_name = team_name.to_sym
  if @teams.key?(team_name)
    if @teams[team_name].key?(:memos)
      memo = @teams[team_name].memos.select { |m| m.memo_id == memo_id.to_i }[-1]
      if memo
        memo.comments ||= []
        memo.comments << { user_name: "#{user.team_id}_#{user.name}", user_id: user.id, message: message, time: Time.now.to_s }
        update_teams()
        if config.simulate
          respond "Comment added to memo #{memo_id} in team #{team_name}"
        else
          react :spiral_note_pad
        end
      else
        respond "Memo *#{memo_id}* does not exist in team *#{team_name}*."
      end
    else
      respond "There are no memos in team *#{team_name}*."
    end
  else
    respond "Team *#{team_name}* does not exist. Call `see teams` to see the list of teams."
  end
end

#delete_memo_team(user, team_name, memo_id) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/slack/smart-bot/commands/general/teams/memos/delete_memo_team.rb', line 6

def delete_memo_team(user, team_name, memo_id)
  save_stats(__method__) if answer.empty?

  get_teams()
  team_id_user = "#{user.team_id}_#{user.name}"

  if @teams.key?(team_name.to_sym)
    assigned_members = @teams[team_name.to_sym].members.values.flatten
    assigned_members.uniq!
    all_team_members = assigned_members.dup
    team_members = []
    if @teams[team_name.to_sym].channels.key?("members")
      @teams[team_name.to_sym].channels["members"].each do |ch|
        get_channels_name_and_id() unless @channels_id.key?(ch)
        tm = get_channel_members(@channels_id[ch])
        tm.each do |m|
           = find_user(m)
          team_members << "#{.team_id}_#{.name}" unless .is_app_user or .is_bot
        end
      end
    end
    team_members.flatten!
    team_members.uniq!
    all_team_members += team_members
    all_team_members.uniq!
  end

  if !@teams.key?(team_name.to_sym)
    respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
  elsif !(all_team_members + config.team_id_masters).flatten.include?(team_id_user)
    respond "You have to be a member of the team or a Master admin to be able to delete a memo of the team."
  elsif !@teams[team_name.to_sym].key?(:memos) or @teams[team_name.to_sym][:memos].empty? or !@teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
    respond "It seems like there is no memo with id #{memo_id}"
  elsif @teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
    memo_selected = @teams[team_name.to_sym][:memos].select { |m| m.memo_id == memo_id.to_i }[-1]
    if memo_selected.privacy == "personal" and memo_selected.user != team_id_user
      respond "Only the creator can delete a personal memo."
    else
      if answer.empty?
        message = @teams[team_name.to_sym][:memos].select { |memo| memo.memo_id == memo_id.to_i }.message.join
        ask "do you really want to delete the memo #{memo_id} (#{message}) from #{team_name} team? (yes/no)"
      else
        case answer
        when /yes/i, /yep/i, /sure/i
          answer_delete
          memos = []
          message = ""
          get_teams()
          @teams[team_name.to_sym][:memos].each do |memo|
            if memo.memo_id != memo_id.to_i
              memos << memo
            else
              message = memo.message
              memos_file = File.join(config.path, "teams", "t_#{team_name}_memos.yaml.deleted")
              File.open(memos_file, "a+") { |file|
                file.flock(File::LOCK_EX)
                file.write("#{Utils::Encryption.encrypt([memo].to_yaml.gsub(/^---\s*$/, ""),config)}\n\n")
                file.flock(File::LOCK_UN)
              }
            end
          end
          @teams[team_name.to_sym][:memos] = memos
          update_teams()
          respond "The memo has been deleted from team #{team_name}: #{message}"
        when /no/i, /nope/i, /cancel/i
          answer_delete
          respond "Ok, the memo was not deleted"
        else
          respond "I don't understand"
          ask "do you really want to delete the memo from #{team_name} team? (yes/no)"
        end
      end
    end
  end
end

#see_memo_team(user, team_name, memo_id) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/slack/smart-bot/commands/general/teams/memos/see_memo_team.rb', line 6

def see_memo_team(user, team_name, memo_id)
  save_stats(__method__)
  get_teams()
  team_name = team_name.to_sym
  if @teams.key?(team_name)
    if @teams[team_name].key?(:memos)
      memo = @teams[team_name].memos.select { |m| m.memo_id == memo_id.to_i }[-1]
      memo_deleted = false
      deleted_memos_file = File.join(config.path, "teams", "t_#{team_name}_memos.yaml.deleted")
      if memo.nil? and File.exist?(deleted_memos_file)
        mydata = File.read(deleted_memos_file)
        all_deleted_memos = []
        mydata.split(/^\s*$/).each do |memo|
          all_deleted_memos << Utils::Encryption.decrypt(memo, config)
        end
        memos = YAML.load(all_deleted_memos.join("\n"))
        memo = memos.select { |m| m.memo_id == memo_id.to_i }[-1]
        memo_deleted = true if memo
      end
      if memo
        if memo_deleted
          uname = memo.user.split("_")[1..-1].join("_")
          messages = ["This memo was deleted from the team #{team_name}.\nOnly the creator (#{uname}) of the memo can get access to it."]
          if memo.user == "#{user.team_id}_#{user.name}"
            messages << "Memo #{memo.memo_id} (#{memo.type}): #{memo.message}"
          end
        else
          messages = see_memos_team(user, type: "all", add_stats: false, name: team_name, memo_id: memo_id)
        end
        if messages.empty?
          messages = ["This memo is private or personal and you don't have access to it on this channel."]
          messages << "Remember in case of a private memo you can only see it in the team members channel."
          messages << "In case of a personal memo you can only see it if you are the creator and you are on a DM."
          respond messages.join("\n")
        else
          if memo.type == "jira" and !memo_deleted
            require "time"
            if config.jira.host == "" or config.jira.user == "" or config.jira.password == ""
              respond "You need to supply the correct credentials for JIRA on the SmartBot settings: `jira: { host: HOST, user: USER, password: PASSWORD }`"
            else
              begin
                http = NiceHttp.new(config.jira.host)
                http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
                resp = http.get("/rest/api/2/issue/#{memo.message}/comment")
                if resp.code.to_s == '200'
                  jira_comments = resp.data.json.comments
                  if !jira_comments.nil? and !jira_comments.empty?
                    messages << "\n_*JIRA Comments:*_"
                    jira_comments.each do |comment|
                      messages << "  *#{comment.author.displayName}* > #{comment.body} _(#{Time.parse(comment.created).strftime("%Y/%m/%d %H:%M")})_"
                    end
                  end
                end
                http.close
              rescue => exception
                @logger.fatal exception
                respond "There was an error trying to connect to JIRA. Please ask the admin to check the logs."
              end
            end
          elsif memo.type == "github" and !memo_deleted
            http = NiceHttp.new(config.github.host)
            http.headers.authorization = "token #{config.github.token}"
            resp = http.get("/repos/#{memo.message}/comments")
            if resp.code.to_s == '200'
              github_comments = resp.data.json
              if !github_comments.nil? and !github_comments.empty?
                messages << "\n_*GitHub Comments:*_"
                github_comments.each do |comment|
                  messages << "  *#{comment.user.}* > #{comment.body} _(#{Time.parse(comment.created_at).strftime("%Y/%m/%d %H:%M")})_"
                end
              end
            end
            http.close
          end
          if memo.key?(:comments) and !memo.comments.empty? and (!memo_deleted or (memo_deleted and memo.user == "#{user.team_id}_#{user.name}"))
            messages << "\n_*Comments:*_"
            memo.comments.each do |comment|
              uname = comment[:user_name].split("_")[1..-1].join("_")
              messages << "  *#{uname}* > #{comment[:message]} _(#{comment[:time][0..15]})_"
            end
          end

          if memo.key?(:comments) and memo.comments.size > 5
            respond_thread messages.join("\n")
          else
            respond messages.join("\n")
          end
        end
      else
        respond "Memo *#{memo_id}* does not exist in team *#{team_name}*."
      end
    else
      respond "There are no memos in team *#{team_name}*."
    end
  else
    respond "Team *#{team_name}* does not exist. Call `see teams` to see the list of teams."
  end
end

#see_memos_team(user, type: "all", name: nil, topic: "", add_stats: true, team: nil, memo_id: nil, precise: true) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/slack/smart-bot/commands/general/teams/memos/see_memos_team.rb', line 6

def see_memos_team(user, type: "all", name: nil, topic: "", add_stats: true, team: nil, memo_id: nil, precise: true)
  save_stats(__method__) if add_stats
  get_teams()
  type = "all" if type.match?(/all\s+memo/i)
  message = []
  if @teams.size > 0
    num_memos = 0
    if team.nil?
      @teams.each do |team_name, teamv|
        if (team_name.to_s == name.to_s) or (name.to_s.gsub("-", "").gsub("_", "") == team_name.to_s)
          team = teamv.deep_copy
          if team.key?(:memos) and team[:memos].size > 0
            num_memos = teamv[:memos].size
          else
            respond "There are no memos for the team #{name}." unless !add_stats
          end
          break
        end
      end
    end
    num_memos = team[:memos].size if team and num_memos == 0
    if team and num_memos > 0
      react :running unless !add_stats
      all_memos = {}
      assigned_members, unassigned_members, not_on_team_channel, channels_members, all_team_members = get_team_members(team)
      users_link = (Thread.current[:dest][0] == "D")
      memos_filtered = []
      all_topics = []
      num_issues = 0
      if memo_id.nil?
        memo_selected = {}
      else
        memo_selected = team[:memos].select { |m| m.memo_id == memo_id.to_i }[-1]
      end
      team[:memos].each do |memo|
        if memo_id.nil? or memo[:memo_id] == memo_id.to_i
          if topic == "" or (memo.topic == topic and precise) or (memo.topic.to_s.downcase.include?(topic.to_s.downcase) and !precise)
            memos_filtered << memo
            all_topics << memo.topic
            if memo.key?(:search) and memo.key?(:issues) and memo.issues.size > 0
              num_issues += memo.issues.size
            else
              num_issues += 1
            end
          end
        end
      end
      all_topics.uniq!
      all_topics.delete(:no_topic)
      if num_issues >= 10 and !add_stats
        message << "   > *_memos_*"
        message << "        There are too many memos to show. "
        message << "        Please use the `see MEMO_TYPE team #{team.name} TOPIC` command."
        message << "        Some available topics: #{all_topics.join(", ")}" if all_topics.size > 0
        message << "        Examples: `see bugs #{team.name} team`, `see all memos #{team.name} team #{all_topics.sample}`, `see tasks #{team.name} team #{all_topics.sample}`"
      elsif memos_filtered.size > 0
        memos_filtered.each do |memo|
          if memo.privacy.empty? or
             (memo.privacy == "private" and (all_team_members.include?("#{user.team_id}_#{user.name}") and (users_link or channels_members.include?(Thread.current[:dest])))) or
             (memo.privacy == "personal" and memo.user == "#{user.team_id}_#{user.name}" and users_link)
            if memo.type == "jira" and config.jira.host != ""
              http = NiceHttp.new(config.jira.host)
              http.headers.authorization = NiceHttpUtils.basic_authentication(user: config.jira.user, password: config.jira.password)
              if memo.message.match?(/^\w+\-\d+$/) or (memo.key?(:search) and !memo.search)
                resp = http.get("/rest/api/latest/issue/#{memo.message}")
                issues = [resp.data.json] if resp.code.to_s == '200'
                memo.search = false
              else
                resp = http.get("/rest/api/latest/search/?jql=#{memo.message}")
                issues = resp.data.json().issues if resp.code.to_s == '200'
                memo.search = true
              end
              if resp.code.to_s == '200'
                unless issues.nil? or issues.empty?
                  if memo.search
                    if memo.key?(:issues)
                      orig_issues = memo.issues.deep_copy.sort
                    else
                      orig_issues = []
                    end
                  end
                  memo_issues = []
                  issues.each do |issue|
                    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 }
                    jira_memo.message = issue.fields.summary
                    memo_issues << jira_memo.message
                    jira_memo.user = issue.fields.reporter.name
                    jira_memo.date = issue.fields.created
                    jira_memo.search = memo.search
                    if issue.fields.key?(:comment) and issue.fields.comment.key?(:comments)
                      jira_memo.comments = issue.fields.comment.comments
                    elsif issue.fields.key?(:comments)
                      jira_memo.comments = issue.fields.comments
                    else
                      jira_memo.comments = []
                    end
                    if memo.topic == :no_topic and !issue.fields.labels.empty?
                      jira_memo.topic = issue.fields.labels.sort.join("_").split(" ").join("_")
                    end
                    if topic == "" or (topic != "" and jira_memo.topic.to_s.downcase == topic.to_s.downcase and precise) or
                        (topic != "" and jira_memo.topic.to_s.downcase.include?(topic.to_s.downcase) and !precise)
                      case issue.fields.issuetype.name
                      when "Story"; jira_memo.type = ":abc:"; jira_memo.mtype = "memo"
                      when "Bug"; jira_memo.type = ":bug:"; jira_memo.mtype = "bug"
                      when "Task"; jira_memo.type = ":clock1:"; jira_memo.mtype = "task"
                      when "New Feature", "Improvement"; jira_memo.type = ":sunny:"; jira_memo.mtype = "feature"
                      else jira_memo.type = ":memo:"; jira_memo.mtype = "memo"
                      end

                      if (type == "all" or type.to_s == jira_memo.mtype.to_s or type == "")
                        case issue.fields.status.statusCategory.name
                        when "Done"; jira_memo.status = ":heavy_check_mark:"
                        when "To Do"; jira_memo.status = ":new:"
                        when "In Progress"; jira_memo.status = ":runner:"
                        else jira_memo.status = ":heavy_minus_sign:"
                        end
                        #todo: check if possible to add link to status instead of jira issue
                        #jira_memo.status = " <#{config.jira.host}/browse/#{issue[:key]}|#{jira_memo.status}> "
                        jira_memo.status += " <#{config.jira.host}/browse/#{issue[:key]}|#{issue[:key]}>"

                        all_memos[jira_memo.topic] ||= []
                        all_memos[jira_memo.topic] << jira_memo
                      end
                    end
                  end
                  if memo.search and orig_issues != memo_issues.sort
                    memo_selected = @teams[team.name.to_sym][:memos].select { |m| m.memo_id == memo.memo_id.to_i }[-1]
                    memo_selected[:issues] = memo_issues.deep_copy
                    memo_selected[:search] = true
                    update_teams()
                  end
                end
              end
              http.close
            elsif memo.type == "github" and config.github.host != ""
              if memo.message.include?("?")
                memo.search = true
              else
                memo.search = false
              end

              http = NiceHttp.new(config.github.host)
              http.headers.authorization = "token #{config.github.token}"
              issue_url = memo.message
              issue_url + "?" unless issue_url.include?("?")
              issue_url += "&per_page=50"

              resp = http.get("/repos/#{issue_url}")
              issues = resp.data.json()
              issues = [issues] unless issues.is_a?(Array)
              if resp.code.to_s == '200'
                unless issues.empty?
                  if memo.search
                    if memo.key?(:issues)
                      orig_issues = memo.issues.deep_copy.sort
                    else
                      orig_issues = []
                    end
                  end
                  memo_issues = []
                  issues.each do |issue|
                    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 }
                    github_memo.message = issue.title
                    memo_issues << github_memo.message
                    github_memo.user = issue.user.
                    github_memo.date = issue.created_at
                    github_memo.search = memo.search
                    if issue.key?(:comments) and issue.comments.to_i > 0
                      github_memo.comments = [issue.comments.to_i]
                    else
                      github_memo.comments = []
                    end

                    if issue.labels.empty?
                      labels = ""
                    else
                      labels = issue.labels.name.sort.join("_").split(" ").join("_")
                    end
                    if memo.topic == :no_topic and !issue.labels.empty?
                      github_memo.topic = labels
                    end
                    if topic == "" or (topic != "" and github_memo.topic.to_s.downcase == topic.to_s.downcase and precise) or
                        (topic != "" and github_memo.topic.to_s.downcase.include?(topic.to_s.downcase) and !precise)
                      case labels
                      when /bug/i; github_memo.type = ":bug:"; github_memo.mtype = "bug"
                      when /docum/i; github_memo.type = ":abc:"; github_memo.mtype = "note"
                      when /task/i; github_memo.type = ":clock1:"; github_memo.mtype = "task"
                      when /enhancem/i, /improvement/i; github_memo.type = ":sunny:"; github_memo.mtype = "feature"
                      else github_memo.type = ":memo:"; github_memo.mtype = "memo"
                      end

                      if (type == "all" or type.to_s == github_memo.mtype.to_s or type == "")
                        if issue.key?(:events_url)
                          resp_events = http.get(issue.events_url)
                          events = resp_events.data.json(:event)
                          issue.state = "in progress" if events.include?("referenced")
                        end
                        case issue.state
                        when "closed"; github_memo.status = ":heavy_check_mark:"
                        when "open"; github_memo.status = ":new:"
                        when "in progress"; github_memo.status = ":runner:"
                        else github_memo.status = ":heavy_minus_sign:"
                        end
                        #todo: check if possible to add link to status instead of github issue
                        github_memo.status += " <#{issue.html_url}|##{issue.number}>"

                        all_memos[github_memo.topic] ||= []
                        all_memos[github_memo.topic] << github_memo
                      end
                    end
                  end
                  if memo.search and orig_issues != memo_issues.sort
                    memo_selected = @teams[team.name.to_sym][:memos].select { |m| m.memo_id == memo.memo_id.to_i }[-1]
                    memo_selected[:issues] = memo_issues.deep_copy
                    memo_selected[:search] = true
                    update_teams()
                  end
                end
              end
              http.close
            else
              if topic == "" or (topic != "" and memo.topic.to_s.downcase == topic.to_s.downcase and precise) or
                  (topic != "" and memo.topic.to_s.downcase.include?(topic.to_s.downcase) and !precise)
                if (type == "all" or type.to_s == memo[:type].to_s or type == "")
                  memo.jira = false
                  memo.github = false
                  all_memos[memo.topic] ||= []
                  case memo.type
                  when "memo"; memo.type = ":memo:"
                  when "note"; memo.type = ":abc:"
                  when "bug"; memo.type = ":bug:"
                  when "task"; memo.type = ":clock1:"
                  when "feature"; memo.type = ":sunny:"
                  when "issue"; memo.type = ":hammer:"
                  else memo.type = ":heavy_minus_sign:"
                  end
                  all_memos[memo.topic] << memo
                end
              end
            end
          end
        end
        if all_memos.empty?
          message << "There are no memos #{name} team #{type} #{topic}." unless !add_stats
        else
          if !add_stats
            if memo_id.nil?
              message << "   > *_memos_*"
            else
              if !memo_id.nil? and memo_selected and memo_selected.key?(:message) and
                 memo_selected.key?(:search) and memo_selected.search
                message << "*_Team #{name.capitalize} memo #{memo_id}_*#{": #{memo_selected.message}"}"
              else
                message << "*_Team #{name.capitalize} memo #{memo_id}_*"
              end
            end
          else
            message << "  > *_#{team.name} team #{type}_*"
          end

          if all_memos.key?(:no_topic)
            all_memos[:no_topic].sort_by { |memo| memo[:date] }.each do |memo|
              case memo.privacy
              when "private"; priv = " `private`"
              when "personal"; priv = " `personal`"
              else priv = ""
              end
              uname = memo.user.split("_")[1..-1].join("_")
              message << "        #{memo.type} #{memo.date.gsub("-", "/")[0..9]}:  #{memo.status} #{memo.message} (#{uname} #{memo.memo_id})#{priv}#{" :spiral_note_pad:" if memo.key?(:comments) and !memo.comments.empty?}#{" :mag:" if memo.key?(:search) and memo.search}"
            end
          end
          all_memos[:no_topic] = []
          all_memos.each do |topic, mems|
            unless mems.empty?
              message << "        _`#{topic}`_:"
              mems.sort_by { |m| m[:date] }.each do |memo|
                case memo.privacy
                when "private"; priv = " `private`"
                when "personal"; priv = " `personal`"
                else priv = ""
                end
                uname = memo.user.split("_")[1..-1].join("_")
                message << "            #{memo.type} #{memo.date.gsub("-", "/")[0..9]}:  #{memo.status} #{memo.message} (#{uname} #{memo.memo_id})#{priv}#{" :spiral_note_pad:" if memo.key?(:comments) and !memo.comments.empty?}#{" :mag:" if memo.key?(:search) and memo.search}"
              end
            end
          end
        end
      else
        message << "There are no memos #{name} team #{type} #{topic}." unless !add_stats
      end
      unreact :running unless !add_stats
    elsif team.nil?
      respond "There is no team named #{name}." unless !add_stats
    end
    if add_stats
      respond message.join("\n")
    else
      return message
    end
  else
    respond "There are no teams added yet\. Use `add team` command to add a team" unless !add_stats
  end
end

#set_memo_status(user, team_name, memo_id, status) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/slack/smart-bot/commands/general/teams/memos/set_memo_status.rb', line 6

def set_memo_status(user, team_name, memo_id, status)
  save_stats(__method__) if answer.empty?

  get_teams()
  if @teams.key?(team_name.to_sym)
    assigned_members = @teams[team_name.to_sym].members.values.flatten
    assigned_members.uniq!
    all_team_members = assigned_members.dup
    team_members = []
    if @teams[team_name.to_sym].channels.key?("members")
      @teams[team_name.to_sym].channels["members"].each do |ch|
        get_channels_name_and_id() unless @channels_id.key?(ch)
        tm = get_channel_members(@channels_id[ch])
        tm.each do |m|
           = find_user(m)
          team_members << "#{.team_id}_#{.name}" unless .is_app_user or .is_bot
        end
      end
    end
    team_members.flatten!
    team_members.uniq!
    all_team_members += team_members
    all_team_members.uniq!
  end

  if !@teams.key?(team_name.to_sym)
    respond "It seems like the team *#{team_name}* doesn't exist.\nRelated commands `add team TEAM_NAME PROPERTIES`, `see team TEAM_NAME`, `see teams`"
  elsif !(all_team_members + config.team_id_masters).flatten.include?("#{user.team_id}_#{user.name}")
    respond "You have to be a member of the team or a Master admin to be able to set the status of a memo."
  elsif !@teams[team_name.to_sym].key?(:memos) or @teams[team_name.to_sym][:memos].empty? or !@teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
    respond "It seems like there is no memo with id #{memo_id}"
  elsif @teams[team_name.to_sym][:memos].memo_id.include?(memo_id.to_i)
    memo_selected = @teams[team_name.to_sym][:memos].select { |m| m.memo_id == memo_id.to_i }[-1]
    if memo_selected.type == "jira" or memo_selected.type == "github"
      #todo: add tests for jira and github
      respond "The memo specified is a #{memo_selected.type} and the status in those cases are linked to the specific issues in #{memo_selected.type}."
    elsif memo_selected.privacy == "personal" and memo_selected.user != "#{user.team_id}_#{user.name}"
      respond "Only the creator can set the status of a personal memo."
    else
      answer_delete
      memos = []
      message = ""
      get_teams()
      @teams[team_name.to_sym][:memos].each do |memo|
        if memo.memo_id == memo_id.to_i
          memo.status = status
          message = memo.message
        end
        memos << memo
      end
      @teams[team_name.to_sym][:memos] = memos
      update_teams()
      respond "The memo status has been updated on team #{team_name}: #{message}"
    end
  end
end