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