rhomobile-cijoe 0.2.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,3 @@
1
+ class CIJoe
2
+ Version = "0.2.1"
3
+ end
@@ -0,0 +1,120 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <link href="<%= cijoe_root %>/screen.css" media="screen" rel="stylesheet" type="text/css" />
5
+ <link rel="shortcut icon" href="<%= cijoe_root %>/favicon.ico" type="image/x-icon" />
6
+ <script type="text/javascript">
7
+ function toggle(id,timestamp,logbase){
8
+ buildid = ""
9
+ logid = ""
10
+ url = "/" + logbase + "/" + timestamp
11
+ if(logbase == 'log') {
12
+ buildid = "build" + id;
13
+ logid = "log" + id;
14
+ } else {
15
+ buildid = "failure" + id;
16
+ logid = "faillog" + id;
17
+ }
18
+ ID = document.getElementById(buildid);
19
+ if(ID.style.display == "") {
20
+ ID.style.display = "none";
21
+ return;
22
+ } else {
23
+ ID.style.display = "";
24
+ }
25
+
26
+ code = document.getElementById(logid)
27
+ if(code.getAttribute('loaded') == 'false') {
28
+ code.setAttribute('loaded', 'true')
29
+ setTimeout(loadXMLDoc(url,logid),1);
30
+ }
31
+ }
32
+ function loadXMLDoc(url,id)
33
+ {
34
+ if (window.XMLHttpRequest)
35
+ {// code for IE7+, Firefox, Chrome, Opera, Safari
36
+ xmlhttp=new XMLHttpRequest();
37
+ }
38
+ else
39
+ {// code for IE6, IE5
40
+ xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
41
+ }
42
+ xmlhttp.open("GET",url,false);
43
+ xmlhttp.send(null);
44
+ document.getElementById(id).innerHTML=xmlhttp.responseText;
45
+ }
46
+ </script>
47
+ </script>
48
+ <title><%= h(joe.project) %>: CI Joe</title>
49
+ </head>
50
+ <body>
51
+ <div class="site">
52
+ <div class="title">
53
+ <a href="<%= cijoe_root %>/">CI Joe</a>
54
+ <span class="extra">because knowing is half the battle</span>
55
+ </div>
56
+
57
+ <div id="home">
58
+ <h1><a href="<%= joe.url %>"><%= joe.project %></a></h1>
59
+ <ul class="posts">
60
+ <% if joe.current_build %>
61
+ <li>
62
+ <span class="date"><%= pretty_time(joe.current_build.started_at) if joe.current_build %></span> &raquo;
63
+ <% if joe.current_build.sha %>
64
+ Building <a href="<%= joe.url %>/commits/<%= joe.current_build.sha %>"><%= joe.current_build.short_sha %></a> <small>(pid: <%= joe.pid %>)</small>
65
+ <% else %>
66
+ Build starting...
67
+ <% end %>
68
+ </li>
69
+ <% else %>
70
+ <li><form method="POST"><input type="submit" value="Build"/></form></li>
71
+ <% end %>
72
+ <% i = 0 %>
73
+ <% joe.old_builds.each do |build| %>
74
+ <li>
75
+ <span class="date"><%= pretty_time(build.finished_at) %></span> &raquo; Built <a href="<%= joe.url %>/commit/<%= build.sha %>"><%= build.short_sha %></a>
76
+ <span class="<%= build.status %>">(<%= build.status %>)</span><span>&nbsp;in <%= "%.2f" % (build.finished_at.to_f - build.started_at.to_f) %> Seconds</span>
77
+ <span>(</span>
78
+ <span class="total"> <%= "#{build.total}" %> : </span>
79
+ <span class="pass"> <%= "#{build.passes}" %> : </span>
80
+ <span class="fail"> <%= "#{build.fails}" %> </span>
81
+ <span>)</span>
82
+ <% if build.failed? %>
83
+ <span class="showlog"> &nbsp; Show/Hide: <a href="#" onclick="toggle('<%= i.to_s %>','<%= build.finished_at.to_i.to_s %>','log')">Output</a> <a href="#" onclick="toggle('<%= i.to_s %>','<%= build.finished_at.to_i.to_s %>','logfail')">Failures</a></span>
84
+ <% end %>
85
+ </li>
86
+ <% if build.failed? %>
87
+ <li id="<%= "build#{i}" %>" style="display:none;"><pre class="terminal"><code id="<%= "log#{i}"%>" loaded="false">Loading...</code></pre><br/></li>
88
+ <li id="<%= "failure#{i}" %>" style="display:none;"><pre class="terminal"><code id="<%= "faillog#{i}"%>" loaded="false">Loading...</code></pre><br/></li>
89
+ <% end %>
90
+ <% i = i + 1 %>
91
+ <% end %>
92
+ </ul>
93
+ </div>
94
+
95
+ <div class="footer">
96
+ <div class="contact">
97
+ <p>
98
+ <a href="http://github.com/defunkt/cijoe/tree/master#readme">Documentation</a><br/>
99
+ <a href="http://github.com/defunkt/cijoe">Source</a><br/>
100
+ <a href="http://github.com/defunkt/cijoe/issues">Issues</a><br/>
101
+ <a href="http://twitter.com/defunkt">Twitter</a>
102
+ </p>
103
+ </div>
104
+ <div class="contact">
105
+ <p>
106
+ Designed by <a href="http://tom.preston-werner.com/">Tom Preston-Werner</a><br/>
107
+ Influenced by <a href="http://integrityapp.com/">Integrity</a><br/>
108
+ Built with <a href="http://sinatrarb.com/">Sinatra</a><br/>
109
+ Keep it simple, Sam.
110
+ </p>
111
+ </div>
112
+ <div class="rss">
113
+ <a href="http://github.com/defunkt/cijoe">
114
+ <img src="<%= cijoe_root %>/octocat.png" alt="Octocat!" />
115
+ </a>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ </body>
120
+ </html>
data/lib/mmmail.rb ADDED
@@ -0,0 +1,291 @@
1
+ # this was taken from
2
+ # http://github.com/lsegal/mmmail/
3
+
4
+ require 'net/smtp'
5
+ require File.expand_path(File.dirname(__FILE__) + '/smtp_tls')
6
+
7
+ module MmMail
8
+ # General exception class when something goes wrong in MmMail
9
+ class TransportError < Exception; end
10
+
11
+ # Handles the transportation of a {Message} to its destination.
12
+ # Basic support for SMTP (through +Net::SMTP+) or +sendmail+.
13
+ #
14
+ # You can either pass a new {Transport::Config} object during transport or use
15
+ # the system wide {Transport::DefaultConfig} object.
16
+ #
17
+ # @example [To set transport to use sendmail]
18
+ # MmMail::Transport::DefaultConfig.method = :sendmail
19
+ # # Note you might need to point to sendmail if it's not in your PATH:
20
+ # MmMail::Transport::DefaultConfig.sendmail_binary = '/path/to/sendmail'
21
+ #
22
+ # @example [To connect to your ISP SMTP server on 587]
23
+ # MmMail::Transport::DefaultConfig.host = 'smtp.myisp.com'
24
+ # MmMail::Transport::DefaultConfig.port = 587
25
+ #
26
+ # @see Transport::Config
27
+ # @see Transport::mail
28
+ class Transport
29
+ # Configuration class for a {Transport}
30
+ class Config
31
+ # Set/get the SMTP host/port information
32
+ attr_accessor :host, :port
33
+
34
+ # Enable TLS
35
+ attr_accessor :enable_tls
36
+
37
+ # Set/get the authentication type (nil for none, :plain, :login or :cram_md5)
38
+ attr_accessor :auth_type
39
+
40
+ # Set/get the AUTH user/password when using SMTP transport.
41
+ attr_accessor :auth_user, :auth_pass
42
+
43
+ # Set/get the email method. Allowed values are +:smtp+ or +:sendmail+.
44
+ attr_accessor :method
45
+
46
+ # Set/get the location of the sendmail binary on the system
47
+ attr_accessor :sendmail_binary
48
+
49
+ # Creates a new Config object set to send via SMTP on
50
+ # localhost:25 with no authentication.
51
+ def initialize
52
+ @method = :smtp # :sendmail
53
+ @host = 'localhost'
54
+ @port = 25
55
+ @auth_type = nil # :plain, :login, :cram_md5
56
+ @auth_user = nil
57
+ @auth_pass = nil
58
+ @sendmail_binary = 'sendmail'
59
+ end
60
+ end
61
+
62
+ # The default system wide configuration used when no custom config
63
+ # object is provided to a Transport object. If you want to make global
64
+ # configuration changes, change the settings here.
65
+ DefaultConfig = Config.new
66
+
67
+ # Creates a new {Transport} object and sends an email.
68
+ #
69
+ # @see #mail
70
+ def self.mail(message, config = nil)
71
+ new(config).mail(message)
72
+ end
73
+
74
+ # Sets a {Config} object to use when sending mail
75
+ attr_accessor :config
76
+
77
+ # Creates a new Transport object to send emails with. To change
78
+ # settings to sendmail or use SMTP auth, set these in the {Config}
79
+ # object.
80
+ #
81
+ # @param [Config] a configuration to use
82
+ # @raise [ArgumentError] if config is not a {Config} object.
83
+ def initialize(config = nil)
84
+ if config && !config.is_a?(Config)
85
+ raise ArgumentError, "expected #{self.class}::Config"
86
+ end
87
+
88
+ @config = config || DefaultConfig
89
+ end
90
+
91
+ # Sends a {Message} object out as an email using the configuration
92
+ # set during initialization.
93
+ #
94
+ # @param [Message] message an email to send
95
+ # @raise [ArgumentError] if message is not a {Message} object
96
+ # @raise [TransportError] if message is not {Message#valid? valid}.
97
+ def mail(message)
98
+ unless Message === message
99
+ raise ArgumentError, "expected MmMail::Message, got #{message.class}"
100
+ end
101
+
102
+ raise TransportError, "invalid message" unless message.valid?
103
+
104
+ send("mail_#{config.method}", message)
105
+ end
106
+
107
+ # Sends a mail through Net::SMTP using the {#config} if
108
+ # any SMTP or hostname information is set.
109
+ #
110
+ # @param [#to_s] message the message to send
111
+ def mail_smtp(message)
112
+ Net::SMTP.enable_tls if config.enable_tls
113
+ Net::SMTP.start(config.host, config.port, 'localhost.localdomain',
114
+ config.auth_user, config.auth_pass, config.auth_type) do |smtp|
115
+ smtp.send_message(message.to_s, message.from, message.recipients_list)
116
+ end
117
+ end
118
+
119
+ # Sends a mail through sendmail using the {Config#sendmail_binary} as the
120
+ # location of the file.
121
+ #
122
+ # @param [#to_s] message the message to send
123
+ # @raise [TransportError] if a problem during execution occured
124
+ def mail_sendmail(message)
125
+ bin, err = config.sendmail_binary, ''
126
+ result = IO.popen("#{bin} -t 2>&1", "w+") do |io|
127
+ io.write(message.to_s)
128
+ io.close_write
129
+ err = io.read.chomp
130
+ end
131
+
132
+ raise TransportError, err if $? != 0
133
+ end
134
+ end
135
+
136
+ # A Message object representing an Email to be passed to a {Transport}.
137
+ class Message
138
+ # Creates a new message with associated fields.
139
+ #
140
+ # @example
141
+ # MmMail::Message.new(:to => 'test@example.com', :body => 'hi')
142
+ #
143
+ # @param [Hash] opts the options to create a message with.
144
+ # @option opts [String] :from ('nobody@localhost') The email's From field
145
+ # @option opts [String] :subject ('') The email's Subject field
146
+ # @option opts [String] :body ('') The email's body (not a header)
147
+ # @option opts [String] :to (nil) The email's To field. List multiple recipients as
148
+ # 'a@b.c, b@c.d', not an array.
149
+ def initialize(opts = {})
150
+ defaults = {
151
+ :from => 'nobody@localhost',
152
+ :subject => '',
153
+ :body => ''
154
+ }
155
+ @headers = defaults.merge(opts)
156
+ end
157
+
158
+ # Allow access of fields by header name or symbolic representation
159
+ #
160
+ # @example
161
+ # m[:x_message_id] = '1234'
162
+ # m['X-Message-Id'] == '1234' # => true
163
+ #
164
+ # @param [String, Symbol] k the header or symbolic header value to lookup.
165
+ # @return [String] the value associated with the field
166
+ def [](k) @headers[translate_header_to_sym(k)] end
167
+
168
+ # Allow access of fields by header name or symbolic representation
169
+ #
170
+ # @example
171
+ # m[:x_message_id] = '1234'
172
+ # m['X-Message-Id'] == '1234' # => true
173
+ #
174
+ def []=(k, v) @headers[translate_header_to_sym(k)] = v end
175
+
176
+ # Override this method to allow any call to obj.meth or obj.meth= to
177
+ # set a header field on this object.
178
+ #
179
+ # @example [To set the field 'X-Message-Id']
180
+ # m.x_message_id = '1234'
181
+ # m.x_message_id == '1234' # => true
182
+ #
183
+ def method_missing(sym, *args)
184
+ if sym.to_s =~ /=$/
185
+ self[sym.to_s[0..-2].to_sym] = args.first
186
+ elsif @headers.has_key?(sym)
187
+ self[sym]
188
+ else
189
+ super
190
+ end
191
+ end
192
+
193
+ # Override this method to verify if a field has been set.
194
+ #
195
+ # @return [Boolean] whether the field was set (or if a regular method
196
+ # is callable.)
197
+ def respond_to?(sym)
198
+ return true if super
199
+ @headers.has_key?(sym)
200
+ end
201
+
202
+ # Returns the message in its full form as expected by an SMTP server.
203
+ #
204
+ # @return [String] the email with headers followed by a body
205
+ def to_s
206
+ [headers, body].join("\n")
207
+ end
208
+
209
+ # Returns all the recipients in the To field.
210
+ #
211
+ # @example
212
+ # m.to = 'a@b.c, b@c.d'
213
+ # m.recipients_list # => ['a@b.c', 'b@c.d']
214
+ #
215
+ # @return [Array<String>] the emails in the To field of the message.
216
+ def recipients_list
217
+ to.split(/\s*,\s*/)
218
+ end
219
+
220
+ # Checks if the message is valid. Validity is based on
221
+ # having the From, To and Subject fields set. From and To
222
+ # must not be empty.
223
+ #
224
+ # @return [Boolean] whether or not the message is a valid e-mail
225
+ def valid?
226
+ [:from, :to].each do |field|
227
+ return false if !self[field] || self[field].empty?
228
+ end
229
+
230
+ self[:subject] ? true : false
231
+ end
232
+
233
+ private
234
+
235
+ # Returns the headers as the RFC822 string.
236
+ #
237
+ # @return [String] the headers in RFC822 format
238
+ def headers
239
+ @headers.reject {|k, v| k == :body }.map do |k, v|
240
+ translate_header_name(k) + ': ' + v + "\n"
241
+ end.join
242
+ end
243
+
244
+ # Translates a header from its symbolic representation to its
245
+ # RFC822 header name or the other way around. If you give in
246
+ # a header name (String) you will get a Symbol, and a Symbol
247
+ # if you give a String.
248
+ #
249
+ # @example
250
+ # msg.translate_header_name(:x_message_id) # => 'X-Message-Id'
251
+ # msg.translate_header_name('Content-Type') # => :content_type
252
+ #
253
+ # @param [String,Symbol] key the header name to translate
254
+ # @return [Symbol,String] the symbolic or header representation of
255
+ # the symbol or header name.
256
+ # @raise [ArgumentError] if key is neither a String or Symbol
257
+ def translate_header_name(key)
258
+ case key
259
+ when String
260
+ key.downcase.tr('-', '_').to_sym
261
+ when Symbol
262
+ key.to_s.capitalize.gsub(/_(.)/) {|m| '-' + m[1].upcase }
263
+ else
264
+ raise ArgumentError, "invalid key type #{key.class}"
265
+ end
266
+ end
267
+
268
+ # Translates a header one-way to the symbolic representation.
269
+ #
270
+ # @param [String, Symbol] key any header or symbolic key
271
+ # @return [Symbol] the symbolic representation of the header name
272
+ # @see #translate_header_name
273
+ def translate_header_to_sym(key)
274
+ return key if Symbol === key
275
+ translate_header_name(key)
276
+ end
277
+ end
278
+
279
+ # Quickly send out an email.
280
+ #
281
+ # @example
282
+ # MmMail.mail(:to => 'me@gmail.com', :body => 'hi!')
283
+ #
284
+ # @param [Hash] opts the hash used to construct the message
285
+ # @param [Transport::Config, nil] config the configuration object to use
286
+ # during transport
287
+ # @see Transport#mail
288
+ def self.mail(opts = {}, config = nil)
289
+ Transport.mail(Message.new(opts), config)
290
+ end
291
+ end
data/lib/smtp_tls.rb ADDED
@@ -0,0 +1,111 @@
1
+ # Include hook code here
2
+
3
+ require 'net/smtp'
4
+ require 'timeout'
5
+
6
+ begin
7
+ require 'openssl'
8
+ rescue LoadError
9
+ end
10
+
11
+ Net::SMTP.class_eval do
12
+
13
+ alias_method :old_initialize, :initialize
14
+ def initialize(*args)
15
+ @usetls = @@usetls
16
+ old_initialize *args
17
+ end
18
+
19
+ @@usetls = false
20
+
21
+ def self.enable_tls()
22
+ @@usetls = true
23
+ end
24
+
25
+ def self.disable_tls()
26
+ @@usetls = false
27
+ end
28
+
29
+ def self.use_tls?()
30
+ @@usetls
31
+ end
32
+
33
+ def use_tls?()
34
+ @usetls
35
+ end
36
+
37
+ def enable_tls()
38
+ print "tls enabled\n"
39
+ @usetls = true
40
+ end
41
+
42
+ def disable_tls()
43
+ @usetls = false
44
+ end
45
+
46
+ def use_tls?()
47
+ @usetls
48
+ end
49
+
50
+ private
51
+ def do_start(helodomain, user, secret, authtype)
52
+ raise IOError 'SMTP session already started' if @started
53
+ if user or secret
54
+ check_auth_method(authtype || DEFAULT_AUTH_TYPE)
55
+ check_auth_args user, secret
56
+ end
57
+
58
+ sock = timeout(@open_timeout) {TCPSocket.open(@address, @port) }
59
+ @socket = Net::InternetMessageIO.new(sock)
60
+ @socket.read_timeout = @read_timeout
61
+
62
+ check_response(critical {recv_response() } )
63
+ do_helo(helodomain)
64
+
65
+ if @usetls
66
+ raise 'openssl is not installed' unless defined?(OpenSSL)
67
+ ssl = OpenSSL::SSL::SSLSocket.new(sock)
68
+ starttls
69
+ ssl.sync_close = true
70
+ ssl.connect
71
+
72
+ @socket = Net::InternetMessageIO.new(ssl)
73
+ @socket.read_timeout = @read_timeout
74
+ do_helo(helodomain)
75
+ end
76
+
77
+ authenticate user, secret, authtype if user
78
+ @started = true
79
+ ensure
80
+ @socket.close if not @started and @socket and not @socket.closed?
81
+ end
82
+
83
+ def do_helo(helodomain)
84
+ begin
85
+ if @esmtp
86
+ ehlo helodomain
87
+ else
88
+ helo helodomain
89
+ end
90
+ rescue Net::ProtocolError
91
+ if @esmtp
92
+ @esmtp = false
93
+ @error_occured = false
94
+ retry
95
+ end
96
+ raise
97
+ end
98
+ end
99
+
100
+ def starttls
101
+ getok('STARTTLS')
102
+ end
103
+
104
+ def quit
105
+ begin
106
+ getok('QUIT')
107
+ rescue EOFError
108
+ # gmail sucks
109
+ end
110
+ end
111
+ end