gitlab-mail-receiver 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ff6d380ad5fe4c2cd3ff4066cfa4c371907a20c
4
+ data.tar.gz: f3018919650a3ac10e1bc1bbe30a4810430edee8
5
+ SHA512:
6
+ metadata.gz: 45eaca00bbd532de05c158f898cf3b9e2cfb05d84ad9069b2e18ef661f44b04c884e4d52e02030b9d90356033f751639f765f937e92e59b49bbf554bd3767b93
7
+ data.tar.gz: 3c186bb6c06e452f6b1c3d2929f145d3053da9ab311ce1440af0460a7e9c8e7644ffe9743a31a5fba1f693438a8030cf441307cb6a6614ad9dd8bf4bb61d9f04
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Li Huashun
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,70 @@
1
+ # GitLab Mail Receiver
2
+
3
+ This gem can allow your GitLab to receive emails to create Issue comments like GitHub.
4
+
5
+ [中文介绍](https://ruby-china.org/topics/27143)
6
+
7
+ ## Features
8
+
9
+ - Receive Email reply to check Issue/MergeRequest and create comment.
10
+ - Very easy to configure on GitLab project.
11
+ - Cleanup the mail content.
12
+
13
+ The WorkFlow:
14
+
15
+ ```
16
+ /--> [ Notify ] ----------------> [Mail Server] <---> [Mail Client]
17
+ { GitLab } ---/ ^
18
+ ^ |
19
+ |-------< [ gitlab-mail-receiver ] <---- check --> |
20
+ ```
21
+
22
+ ## Requirements
23
+
24
+ - GitLab 7.13 (I just tested on this version.)
25
+ - A Email can receive mail via POP3/IMAP.
26
+
27
+
28
+ ## Configuration
29
+
30
+ Add this gem in GitLab project Gemfile:
31
+
32
+ ```rb
33
+ gem 'gitlab-mail-receiver'
34
+ ```
35
+
36
+ Create initialize file in GitLab `config/initializes/gitlab-mail-receiver.rb`:
37
+
38
+ ```rb
39
+ require 'gitlab-mail-receiver'
40
+
41
+ Notify.send(:prepend, MailReceiver::ReplyTo)
42
+
43
+ MailReceiver.configure do
44
+ self.sender = 'xxx@your-mail-host.com'
45
+ self.poll_interval = 5
46
+ self.imap = {
47
+ server: 'imap.your-mail-host.com'
48
+ port: 993
49
+ ssl: true
50
+ username: 'xxx@your-mail-host.com'
51
+ password: 'your-password'
52
+ }
53
+ end
54
+ ```
55
+
56
+ ## Run
57
+
58
+ ```
59
+ $ cd gitlab
60
+ $ bundle exec gitlab-mail-receiver
61
+ ```
62
+
63
+ > NOTE: The daemon log will write to `$rails_root/log/gitlab-mail-receiver.log`
64
+
65
+ ## Run in production
66
+
67
+ ```
68
+ $ cd gitlab
69
+ $ RAILS_ENV=production nohup bundle exec gitlab-mail-receiver &
70
+ ```
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'bundler/setup'
4
+ require_relative '../lib/gitlab-mail-receiver'
5
+
6
+ app_root = ENV['GITLAB_ROOT'] || "."
7
+
8
+ begin
9
+ rails_env = ::File.expand_path('./config/environment', app_root)
10
+ require rails_env
11
+ rescue => e
12
+ puts "You need run this command under GitLab root."
13
+ return
14
+ end
15
+
16
+ logger = Logger.new(File.join(app_root, 'log/gitlab-mail-receiver.log'))
17
+ Mailman.config.logger = logger
18
+ Mailman.config.rails_root = app_root
19
+
20
+ logger.info "Starting Mailman ..."
21
+ Mailman::Application.run do
22
+ to '%user%+%suffix%@%host%' do
23
+ @receiver = MailReceiver::Receiver.new(message, logger: logger)
24
+ @receiver.process!
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ require_relative './mail-receiver/body_parser'
2
+ require_relative './mail-receiver/receiver'
3
+ require_relative './mail-receiver/reply_to'
4
+ require "mailman"
5
+ require 'active_support/core_ext'
6
+
7
+ module MailmanConfig
8
+ extend ActiveSupport::Concern
9
+
10
+ included do
11
+ attr_accessor :sender
12
+ end
13
+ end
14
+
15
+ Mailman::Configuration.send(:include, MailmanConfig)
16
+
17
+ module MailReceiver
18
+ def self.configure(&block)
19
+ Mailman.config.instance_exec(&block)
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ module GitLabMailReceiver
2
+ module Rails
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # Mail body context parser
2
+ module MailReceiver
3
+ module BodyParser
4
+ # might need: mail.body.split(‘—-Original Message-—‘)[0].reverse.split(‘nO’)[-1].reverse for Outlook
5
+ def extract
6
+ self.decoded_part.
7
+ # Most providers start it off with that "On" date line.
8
+ reverse.split(' nO')[-1].reverse.
9
+ # Fancy sigs and sigs need to be discarded
10
+ split(/^-*/).first.chomp.
11
+ # Strip leading and trailing whitespace
12
+ strip
13
+ end
14
+
15
+ def decoded_part
16
+ self.part.decoded
17
+ end
18
+
19
+ def part
20
+ self.mail.multipart? ? self.mail.parts.first.body : self.mail.body
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,115 @@
1
+ module MailReceiver
2
+ class Receiver
3
+ include BodyParser
4
+
5
+ def initialize(message, opts = {})
6
+ @message = message
7
+ @logger = opts[:logger]
8
+ end
9
+
10
+ def mail
11
+ @message
12
+ end
13
+
14
+ def project_slug
15
+ @project_slug ||= id_prefix.split(/!|#/).first
16
+ end
17
+
18
+ def issue_id
19
+ @issue_id ||= id_prefix.split(/!|#/).last
20
+ end
21
+
22
+ def merge_request?
23
+ @merge_request ||= id_prefix.match('!')
24
+ end
25
+
26
+ def body
27
+ return @body if defined?(@body)
28
+ @body = self.extract
29
+ @body
30
+ end
31
+
32
+ def to
33
+ @to ||= @message.to.is_a?(Array) ? @message.to.first : @message.to
34
+ end
35
+
36
+ def from
37
+ @from ||= @message.from.is_a?(Array) ? @message.from.first : @message.from
38
+ end
39
+
40
+ # foo@gmail.com => foo
41
+ def prefix
42
+ @prefix ||= to.split('@').first
43
+ end
44
+
45
+ def inspect
46
+ { project_slug: project_slug, issue_id: issue_id, merge_request: merge_request?, to: to, body: body}
47
+ end
48
+
49
+ def project
50
+ @project ||= Project.find_with_namespace(project_slug)
51
+ rescue => e
52
+ logger.warn "Project: #{project_slug} record not found."
53
+ end
54
+
55
+ def process!
56
+ if current_user.blank?
57
+ logger.warn "Reply user: #{from} not found user in GitLab."
58
+ return
59
+ end
60
+
61
+ if project.blank?
62
+ logger.warn "Project #{project_slug} is not found."
63
+ return
64
+ end
65
+
66
+ note_params = merge_request? ? process_mr! : process_issue!
67
+ return if note_params.blank?
68
+
69
+ note_params[:project_id] = project.id
70
+ note_params[:note] = body
71
+
72
+ @note = Notes::CreateService.new(project, current_user, note_params).execute
73
+ logger.info "Note #{@note.id} created."
74
+ end
75
+
76
+ def process_mr!
77
+ @mr = project.merge_requests.find_by(iid: self.issue_id)
78
+ if @mr.blank?
79
+ logger.warn "MergeRequest #{self.issue_id} not found."
80
+ return nil
81
+ end
82
+
83
+ logger.info "Found MergeRequest: #{@mr.id}"
84
+ { noteable_type: 'MergeRequest', noteable_id: @mr.id }
85
+ end
86
+
87
+ def process_issue!
88
+ @issue = project.issues.find_by(iid: self.issue_id)
89
+ if @issue.blank?
90
+ logger.warn "Issue #{self.issue_id} not found."
91
+ return nil
92
+ end
93
+
94
+ logger.info "Found issue: #{@issue.id}"
95
+ { noteable_type: 'Issue', noteable_id: @issue.id }
96
+ end
97
+
98
+ def current_user
99
+ @current_user ||= User.find_by_any_email(from)
100
+ end
101
+
102
+ private
103
+
104
+ def logger
105
+ @logger ||= Logger.new($stdout)
106
+ end
107
+
108
+ # foo+chair/chair!123 => chair/chair!123
109
+ def id_prefix
110
+ return @id_prefix if defined?(@id_prefix)
111
+ @id_prefix = prefix.split('+').last
112
+ return @id_prefix
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,70 @@
1
+ require 'mailman'
2
+
3
+ module MailReceiver
4
+ module ReplyTo
5
+ def mail_new_thread(model, headers = {}, &block)
6
+ headers['Message-ID'] = message_id(model)
7
+ headers['X-GitLab-Project'] = "#{@project.name} | " if @project
8
+
9
+ # Mail receiver
10
+ headers[:reply_to] = reply_to_address(model)
11
+
12
+ mail(headers, &block)
13
+ end
14
+
15
+ def mail_answer_thread(model, headers = {}, &block)
16
+ headers['In-Reply-To'] = message_id(model)
17
+ headers['References'] = message_id(model)
18
+ headers['X-GitLab-Project'] = "#{@project.name} | " if @project
19
+
20
+ if headers[:subject]
21
+ headers[:subject].prepend('Re: ')
22
+ end
23
+
24
+ # Mail receiver
25
+ headers[:reply_to] = reply_to_address(model)
26
+
27
+ mail(headers, &block)
28
+ end
29
+
30
+ protected
31
+ def reply_to_address(model)
32
+ able_path = convert_able_path(model)
33
+ return default_email_reply_to if able_path.blank?
34
+ return default_email_reply_to if @project.blank?
35
+
36
+ slug = "#{@project.path_with_namespace}#{able_path}"
37
+
38
+ Mailman.config.sender.sub('@', "+#{slug}@")
39
+ end
40
+
41
+
42
+
43
+ def default_email_reply_to
44
+ Gitlab.config.gitlab.email_reply_to
45
+ end
46
+
47
+ def convert_able_path(model)
48
+ if model.class.name == 'Issue'
49
+ return "##{model.iid}"
50
+ end
51
+
52
+ if model.class.name == 'MergeRequest'
53
+ return "!#{model.iid}"
54
+ end
55
+
56
+
57
+ if model.class.name == 'Note'
58
+ if model.noteable_type == 'Issue' && model.noteable
59
+ return "##{model.noteable.iid}"
60
+ end
61
+
62
+ if model.noteable_type == 'MergeRequest' && model.noteable
63
+ return "!#{model.noteable.iid}"
64
+ end
65
+ end
66
+
67
+ return nil
68
+ end
69
+ end
70
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gitlab-mail-receiver
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jason Lee
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mailman
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.7.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.7.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ description: Allow your GitLab to receive mails to create Issue comment.
42
+ email:
43
+ - huacnlee@gmail.com
44
+ executables:
45
+ - gitlab-mail-receiver
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - LICENSE
50
+ - README.md
51
+ - bin/gitlab-mail-receiver
52
+ - lib/gitlab-mail-receiver.rb
53
+ - lib/gitlab-mail-receiver/railtie.rb
54
+ - lib/mail-receiver/body_parser.rb
55
+ - lib/mail-receiver/receiver.rb
56
+ - lib/mail-receiver/reply_to.rb
57
+ homepage: http://github.com/huacnlee/gitlab-mail-receiver
58
+ licenses:
59
+ - MIT
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.3.6
75
+ requirements: []
76
+ rubyforge_project:
77
+ rubygems_version: 2.4.7
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: Allow your GitLab to receive mails to create Issue comment
81
+ test_files: []
82
+ has_rdoc: