##// END OF EJS Templates
remove trailing white-spaces from extra/mail_handler/rdm-mailhandler.rb...
Toshi MARUYAMA -
r9158:be04f1dd6270
parent child
Show More
@@ -1,187 +1,187
1 #!/usr/bin/env ruby
1 #!/usr/bin/env ruby
2
2
3 # == Synopsis
3 # == Synopsis
4 #
4 #
5 # Reads an email from standard input and forward it to a Redmine server
5 # Reads an email from standard input and forward it to a Redmine server
6 # through a HTTP request.
6 # through a HTTP request.
7 #
7 #
8 # == Usage
8 # == Usage
9 #
9 #
10 # rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>
10 # rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>
11 #
11 #
12 # == Arguments
12 # == Arguments
13 #
13 #
14 # -u, --url URL of the Redmine server
14 # -u, --url URL of the Redmine server
15 # -k, --key Redmine API key
15 # -k, --key Redmine API key
16 #
16 #
17 # General options:
17 # General options:
18 # --unknown-user=ACTION how to handle emails from an unknown user
18 # --unknown-user=ACTION how to handle emails from an unknown user
19 # ACTION can be one of the following values:
19 # ACTION can be one of the following values:
20 # ignore: email is ignored (default)
20 # ignore: email is ignored (default)
21 # accept: accept as anonymous user
21 # accept: accept as anonymous user
22 # create: create a user account
22 # create: create a user account
23 # --no-permission-check disable permission checking when receiving
23 # --no-permission-check disable permission checking when receiving
24 # the email
24 # the email
25 # --key-file=PATH path to a file that contains the Redmine
25 # --key-file=PATH path to a file that contains the Redmine
26 # API key (use this option instead of --key
26 # API key (use this option instead of --key
27 # if you don't the key to appear in the
27 # if you don't the key to appear in the
28 # command line)
28 # command line)
29 # --no-check-certificate do not check server certificate
29 # --no-check-certificate do not check server certificate
30 # -h, --help show this help
30 # -h, --help show this help
31 # -v, --verbose show extra information
31 # -v, --verbose show extra information
32 # -V, --version show version information and exit
32 # -V, --version show version information and exit
33 #
33 #
34 # Issue attributes control options:
34 # Issue attributes control options:
35 # -p, --project=PROJECT identifier of the target project
35 # -p, --project=PROJECT identifier of the target project
36 # -s, --status=STATUS name of the target status
36 # -s, --status=STATUS name of the target status
37 # -t, --tracker=TRACKER name of the target tracker
37 # -t, --tracker=TRACKER name of the target tracker
38 # --category=CATEGORY name of the target category
38 # --category=CATEGORY name of the target category
39 # --priority=PRIORITY name of the target priority
39 # --priority=PRIORITY name of the target priority
40 # -o, --allow-override=ATTRS allow email content to override attributes
40 # -o, --allow-override=ATTRS allow email content to override attributes
41 # specified by previous options
41 # specified by previous options
42 # ATTRS is a comma separated list of attributes
42 # ATTRS is a comma separated list of attributes
43 #
43 #
44 # == Examples
44 # == Examples
45 # No project specified. Emails MUST contain the 'Project' keyword:
45 # No project specified. Emails MUST contain the 'Project' keyword:
46 #
46 #
47 # rdm-mailhandler --url http://redmine.domain.foo --key secret
47 # rdm-mailhandler --url http://redmine.domain.foo --key secret
48 #
48 #
49 # Fixed project and default tracker specified, but emails can override
49 # Fixed project and default tracker specified, but emails can override
50 # both tracker and priority attributes using keywords:
50 # both tracker and priority attributes using keywords:
51 #
51 #
52 # rdm-mailhandler --url https://domain.foo/redmine --key secret \\
52 # rdm-mailhandler --url https://domain.foo/redmine --key secret \\
53 # --project foo \\
53 # --project foo \\
54 # --tracker bug \\
54 # --tracker bug \\
55 # --allow-override tracker,priority
55 # --allow-override tracker,priority
56
56
57 require 'net/http'
57 require 'net/http'
58 require 'net/https'
58 require 'net/https'
59 require 'uri'
59 require 'uri'
60 require 'getoptlong'
60 require 'getoptlong'
61 require 'rdoc/usage'
61 require 'rdoc/usage'
62
62
63 module Net
63 module Net
64 class HTTPS < HTTP
64 class HTTPS < HTTP
65 def self.post_form(url, params, headers, options={})
65 def self.post_form(url, params, headers, options={})
66 request = Post.new(url.path)
66 request = Post.new(url.path)
67 request.form_data = params
67 request.form_data = params
68 request.basic_auth url.user, url.password if url.user
68 request.basic_auth url.user, url.password if url.user
69 request.initialize_http_header(headers)
69 request.initialize_http_header(headers)
70 http = new(url.host, url.port)
70 http = new(url.host, url.port)
71 http.use_ssl = (url.scheme == 'https')
71 http.use_ssl = (url.scheme == 'https')
72 if options[:no_check_certificate]
72 if options[:no_check_certificate]
73 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
73 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
74 end
74 end
75 http.start {|h| h.request(request) }
75 http.start {|h| h.request(request) }
76 end
76 end
77 end
77 end
78 end
78 end
79
79
80 class RedmineMailHandler
80 class RedmineMailHandler
81 VERSION = '0.1'
81 VERSION = '0.1'
82
82
83 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key, :no_check_certificate
83 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key, :no_check_certificate
84
84
85 def initialize
85 def initialize
86 self.issue_attributes = {}
86 self.issue_attributes = {}
87
87
88 opts = GetoptLong.new(
88 opts = GetoptLong.new(
89 [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
89 [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
90 [ '--version', '-V', GetoptLong::NO_ARGUMENT ],
90 [ '--version', '-V', GetoptLong::NO_ARGUMENT ],
91 [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
91 [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
92 [ '--url', '-u', GetoptLong::REQUIRED_ARGUMENT ],
92 [ '--url', '-u', GetoptLong::REQUIRED_ARGUMENT ],
93 [ '--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
93 [ '--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
94 [ '--key-file', GetoptLong::REQUIRED_ARGUMENT],
94 [ '--key-file', GetoptLong::REQUIRED_ARGUMENT],
95 [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
95 [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
96 [ '--status', '-s', GetoptLong::REQUIRED_ARGUMENT ],
96 [ '--status', '-s', GetoptLong::REQUIRED_ARGUMENT ],
97 [ '--tracker', '-t', GetoptLong::REQUIRED_ARGUMENT],
97 [ '--tracker', '-t', GetoptLong::REQUIRED_ARGUMENT],
98 [ '--category', GetoptLong::REQUIRED_ARGUMENT],
98 [ '--category', GetoptLong::REQUIRED_ARGUMENT],
99 [ '--priority', GetoptLong::REQUIRED_ARGUMENT],
99 [ '--priority', GetoptLong::REQUIRED_ARGUMENT],
100 [ '--allow-override', '-o', GetoptLong::REQUIRED_ARGUMENT],
100 [ '--allow-override', '-o', GetoptLong::REQUIRED_ARGUMENT],
101 [ '--unknown-user', GetoptLong::REQUIRED_ARGUMENT],
101 [ '--unknown-user', GetoptLong::REQUIRED_ARGUMENT],
102 [ '--no-permission-check', GetoptLong::NO_ARGUMENT],
102 [ '--no-permission-check', GetoptLong::NO_ARGUMENT],
103 [ '--no-check-certificate', GetoptLong::NO_ARGUMENT]
103 [ '--no-check-certificate', GetoptLong::NO_ARGUMENT]
104 )
104 )
105
105
106 opts.each do |opt, arg|
106 opts.each do |opt, arg|
107 case opt
107 case opt
108 when '--url'
108 when '--url'
109 self.url = arg.dup
109 self.url = arg.dup
110 when '--key'
110 when '--key'
111 self.key = arg.dup
111 self.key = arg.dup
112 when '--key-file'
112 when '--key-file'
113 begin
113 begin
114 self.key = File.read(arg).strip
114 self.key = File.read(arg).strip
115 rescue Exception => e
115 rescue Exception => e
116 $stderr.puts "Unable to read the key from #{arg}: #{e.message}"
116 $stderr.puts "Unable to read the key from #{arg}: #{e.message}"
117 exit 1
117 exit 1
118 end
118 end
119 when '--help'
119 when '--help'
120 usage
120 usage
121 when '--verbose'
121 when '--verbose'
122 self.verbose = true
122 self.verbose = true
123 when '--version'
123 when '--version'
124 puts VERSION; exit
124 puts VERSION; exit
125 when '--project', '--status', '--tracker', '--category', '--priority'
125 when '--project', '--status', '--tracker', '--category', '--priority'
126 self.issue_attributes[opt.gsub(%r{^\-\-}, '')] = arg.dup
126 self.issue_attributes[opt.gsub(%r{^\-\-}, '')] = arg.dup
127 when '--allow-override'
127 when '--allow-override'
128 self.allow_override = arg.dup
128 self.allow_override = arg.dup
129 when '--unknown-user'
129 when '--unknown-user'
130 self.unknown_user = arg.dup
130 self.unknown_user = arg.dup
131 when '--no-permission-check'
131 when '--no-permission-check'
132 self.no_permission_check = '1'
132 self.no_permission_check = '1'
133 when '--no-check-certificate'
133 when '--no-check-certificate'
134 self.no_check_certificate = true
134 self.no_check_certificate = true
135 end
135 end
136 end
136 end
137
137
138 RDoc.usage if url.nil?
138 RDoc.usage if url.nil?
139 end
139 end
140
140
141 def submit(email)
141 def submit(email)
142 uri = url.gsub(%r{/*$}, '') + '/mail_handler'
142 uri = url.gsub(%r{/*$}, '') + '/mail_handler'
143
143
144 headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
144 headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
145
145
146 data = { 'key' => key, 'email' => email,
146 data = { 'key' => key, 'email' => email,
147 'allow_override' => allow_override,
147 'allow_override' => allow_override,
148 'unknown_user' => unknown_user,
148 'unknown_user' => unknown_user,
149 'no_permission_check' => no_permission_check}
149 'no_permission_check' => no_permission_check}
150 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
150 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
151
151
152 debug "Posting to #{uri}..."
152 debug "Posting to #{uri}..."
153 response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
153 response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
154 debug "Response received: #{response.code}"
154 debug "Response received: #{response.code}"
155
155
156 case response.code.to_i
156 case response.code.to_i
157 when 403
157 when 403
158 warn "Request was denied by your Redmine server. " +
158 warn "Request was denied by your Redmine server. " +
159 "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
159 "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
160 return 77
160 return 77
161 when 422
161 when 422
162 warn "Request was denied by your Redmine server. " +
162 warn "Request was denied by your Redmine server. " +
163 "Possible reasons: email is sent from an invalid email address or is missing some information."
163 "Possible reasons: email is sent from an invalid email address or is missing some information."
164 return 77
164 return 77
165 when 400..499
165 when 400..499
166 warn "Request was denied by your Redmine server (#{response.code})."
166 warn "Request was denied by your Redmine server (#{response.code})."
167 return 77
167 return 77
168 when 500..599
168 when 500..599
169 warn "Failed to contact your Redmine server (#{response.code})."
169 warn "Failed to contact your Redmine server (#{response.code})."
170 return 75
170 return 75
171 when 201
171 when 201
172 debug "Proccessed successfully"
172 debug "Proccessed successfully"
173 return 0
173 return 0
174 else
174 else
175 return 1
175 return 1
176 end
176 end
177 end
177 end
178
178
179 private
179 private
180
180
181 def debug(msg)
181 def debug(msg)
182 puts msg if verbose
182 puts msg if verbose
183 end
183 end
184 end
184 end
185
185
186 handler = RedmineMailHandler.new
186 handler = RedmineMailHandler.new
187 exit(handler.submit(STDIN.read))
187 exit(handler.submit(STDIN.read))
General Comments 0
You need to be logged in to leave comments. Login now