class SchleuderGitlabTicketing::List

Public Class Methods

new(name, config) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 8
def initialize(name, config)
  @name = name
  @config = config
end

Public Instance Methods

configured?() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 13
def configured?
  unless @config['project'] && @config['namespace'] && @config['gitlab'] && gitlab && project
    return false
  end
  true
end
gitlab() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 67
def gitlab
  @gitlab ||= if @config['gitlab'].is_a?(Gitlab::Client)
    @config['gitlab']
  else
    super
  end
end
process(mail) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 20
def process(mail)
  return false if ignore_mail?(mail)
  ticket_id = get_ticket_id(mail.subject)
  ticket = ticket_id ? get_ticket(ticket_id) : nil

  if (title = clean_subject(mail.subject)).nil? || title.empty?
    title = "Request from #{mail.from.first}"
  end
  desc = desc(mail)
  updates = {}
  labels = Set.new

  if !ticket
    ticket = create_ticket(title, desc)
    ticket_id = ticket.iid
    mail.subject = update_subject(mail.subject, ticket_id)
  else
    labels = Set.new(ticket.labels)
    comment_ticket(ticket_id,desc)
    assignee_id = team_member_id(mail.from.first)
    if assignee_id && ((as = ticket.assignee).nil? || as.id != assignee_id)
      updates[:assignee_id] = assignee_id
    end
  end

  bc = be_closed?(mail.subject)
  tc = ticket_closed?(ticket)

  if !tc && bc
    labels.delete('inprocess')
    updates[:state_event] = 'close'
  elsif !tc && !bc
    labels << 'inprocess' if updates[:assignee_id]
  elsif tc && !bc
    labels << 'inprocess'
    updates[:state_event] = 'reopen'
  end
  if labels.empty? && (updates[:state_event] == 'close')
    # make sure we remove the inprocess label
    updates[:labels] = ''
  elsif !labels.empty? && (labels.to_a.sort != ticket.labels.sort)
    updates[:labels] = labels.to_a.join(',')
  end
  update_ticket(ticket_id, updates)
  true
end
sender_filters() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 75
def sender_filters
  Array(@config['sender_filters'])
end
subject_filters() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 78
def subject_filters
  Array(@config['subject_filters'])
end

Private Instance Methods

be_closed?(subject) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 91
def be_closed?(subject)
  !(subject =~ /\[ok\]/).nil?
end
clean_subject(subj) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 186
def clean_subject(subj)
  subj.nil? ? nil : subj.gsub(/^(Re|Fw):\s*/,'').gsub(/\[[<>]?#{list_subj}\]\s*/,'').gsub(/\s*\[#{Regexp.escape(ticket_prefix)}#\d+\](\s*$)?/,'').gsub(/\s*\[ok\](\s*$)?/,'').strip
end
comment_ticket(ticket_id, desc) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 111
def comment_ticket(ticket_id, desc)
  gitlab.create_issue_note(project.id, ticket_id, desc)
end
create_ticket(title, desc) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 106
def create_ticket(title, desc)
  opts = { description: desc }
  gitlab.create_issue(project.id, title, opts)
end
desc(mail) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 83
def desc(mail)
  res = []
  res << "From: #{mail.from.first}"
  res << "Message-Id: #{mail.message_id}"
  res << "Subject: #{mail.subject || '[not set]'}"
  res.join("\n\n")
end
find_user_id(username_or_email) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 159
def find_user_id(username_or_email)
  users = gitlab.user_search(username_or_email)
  # did we look for an email => exact match
  # or by username?
  user = if username_or_email =~ /@/
    users.first
  else
    users.find do |u|
      u.name == username_or_email || u.username == username_or_email
    end
  end
  user.nil? ? nil : user.id
rescue Gitlab::Error::NotFound => e
  nil
end
get_ticket(id) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 115
def get_ticket(id)
  gitlab.issue(project.id, id)
rescue Gitlab::Error::NotFound => e
  nil
end
get_ticket_id(str) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 121
def get_ticket_id(str)
  if str && (m = str.match(/.*\[#{Regexp.escape(ticket_prefix)}\#(\d+)\].*/)) && m[1]
    m[1].to_i
  else
    nil
  end
end
ignore_mail?(mail) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 175
def ignore_mail?(mail)
  return true if mail.respond_to?(:[]) && mail['X-Spam-Flag'].to_s.downcase == 'yes'
  return true if sender_filters.any?{|s| mail.from.first =~ /#{s}/ }
  return true if subject_filters.any?{|s| mail.subject =~ /#{s}/ }
  false
end
issues() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 135
def issues
  gitlab.issues(p.id)
end
list_subj() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 190
def list_subj
  @list_subj ||= (@config['list_subj'] || @name.split('@',2).first)
end
project() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 129
def project
  @project ||= gitlab.search_projects(@config['project']).find{|p| p.namespace.name == @config['namespace'] && p.name == @config['project'] }
rescue Gitlab::Error::NotFound => e
  nil
end
project_member?(project, user_id) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 149
def project_member?(project, user_id)
  begin
    gitlab.team_member(project.id, user_id)
  rescue Gitlab::Error::NotFound
    gitlab.group_member(project.namespace.id, user_id)
  end
rescue Gitlab::Error::NotFound => e
  nil
end
team_member_id(email) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 139
def team_member_id(email)
  if user_id = find_user_id(email)
    user_id if project_member?(project, user_id)
  else
    nil
  end
rescue Gitlab::Error::NotFound => e
  nil
end
ticket_closed?(ticket) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 95
def ticket_closed?(ticket)
  ticket.state == 'closed'
end
ticket_prefix() click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 182
def ticket_prefix
  @ticket_prefix ||= (@config['ticket_prefix'] || "gl/#{@config['project']}")
end
update_subject(subject,ticket_id) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 194
def update_subject(subject,ticket_id)
  [subject.nil? ? nil : subject.gsub(/(\s)?\[#{Regexp.escape(ticket_prefix)}#\d+\]/,''), "[#{ticket_prefix}##{ticket_id}]"].compact.join(' ')
end
update_ticket(ticket_id,updates) click to toggle source
# File lib/schleuder-gitlab-ticketing/list.rb, line 99
def update_ticket(ticket_id,updates)
  return if updates.empty?
  gitlab.edit_issue(project.id, ticket_id, updates)
rescue Gitlab::Error::NotFound => e
  nil
end