rq 3.3.0 → 3.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/a.rb +1 -0
- data/bin/rq +10 -0
- data/bin/rqmailer +45 -26
- data/lib/rq/cron.rb +16 -4
- data/lib/rq/jobqueue.rb +4 -1
- data/lib/rq/updater.rb +0 -1
- data/rails/data/config +1 -1
- data/rails/example.rb +5 -2
- metadata +9 -23
- data/q/bin/rqmailer +0 -16
- data/q/db +0 -0
- data/q/db.schema +0 -28
- data/q/lock +0 -0
- data/rails/q/bin/rqmailer +0 -847
- data/rails/q/db +0 -0
- data/rails/q/db.schema +0 -28
- data/rails/q/lock +0 -0
data/bin/rq
CHANGED
@@ -424,6 +424,8 @@
|
|
424
424
|
tail
|
425
425
|
when 'cron'
|
426
426
|
cron
|
427
|
+
when 'crontab'
|
428
|
+
crontab
|
427
429
|
else
|
428
430
|
raise "invalid mode <#{ @mode }>"
|
429
431
|
end
|
@@ -717,6 +719,14 @@
|
|
717
719
|
cron.cron
|
718
720
|
#--}}}
|
719
721
|
end
|
722
|
+
def crontab
|
723
|
+
#--{{{
|
724
|
+
argv.unshift 'tab'
|
725
|
+
init_logging
|
726
|
+
cron = Cron::new self
|
727
|
+
cron.cron
|
728
|
+
#--}}}
|
729
|
+
end
|
720
730
|
|
721
731
|
def dump_ios which, jids
|
722
732
|
#--{{{
|
data/bin/rqmailer
CHANGED
@@ -32,8 +32,6 @@ Main {
|
|
32
32
|
argument_required
|
33
33
|
}
|
34
34
|
|
35
|
-
SMTP = {}
|
36
|
-
|
37
35
|
def run #--{{{
|
38
36
|
indicating_that_rqmailer_failed do
|
39
37
|
setup
|
@@ -51,6 +49,10 @@ Main {
|
|
51
49
|
@config = {}
|
52
50
|
@rq = ENV['RQ']
|
53
51
|
@rq_data = ENV['RQ_DATA']
|
52
|
+
if(@rq.nil? and @rq_data.nil? and argv.first and test(?d, argv.first))
|
53
|
+
@rq_data = File.expand_path argv.shift
|
54
|
+
@rq = true
|
55
|
+
end
|
54
56
|
@exit_status = 0
|
55
57
|
@exception = nil
|
56
58
|
@template_expander = TemplateExpander.instance
|
@@ -163,38 +165,55 @@ Main {
|
|
163
165
|
def mail_message #--{{{
|
164
166
|
build_mail!
|
165
167
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
168
|
+
deliver = @config.has_key?('smtp') ? 'smtp' : 'sendmail'
|
169
|
+
|
170
|
+
if deliver == 'smtp'
|
171
|
+
hash = @config['smtp'] || {}
|
172
|
+
server = hash['server']
|
173
|
+
port = Integer hash['port']
|
174
|
+
hostname = hash['hostname'] || @hostname || 'localhost.localdomain'
|
175
|
+
account = hash['account']
|
176
|
+
password = hash['password']
|
177
|
+
authtype = hash['authtype'] || :plain
|
178
|
+
tls = hash['tls'] ? true : false
|
179
|
+
else
|
180
|
+
sendmail = @config['sendmail'] || '/usr/sbin/sendmail -i -t'
|
181
|
+
end
|
174
182
|
|
175
183
|
if @belch
|
176
184
|
if @send
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
185
|
+
case deliver
|
186
|
+
when 'smtp'
|
187
|
+
smtp = Net::SMTP.new server, port
|
188
|
+
smtp.set_debug_output STDERR
|
189
|
+
smtp.start hostname, account, password, authtype, tls do |connection|
|
190
|
+
connection.send_message @mail, account, @mail.recipients
|
191
|
+
end
|
192
|
+
when 'sendmail'
|
193
|
+
IO.popen(sendmail, 'w+') do |pipe|
|
194
|
+
pipe.write @mail.to_s.gsub(%r/\r/,'')
|
195
|
+
pipe.flush
|
196
|
+
end
|
181
197
|
end
|
182
198
|
end
|
183
199
|
STDOUT.puts @mail
|
184
200
|
else
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
201
|
+
case deliver
|
202
|
+
when 'smtp'
|
203
|
+
debug_output = open File.join(@rq_data, 'smtp'), 'w'
|
204
|
+
at_exit{ debug_output.close rescue nil }
|
205
|
+
smtp = Net::SMTP.new server, port
|
206
|
+
smtp.set_debug_output debug_output
|
207
|
+
smtp.start hostname, account, password, authtype, tls do |connection|
|
208
|
+
connection.send_message @mail, account, @mail.recipients
|
209
|
+
end
|
210
|
+
when 'sendmail'
|
211
|
+
IO.popen(sendmail, 'w+') do |pipe|
|
212
|
+
pipe.write @mail.to_s.gsub(%r/\r/,'')
|
213
|
+
pipe.flush
|
214
|
+
end
|
192
215
|
end
|
193
|
-
|
194
|
-
if @rq
|
195
|
-
open(File.join(@rq_data, 'mail'), 'w'){|fd| fd.write @mail}
|
196
|
-
end
|
197
|
-
|
216
|
+
open(File.join(@rq_data, 'mail'), 'w'){|fd| fd.write @mail} rescue nil
|
198
217
|
STDERR.puts @mail
|
199
218
|
end
|
200
219
|
|
data/lib/rq/cron.rb
CHANGED
@@ -74,19 +74,29 @@ unless defined? $__rq_cron__
|
|
74
74
|
puts entry
|
75
75
|
end
|
76
76
|
end
|
77
|
+
#--}}}
|
78
|
+
end
|
79
|
+
def cron_tab
|
80
|
+
#--{{{
|
81
|
+
opts = @options.map{|kv| "'--#{ kv.join('=') }'" }.join(' ')
|
82
|
+
entries = [
|
83
|
+
"*/15 * * * * #{ @cmd } start #{ opts } ###md5:#{ @md5[:start] }\n",
|
84
|
+
"0 0 * * * #{ @cmd } rotate ###md5:#{ @md5[:start] }\n",
|
85
|
+
]
|
86
|
+
puts entries
|
77
87
|
#--}}}
|
78
88
|
end
|
79
89
|
def cron_start
|
80
90
|
#--{{{
|
81
91
|
cron_add
|
82
|
-
main.start
|
92
|
+
#main.start
|
83
93
|
#--}}}
|
84
94
|
end
|
85
95
|
def cron_delete
|
86
96
|
#--{{{
|
87
97
|
lines = `crontab -l`.split "\n"
|
88
98
|
|
89
|
-
re = %r/###\s*md5
|
99
|
+
re = %r/###\s*md5:(#{ @md5[:start] })/
|
90
100
|
found = []
|
91
101
|
|
92
102
|
lines.each_with_index do |line, idx|
|
@@ -100,9 +110,11 @@ unless defined? $__rq_cron__
|
|
100
110
|
found << idx if(re.match entry)
|
101
111
|
end
|
102
112
|
|
113
|
+
p found
|
114
|
+
|
103
115
|
unless found.empty?
|
104
|
-
deleted =
|
105
|
-
lines.delete_at
|
116
|
+
deleted = []
|
117
|
+
found.each{|idx| deleted << lines[idx]; lines.delete_at(idx)}
|
106
118
|
tmp = Tempfile::new Process::pid.to_s
|
107
119
|
lines.each{|line| tmp << "#{ line }\n"}
|
108
120
|
tmp.close
|
data/lib/rq/jobqueue.rb
CHANGED
@@ -239,7 +239,10 @@ unless defined? $__rq_jobqueue__
|
|
239
239
|
end
|
240
240
|
def tmp_stdin stdin = nil
|
241
241
|
#--{{{
|
242
|
-
stdin = nil if stdin.to_s.empty?
|
242
|
+
#stdin = nil if stdin.to_s.empty?
|
243
|
+
if stdin.to_s.empty?
|
244
|
+
return(block_given? ? yield(nil) : nil)
|
245
|
+
end
|
243
246
|
stdin = STDIN if stdin == '-'
|
244
247
|
|
245
248
|
was_opened = false
|
data/lib/rq/updater.rb
CHANGED
data/rails/data/config
CHANGED
data/rails/example.rb
CHANGED
@@ -25,7 +25,10 @@
|
|
25
25
|
Subject: testing 1-2-3
|
26
26
|
Cc: ara.t.howard@gmail.com
|
27
27
|
attach: #{ this_file }
|
28
|
+
yml
|
28
29
|
|
30
|
+
### put this in theconfig if you want to use smtp
|
31
|
+
=begin
|
29
32
|
smtp:
|
30
33
|
account : ara.t.howard@eparklabs.com
|
31
34
|
tls : true
|
@@ -33,8 +36,8 @@
|
|
33
36
|
server : secure.eparklabs.com
|
34
37
|
domain : eparklabs.com
|
35
38
|
authtype : :plain
|
36
|
-
password :
|
37
|
-
|
39
|
+
password : :password
|
40
|
+
=end
|
38
41
|
|
39
42
|
config = YAML.load yml
|
40
43
|
|
metadata
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.
|
2
|
+
rubygems_version: 0.9.4
|
3
3
|
specification_version: 1
|
4
4
|
name: rq
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 3.
|
7
|
-
date: 2007-
|
6
|
+
version: 3.4.0
|
7
|
+
date: 2007-12-18 00:00:00 -07:00
|
8
8
|
summary: rq
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -29,6 +29,7 @@ post_install_message:
|
|
29
29
|
authors:
|
30
30
|
- Ara T. Howard
|
31
31
|
files:
|
32
|
+
- a.rb
|
32
33
|
- all
|
33
34
|
- all/install.rb
|
34
35
|
- all/install.sh
|
@@ -47,6 +48,7 @@ files:
|
|
47
48
|
- bin
|
48
49
|
- bin/rq
|
49
50
|
- bin/rqmailer
|
51
|
+
- build
|
50
52
|
- doc
|
51
53
|
- extconf.rb
|
52
54
|
- gemspec.rb
|
@@ -100,16 +102,6 @@ files:
|
|
100
102
|
- lib/rq/util.rb
|
101
103
|
- lib/rq.rb
|
102
104
|
- Makefile
|
103
|
-
- q
|
104
|
-
- q/bin
|
105
|
-
- q/bin/rqmailer
|
106
|
-
- q/data
|
107
|
-
- q/db
|
108
|
-
- q/db.schema
|
109
|
-
- q/lock
|
110
|
-
- q/stderr
|
111
|
-
- q/stdin
|
112
|
-
- q/stdout
|
113
105
|
- rails
|
114
106
|
- rails/app
|
115
107
|
- rails/app/controllers
|
@@ -162,16 +154,6 @@ files:
|
|
162
154
|
- rails/public/javascripts/prototype.js
|
163
155
|
- rails/public/robots.txt
|
164
156
|
- rails/public/stylesheets
|
165
|
-
- rails/q
|
166
|
-
- rails/q/bin
|
167
|
-
- rails/q/bin/rqmailer
|
168
|
-
- rails/q/data
|
169
|
-
- rails/q/db
|
170
|
-
- rails/q/db.schema
|
171
|
-
- rails/q/lock
|
172
|
-
- rails/q/stderr
|
173
|
-
- rails/q/stdin
|
174
|
-
- rails/q/stdout
|
175
157
|
- rails/q.20070629122840.tgz
|
176
158
|
- rails/Rakefile
|
177
159
|
- rails/README
|
@@ -201,8 +183,11 @@ files:
|
|
201
183
|
- rails/test/test_helper.rb
|
202
184
|
- rails/test/unit
|
203
185
|
- rails/tmp
|
186
|
+
- rails/tmp/12344
|
187
|
+
- rails/tmp/12532
|
204
188
|
- rails/tmp/12565
|
205
189
|
- rails/tmp/12589
|
190
|
+
- rails/tmp/15392
|
206
191
|
- rails/tmp/16694
|
207
192
|
- rails/tmp/2311
|
208
193
|
- rails/tmp/2312
|
@@ -241,6 +226,7 @@ files:
|
|
241
226
|
- rails/tmp/4063
|
242
227
|
- rails/tmp/4086
|
243
228
|
- rails/tmp/4102
|
229
|
+
- rails/tmp/5245
|
244
230
|
- rails/tmp/8272
|
245
231
|
- rails/tmp/8321
|
246
232
|
- rails/tmp/8362
|
data/q/bin/rqmailer
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
#!/Applications/Locomotive2/Bundles/standardRailsMar2007.locobundle/i386/bin/ruby
|
2
|
-
#
|
3
|
-
# This file was generated by RubyGems.
|
4
|
-
#
|
5
|
-
# The application 'rq' is installed as part of a gem, and
|
6
|
-
# this file is here to facilitate running it.
|
7
|
-
#
|
8
|
-
|
9
|
-
require 'rubygems'
|
10
|
-
version = "> 0"
|
11
|
-
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
|
12
|
-
version = $1
|
13
|
-
ARGV.shift
|
14
|
-
end
|
15
|
-
gem 'rq', version
|
16
|
-
load 'rqmailer'
|
data/q/db
DELETED
Binary file
|
data/q/db.schema
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
PRAGMA default_synchronous = FULL;
|
2
|
-
create table jobs
|
3
|
-
(
|
4
|
-
jid integer primary key,
|
5
|
-
priority,
|
6
|
-
state,
|
7
|
-
submitted,
|
8
|
-
started,
|
9
|
-
finished,
|
10
|
-
elapsed,
|
11
|
-
submitter,
|
12
|
-
runner,
|
13
|
-
stdin,
|
14
|
-
stdout,
|
15
|
-
stderr,
|
16
|
-
data,
|
17
|
-
pid,
|
18
|
-
exit_status,
|
19
|
-
tag,
|
20
|
-
restartable,
|
21
|
-
command
|
22
|
-
);
|
23
|
-
create table attributes
|
24
|
-
(
|
25
|
-
key,
|
26
|
-
value,
|
27
|
-
primary key (key)
|
28
|
-
);
|
data/q/lock
DELETED
File without changes
|
data/rails/q/bin/rqmailer
DELETED
@@ -1,847 +0,0 @@
|
|
1
|
-
#!/opt/local/bin/ruby
|
2
|
-
#! /opt/local/bin/ruby
|
3
|
-
|
4
|
-
### built-in
|
5
|
-
require 'openssl'
|
6
|
-
require 'net/smtp'
|
7
|
-
require 'io/wait'
|
8
|
-
require 'erb'
|
9
|
-
require 'socket'
|
10
|
-
|
11
|
-
### rubyforge
|
12
|
-
require 'rubygems'
|
13
|
-
require 'main'
|
14
|
-
require 'open4'
|
15
|
-
#require 'mailfactory' # patched version inlined below
|
16
|
-
|
17
|
-
Main {
|
18
|
-
option('config', 'c'){
|
19
|
-
argument_required
|
20
|
-
}
|
21
|
-
|
22
|
-
option('template', 't'){
|
23
|
-
argument_required
|
24
|
-
}
|
25
|
-
|
26
|
-
option('belch', 'b'){
|
27
|
-
}
|
28
|
-
|
29
|
-
option('send', 's'){
|
30
|
-
}
|
31
|
-
|
32
|
-
option('queue', 'q'){
|
33
|
-
argument_required
|
34
|
-
}
|
35
|
-
|
36
|
-
SMTP = {}
|
37
|
-
|
38
|
-
def run #--{{{
|
39
|
-
indicating_that_rqmailer_failed do
|
40
|
-
setup
|
41
|
-
load_config
|
42
|
-
load_template
|
43
|
-
generate_cmd
|
44
|
-
run_cmd
|
45
|
-
expand_template
|
46
|
-
mail_message
|
47
|
-
end
|
48
|
-
exit @exit_status || 42
|
49
|
-
end #--}}}
|
50
|
-
|
51
|
-
def setup #--{{{
|
52
|
-
@config = {}
|
53
|
-
@rq = ENV['RQ']
|
54
|
-
@rq_data = ENV['RQ_DATA']
|
55
|
-
@exit_status = 0
|
56
|
-
@exception = nil
|
57
|
-
@template_expander = TemplateExpander.instance
|
58
|
-
@stdin = @stdout = @stderr = nil
|
59
|
-
@belch = params['belch'].given?
|
60
|
-
@send = params['send'].given?
|
61
|
-
@hostname = Socket.gethostname rescue 'localhost.localdomain'
|
62
|
-
@mail = MailFactory.new
|
63
|
-
end #--}}}
|
64
|
-
|
65
|
-
def load_config #--{{{
|
66
|
-
if param['config'].given?
|
67
|
-
@config = YAML.load IO.read(param['config'].value)
|
68
|
-
else
|
69
|
-
if @rq_data
|
70
|
-
config = File.join @rq_data, 'config'
|
71
|
-
@config = YAML.load IO.read(config)
|
72
|
-
else
|
73
|
-
abort 'no config'
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end #--}}}
|
77
|
-
|
78
|
-
def load_template #--{{{
|
79
|
-
if param['template'].given?
|
80
|
-
@template = IO.read param['template'].value
|
81
|
-
else
|
82
|
-
if @rq_data
|
83
|
-
template = File.join @rq_data, 'template'
|
84
|
-
@template = IO.read(template)
|
85
|
-
else
|
86
|
-
@template = DATA.read
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end #--}}}
|
90
|
-
|
91
|
-
def generate_cmd #--{{{
|
92
|
-
stdin = argv.first == '-' && argv.delete('-')
|
93
|
-
@cmd =
|
94
|
-
if stdin
|
95
|
-
STDIN.read
|
96
|
-
else
|
97
|
-
@config['command'] || @config['cmd'] || argv.join(' ')
|
98
|
-
end
|
99
|
-
abort 'no cmd' if @cmd.to_s.strip.empty?
|
100
|
-
end #--}}}
|
101
|
-
|
102
|
-
def run_cmd #--{{{
|
103
|
-
if @rq
|
104
|
-
@stdin = STDIN if STDIN.ready?
|
105
|
-
@stdout = STDOUT
|
106
|
-
@stderr = STDERR
|
107
|
-
STDOUT.flush; STDERR.flush
|
108
|
-
@exit_status = Open4.spawn @cmd, 0=>@stdin, 1=>@stdout, 2=>@stderr
|
109
|
-
STDOUT.flush; STDERR.flush
|
110
|
-
else
|
111
|
-
@stdin = STDIN if STDIN.ready?
|
112
|
-
@stdin = IO.read(@stdin) if @stdin
|
113
|
-
@stdout = ''
|
114
|
-
@stderr = ''
|
115
|
-
@exit_status = Open4.spawn @cmd, 0=>@stdin, 1=>@stdout, 2=>@stderr
|
116
|
-
end
|
117
|
-
update_config_with_cmd_info
|
118
|
-
end #--}}}
|
119
|
-
|
120
|
-
def errmsg e #--{{{
|
121
|
-
m, c, bt = e.message, e.class, (e.backtrace || []).join("\n")
|
122
|
-
"#{ m } (#{ c })\n#{ bt }"
|
123
|
-
end #--}}}
|
124
|
-
|
125
|
-
def indicating_that_rqmailer_failed #--{{{
|
126
|
-
begin
|
127
|
-
yield
|
128
|
-
rescue Exception => e
|
129
|
-
@exception = e
|
130
|
-
STDERR.puts errmsg(e)
|
131
|
-
@exit_status = 42
|
132
|
-
end
|
133
|
-
end #--}}}
|
134
|
-
|
135
|
-
def update_config_with_cmd_info #--{{{
|
136
|
-
if @rq
|
137
|
-
%w( stdin stdout stderr ).each do |iof|
|
138
|
-
path = instance_variable_get "@rq_#{ iof }"
|
139
|
-
buf = IO.read path rescue ''
|
140
|
-
@config[iof] = buf
|
141
|
-
@config["#{ iof }_path"] = path
|
142
|
-
end
|
143
|
-
else
|
144
|
-
@config['stdin'] = @stdin
|
145
|
-
@config['stdin_path'] = '-'
|
146
|
-
@config['stdout'] = @stdout
|
147
|
-
@config['stdout_path'] = '-'
|
148
|
-
@config['stderr'] = @stderr
|
149
|
-
@config['stderr_path'] = '-'
|
150
|
-
end
|
151
|
-
|
152
|
-
@config['cmd'] = @config['command'] = @cmd
|
153
|
-
@config['exit_status'] = @config['exitstatus'] = @exit_status
|
154
|
-
end #--}}}
|
155
|
-
|
156
|
-
def expand_template #--{{{
|
157
|
-
@template_expander.configure @config
|
158
|
-
@template_expander.configure 'mail' => @mail
|
159
|
-
mconfig = @config['mail'] || {}
|
160
|
-
@template_expander.configure mconfig
|
161
|
-
@message = @template_expander.expand @template
|
162
|
-
end #--}}}
|
163
|
-
|
164
|
-
def mail_message #--{{{
|
165
|
-
build_mail!
|
166
|
-
|
167
|
-
hash = @config['smtp'] || SMTP
|
168
|
-
server = hash['server']
|
169
|
-
port = Integer hash['port']
|
170
|
-
hostname = hash['hostname'] || @hostname || 'localhost.localdomain'
|
171
|
-
account = hash['account']
|
172
|
-
password = hash['password']
|
173
|
-
authtype = hash['authtype'] || :plain
|
174
|
-
tls = hash['tls'] ? true : false
|
175
|
-
|
176
|
-
if @belch
|
177
|
-
if @send
|
178
|
-
smtp = Net::SMTP.new server, port
|
179
|
-
smtp.set_debug_output STDERR
|
180
|
-
smtp.start hostname, account, password, authtype, tls do |connection|
|
181
|
-
connection.send_message @mail, account, @mail.recipients
|
182
|
-
end
|
183
|
-
end
|
184
|
-
STDOUT.puts @mail
|
185
|
-
else
|
186
|
-
debug_output = open File.join(@rq_data, 'smtp'), 'w'
|
187
|
-
at_exit{ debug_output.close rescue nil }
|
188
|
-
|
189
|
-
smtp = Net::SMTP.new server, port
|
190
|
-
smtp.set_debug_output debug_output
|
191
|
-
smtp.start hostname, account, password, authtype, tls do |connection|
|
192
|
-
connection.send_message @mail, account, @mail.recipients
|
193
|
-
end
|
194
|
-
|
195
|
-
if @rq
|
196
|
-
open(File.join(@rq_data, 'mail'), 'w'){|fd| fd.write @mail}
|
197
|
-
end
|
198
|
-
|
199
|
-
STDERR.puts @mail
|
200
|
-
end
|
201
|
-
|
202
|
-
end #--}}}
|
203
|
-
|
204
|
-
def build_mail! #--{{{
|
205
|
-
mconfig = @config['mail'] || @config
|
206
|
-
|
207
|
-
attributes = %w(
|
208
|
-
to
|
209
|
-
from
|
210
|
-
cc
|
211
|
-
bcc
|
212
|
-
subject
|
213
|
-
)
|
214
|
-
attributes.each do |attribute|
|
215
|
-
up, down = attribute.downcase.capitalize, attribute.downcase
|
216
|
-
[up, down].each do |attribute|
|
217
|
-
if mconfig.has_key?(attribute)
|
218
|
-
value = [mconfig[attribute]].flatten.join ','
|
219
|
-
@mail.send "#{ up }=", value
|
220
|
-
@mail.send "#{ down }=", value
|
221
|
-
end
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
methods = %w(
|
226
|
-
attach
|
227
|
-
attachment
|
228
|
-
attachments
|
229
|
-
Attach
|
230
|
-
Attachment
|
231
|
-
Attachments
|
232
|
-
)
|
233
|
-
methods.each do |method|
|
234
|
-
if mconfig.has_key?(method)
|
235
|
-
values = [mconfig[method]].flatten
|
236
|
-
values.each do |value|
|
237
|
-
@mail.attach value
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
class << @mail
|
243
|
-
def recipients
|
244
|
-
to.to_s.split %r/,/
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
@mail.subject ||= "rqmailer"
|
249
|
-
@mail.text = @message
|
250
|
-
@mail
|
251
|
-
end #--}}}
|
252
|
-
|
253
|
-
class TemplateExpander #--{{{
|
254
|
-
alias_method "__instance_variable_set__", "instance_variable_set"
|
255
|
-
alias_method "__instance_eval__", "instance_eval"
|
256
|
-
instance_methods.each{|m| undef_method unless m[%r/__/]}
|
257
|
-
alias_method "instance_eval", "__instance_eval__"
|
258
|
-
alias_method "instance_variable_set", "__instance_variable_set__"
|
259
|
-
|
260
|
-
def self.new *a, &b
|
261
|
-
@instance ||= super
|
262
|
-
end
|
263
|
-
def self.instance *a, &b
|
264
|
-
new *a, &b
|
265
|
-
end
|
266
|
-
def self.const_missing c
|
267
|
-
msg = c.to_s.downcase
|
268
|
-
if @instance.respond_to? msg
|
269
|
-
@instance.send msg
|
270
|
-
else
|
271
|
-
super
|
272
|
-
end
|
273
|
-
end
|
274
|
-
def singleton_class &b #--{{{
|
275
|
-
@sc ||=
|
276
|
-
class << self
|
277
|
-
self
|
278
|
-
end
|
279
|
-
b ? @sc.module_eval(&b) : @sc
|
280
|
-
end #--}}}
|
281
|
-
def set key, value #--{{{
|
282
|
-
key = key.to_s.downcase
|
283
|
-
instance_variable_set "@#{ key }", value
|
284
|
-
singleton_class do
|
285
|
-
define_method(key){ instance_variable_get "@#{ key }" }
|
286
|
-
define_method(key.capitalize){ instance_variable_get "@#{ key }" }
|
287
|
-
end
|
288
|
-
end #--}}}
|
289
|
-
def configure hash #--{{{
|
290
|
-
hash.each{|k,v| set k, v}
|
291
|
-
end #--}}}
|
292
|
-
def expand message #--{{{
|
293
|
-
ERB.new(message).result binding
|
294
|
-
end #--}}}
|
295
|
-
def lazy #--{{{
|
296
|
-
singleton_class{ define_method m, &b }
|
297
|
-
end #--}}}
|
298
|
-
def method_missing m, *a, &b
|
299
|
-
super unless defined? @mail
|
300
|
-
@mail.send m, *a, &b
|
301
|
-
end
|
302
|
-
end #--}}}
|
303
|
-
}
|
304
|
-
|
305
|
-
|
306
|
-
BEGIN {
|
307
|
-
|
308
|
-
### hacking in smtp tls support
|
309
|
-
#--{{{
|
310
|
-
# Original code believed public domain from ruby-talk or ruby-core email.
|
311
|
-
# Modifications by Kyle Maxwell <kyle@kylemaxwell.com> used under MIT license.
|
312
|
-
|
313
|
-
require "openssl"
|
314
|
-
require "net/smtp"
|
315
|
-
|
316
|
-
# :stopdoc:
|
317
|
-
|
318
|
-
class Net::SMTP
|
319
|
-
|
320
|
-
class << self
|
321
|
-
send :remove_method, :start
|
322
|
-
end
|
323
|
-
|
324
|
-
def self.start( address, port = nil,
|
325
|
-
helo = 'localhost.localdomain',
|
326
|
-
user = nil, secret = nil, authtype = nil, use_tls = false,
|
327
|
-
&block) # :yield: smtp
|
328
|
-
new(address, port).start(helo, user, secret, authtype, use_tls, &block)
|
329
|
-
end
|
330
|
-
|
331
|
-
alias tls_old_start start
|
332
|
-
|
333
|
-
def start( helo = 'localhost.localdomain',
|
334
|
-
user = nil, secret = nil, authtype = nil, use_tls = false ) # :yield: smtp
|
335
|
-
start_method = use_tls ? :do_tls_start : :do_start
|
336
|
-
if block_given?
|
337
|
-
begin
|
338
|
-
send start_method, helo, user, secret, authtype
|
339
|
-
return yield(self)
|
340
|
-
ensure
|
341
|
-
do_finish
|
342
|
-
end
|
343
|
-
else
|
344
|
-
send start_method, helo, user, secret, authtype
|
345
|
-
return self
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
private
|
350
|
-
|
351
|
-
def do_tls_start(helodomain, user, secret, authtype)
|
352
|
-
raise IOError, 'SMTP session already started' if @started
|
353
|
-
check_auth_args user, secret, authtype if user or secret
|
354
|
-
|
355
|
-
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
|
356
|
-
@socket = Net::InternetMessageIO.new(sock)
|
357
|
-
@socket.read_timeout = 60 #@read_timeout
|
358
|
-
@socket.debug_output = @debug_output
|
359
|
-
|
360
|
-
check_response(critical { recv_response() })
|
361
|
-
do_helo(helodomain)
|
362
|
-
|
363
|
-
raise 'openssl library not installed' unless defined?(OpenSSL)
|
364
|
-
starttls
|
365
|
-
ssl = OpenSSL::SSL::SSLSocket.new(sock)
|
366
|
-
ssl.sync_close = true
|
367
|
-
ssl.connect
|
368
|
-
@socket = Net::InternetMessageIO.new(ssl)
|
369
|
-
@socket.read_timeout = 60 #@read_timeout
|
370
|
-
@socket.debug_output = @debug_output
|
371
|
-
do_helo(helodomain)
|
372
|
-
|
373
|
-
authenticate user, secret, authtype if user
|
374
|
-
@started = true
|
375
|
-
ensure
|
376
|
-
unless @started
|
377
|
-
# authentication failed, cancel connection.
|
378
|
-
@socket.close if not @started and @socket and not @socket.closed?
|
379
|
-
@socket = nil
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
def do_helo(helodomain)
|
384
|
-
begin
|
385
|
-
if @esmtp
|
386
|
-
ehlo helodomain
|
387
|
-
else
|
388
|
-
helo helodomain
|
389
|
-
end
|
390
|
-
rescue Net::ProtocolError
|
391
|
-
if @esmtp
|
392
|
-
@esmtp = false
|
393
|
-
@error_occured = false
|
394
|
-
retry
|
395
|
-
end
|
396
|
-
raise
|
397
|
-
end
|
398
|
-
end
|
399
|
-
|
400
|
-
def starttls
|
401
|
-
getok('STARTTLS')
|
402
|
-
end
|
403
|
-
|
404
|
-
alias tls_old_quit quit
|
405
|
-
|
406
|
-
def quit
|
407
|
-
begin
|
408
|
-
getok('QUIT')
|
409
|
-
rescue EOFError
|
410
|
-
end
|
411
|
-
end
|
412
|
-
|
413
|
-
end unless Net::SMTP.private_method_defined? :do_tls_start or
|
414
|
-
Net::SMTP.method_defined? :tls?
|
415
|
-
#--}}}
|
416
|
-
|
417
|
-
### inlining mailfactory
|
418
|
-
#--{{{
|
419
|
-
# = Overview:
|
420
|
-
# A simple to use module for generating RFC compliant MIME mail
|
421
|
-
# ---
|
422
|
-
# = License:
|
423
|
-
# Author:: David Powers
|
424
|
-
# Copyright:: May, 2005
|
425
|
-
# License:: Ruby License
|
426
|
-
# ---
|
427
|
-
# = Usage:
|
428
|
-
# require 'net/smtp'
|
429
|
-
# require 'rubygems'
|
430
|
-
# require 'mailfactory'
|
431
|
-
#
|
432
|
-
#
|
433
|
-
# mail = MailFactory.new()
|
434
|
-
# mail.to = "test@test.com"
|
435
|
-
# mail.from = "sender@sender.com"
|
436
|
-
# mail.subject = "Here are some files for you!"
|
437
|
-
# mail.text = "This is what people with plain text mail readers will see"
|
438
|
-
# mail.html = "A little something <b>special</b> for people with HTML readers"
|
439
|
-
# mail.attach("/etc/fstab")
|
440
|
-
# mail.attach("/some/other/file")
|
441
|
-
#
|
442
|
-
# Net::SMTP.start('smtp1.testmailer.com', 25, 'mail.from.domain', fromaddress, password, :cram_md5) { |smtp|
|
443
|
-
# mail.to = toaddress
|
444
|
-
# smtp.send_message(mail.to_s(), fromaddress, toaddress)
|
445
|
-
# }
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
require 'base64'
|
450
|
-
require 'pathname'
|
451
|
-
|
452
|
-
# try to bring in the mime/types module, make a dummy module if it can't be found
|
453
|
-
begin
|
454
|
-
begin
|
455
|
-
require 'rubygems'
|
456
|
-
rescue LoadError
|
457
|
-
end
|
458
|
-
require 'mime/types'
|
459
|
-
rescue LoadError
|
460
|
-
module MIME
|
461
|
-
class Types
|
462
|
-
def Types::type_for(filename)
|
463
|
-
return('')
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
|
469
|
-
# An easy class for creating a mail message
|
470
|
-
class MailFactory
|
471
|
-
|
472
|
-
def initialize()
|
473
|
-
@headers = Array.new()
|
474
|
-
@attachments = Array.new()
|
475
|
-
@attachmentboundary = generate_boundary()
|
476
|
-
@bodyboundary = generate_boundary()
|
477
|
-
@html = nil
|
478
|
-
@text = nil
|
479
|
-
end
|
480
|
-
|
481
|
-
|
482
|
-
# adds a header to the bottom of the headers
|
483
|
-
def add_header(header, value)
|
484
|
-
@headers << "#{header}: #{value}"
|
485
|
-
end
|
486
|
-
|
487
|
-
|
488
|
-
# removes the named header - case insensitive
|
489
|
-
def remove_header(header)
|
490
|
-
@headers.each_index() { |i|
|
491
|
-
if(@headers[i] =~ /^#{Regexp.escape(header)}:/i)
|
492
|
-
@headers.delete_at(i)
|
493
|
-
end
|
494
|
-
}
|
495
|
-
end
|
496
|
-
|
497
|
-
|
498
|
-
# sets a header (removing any other versions of that header)
|
499
|
-
def set_header(header, value)
|
500
|
-
remove_header(header)
|
501
|
-
add_header(header, value)
|
502
|
-
end
|
503
|
-
|
504
|
-
|
505
|
-
def replyto=(newreplyto)
|
506
|
-
remove_header("Reply-To")
|
507
|
-
add_header("Reply-To", newreplyto)
|
508
|
-
end
|
509
|
-
|
510
|
-
|
511
|
-
def replyto()
|
512
|
-
return(get_header("Reply-To")[0])
|
513
|
-
end
|
514
|
-
|
515
|
-
def self.hattr h
|
516
|
-
h = h.to_s
|
517
|
-
module_eval <<-code
|
518
|
-
def #{ h.downcase }=(value)
|
519
|
-
remove_header("#{ h.downcase.capitalize }")
|
520
|
-
add_header("#{ h.downcase.capitalize }", value)
|
521
|
-
end
|
522
|
-
def #{ h.downcase }()
|
523
|
-
return(get_header("#{ h.downcase.capitalize }")[0])
|
524
|
-
end
|
525
|
-
code
|
526
|
-
end
|
527
|
-
%w( to from cc bcc subject ).each{|h| hattr h}
|
528
|
-
|
529
|
-
|
530
|
-
# sets the plain text body of the message
|
531
|
-
def text=(newtext)
|
532
|
-
@text = newtext
|
533
|
-
end
|
534
|
-
|
535
|
-
|
536
|
-
# sets the HTML body of the message. Only the body of the
|
537
|
-
# html should be provided
|
538
|
-
def html=(newhtml)
|
539
|
-
@html = "<html>\n<head>\n<meta content=\"text/html;charset=ISO-8859-1\" http-equiv=\"Content-Type\">\n</head>\n<body bgcolor=\"#ffffff\" text=\"#000000\">\n#{newhtml}\n</body>\n</html>"
|
540
|
-
end
|
541
|
-
|
542
|
-
|
543
|
-
# sets the HTML body of the message. The entire HTML section should be provided
|
544
|
-
def rawhtml=(newhtml)
|
545
|
-
@html = newhtml
|
546
|
-
end
|
547
|
-
|
548
|
-
|
549
|
-
# implement method missing to provide helper methods for setting and getting headers.
|
550
|
-
# Headers with '-' characters may be set/gotten as 'x_mailer' or 'XMailer' (splitting
|
551
|
-
# will occur between capital letters or on '_' chracters)
|
552
|
-
def method_missing(methId, *args)
|
553
|
-
name = methId.id2name()
|
554
|
-
|
555
|
-
# mangle the name if we have to
|
556
|
-
if(name =~ /_/)
|
557
|
-
name = name.gsub(/_/, '-')
|
558
|
-
elsif(name =~ /[A-Z]/)
|
559
|
-
name = name.gsub(/([a-zA-Z])([A-Z])/, '\1-\2')
|
560
|
-
end
|
561
|
-
|
562
|
-
# determine if it sets or gets, and do the right thing
|
563
|
-
if(name =~ /=$/)
|
564
|
-
if(args.length != 1)
|
565
|
-
super(methId, args)
|
566
|
-
end
|
567
|
-
set_header(name[/^(.*)=$/, 1], args[0])
|
568
|
-
else
|
569
|
-
if(args.length != 0)
|
570
|
-
super(methId, args)
|
571
|
-
end
|
572
|
-
headers = get_header(name)
|
573
|
-
return(get_header(name))
|
574
|
-
end
|
575
|
-
end
|
576
|
-
|
577
|
-
|
578
|
-
# returns the value (or values) of the named header in an array
|
579
|
-
def get_header(header)
|
580
|
-
headers = Array.new()
|
581
|
-
headerregex = /^#{Regexp.escape(header)}:/i
|
582
|
-
@headers.each() { |h|
|
583
|
-
if(headerregex.match(h))
|
584
|
-
headers << h[/^[^:]+:(.*)/i, 1].strip()
|
585
|
-
end
|
586
|
-
}
|
587
|
-
|
588
|
-
return(headers)
|
589
|
-
end
|
590
|
-
|
591
|
-
|
592
|
-
# returns true if the email is multipart
|
593
|
-
def multipart?()
|
594
|
-
if(@attachments.length > 0 or @html != nil)
|
595
|
-
return(true)
|
596
|
-
else
|
597
|
-
return(false)
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
|
602
|
-
# builds an email and returns it as a string. Takes the following options:
|
603
|
-
# <tt>:messageid</tt>:: Adds a message id to the message based on the from header (defaults to false)
|
604
|
-
# <tt>:date</tt>:: Adds a date to the message if one is not present (defaults to true)
|
605
|
-
def construct(options = Hash.new)
|
606
|
-
if(options[:date] == nil)
|
607
|
-
options[:date] = true
|
608
|
-
end
|
609
|
-
|
610
|
-
if(options[:messageid])
|
611
|
-
# add a unique message-id
|
612
|
-
remove_header("Message-ID")
|
613
|
-
sendingdomain = get_header('from')[0].to_s()[/@([-a-zA-Z0-9._]+)/,1].to_s()
|
614
|
-
add_header("Message-ID", "<#{Time.now.to_f()}.#{Process.euid()}.#{String.new.object_id()}@#{sendingdomain}>")
|
615
|
-
end
|
616
|
-
|
617
|
-
if(options[:date])
|
618
|
-
if(get_header("Date").length == 0)
|
619
|
-
add_header("Date", Time.now.strftime("%a, %d %b %Y %H:%M:%S %z"))
|
620
|
-
end
|
621
|
-
end
|
622
|
-
|
623
|
-
# Add a mime header if we don't already have one and we have multiple parts
|
624
|
-
if(multipart?())
|
625
|
-
if(get_header("MIME-Version").length == 0)
|
626
|
-
add_header("MIME-Version", "1.0")
|
627
|
-
end
|
628
|
-
|
629
|
-
if(get_header("Content-Type").length == 0)
|
630
|
-
if(@attachments.length == 0)
|
631
|
-
add_header("Content-Type", "multipart/alternative;boundary=\"#{@bodyboundary}\"")
|
632
|
-
else
|
633
|
-
add_header("Content-Type", "multipart/mixed; boundary=\"#{@attachmentboundary}\"")
|
634
|
-
end
|
635
|
-
end
|
636
|
-
end
|
637
|
-
|
638
|
-
return("#{headers_to_s()}#{body_to_s()}")
|
639
|
-
end
|
640
|
-
|
641
|
-
|
642
|
-
# returns a formatted email - equivalent to construct(:messageid => true)
|
643
|
-
def to_s()
|
644
|
-
return(construct(:messageid => true))
|
645
|
-
end
|
646
|
-
|
647
|
-
|
648
|
-
# generates a unique boundary string
|
649
|
-
def generate_boundary()
|
650
|
-
randomstring = Array.new()
|
651
|
-
1.upto(25) {
|
652
|
-
whichglyph = rand(100)
|
653
|
-
if(whichglyph < 40)
|
654
|
-
randomstring << (rand(25) + 65).chr()
|
655
|
-
elsif(whichglyph < 70)
|
656
|
-
randomstring << (rand(25) + 97).chr()
|
657
|
-
elsif(whichglyph < 90)
|
658
|
-
randomstring << (rand(10) + 48).chr()
|
659
|
-
elsif(whichglyph < 95)
|
660
|
-
randomstring << '.'
|
661
|
-
else
|
662
|
-
randomstring << '_'
|
663
|
-
end
|
664
|
-
}
|
665
|
-
return("----=_NextPart_#{randomstring.join()}")
|
666
|
-
end
|
667
|
-
|
668
|
-
|
669
|
-
# adds an attachment to the mail. Type may be given as a mime type. If it
|
670
|
-
# is left off and the MIME::Types module is available it will be determined automagically.
|
671
|
-
# If the optional attachemntheaders is given, then they will be added to the attachment
|
672
|
-
# boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
|
673
|
-
# can be given as an Array or a String.
|
674
|
-
def add_attachment(filename, type=nil, attachmentheaders = nil)
|
675
|
-
attachment = Hash.new()
|
676
|
-
attachment['filename'] = Pathname.new(filename).basename
|
677
|
-
if(type == nil)
|
678
|
-
attachment['mimetype'] = MIME::Types.type_for(filename).to_s
|
679
|
-
else
|
680
|
-
attachment['mimetype'] = type
|
681
|
-
end
|
682
|
-
|
683
|
-
# Open in rb mode to handle Windows, which mangles binary files opened in a text mode
|
684
|
-
File.open(filename, "rb") { |fp|
|
685
|
-
attachment['attachment'] = file_encode(fp.read())
|
686
|
-
}
|
687
|
-
|
688
|
-
if(attachmentheaders != nil)
|
689
|
-
if(!attachmentheaders.kind_of?(Array))
|
690
|
-
attachmentheaders = attachmentheaders.split(/\r?\n/)
|
691
|
-
end
|
692
|
-
attachment['headers'] = attachmentheaders
|
693
|
-
end
|
694
|
-
|
695
|
-
@attachments << attachment
|
696
|
-
end
|
697
|
-
|
698
|
-
|
699
|
-
# adds an attachment to the mail as emailfilename. Type may be given as a mime type. If it
|
700
|
-
# is left off and the MIME::Types module is available it will be determined automagically.
|
701
|
-
# file may be given as an IO stream (which will be read until the end) or as a filename.
|
702
|
-
# If the optional attachemntheaders is given, then they will be added to the attachment
|
703
|
-
# boundary in the email, which can be used to produce Content-ID markers. attachmentheaders
|
704
|
-
# can be given as an Array of a String.
|
705
|
-
def add_attachment_as(file, emailfilename, type=nil, attachmentheaders = nil)
|
706
|
-
attachment = Hash.new()
|
707
|
-
attachment['filename'] = emailfilename
|
708
|
-
|
709
|
-
if(type != nil)
|
710
|
-
attachment['mimetype'] = type.to_s()
|
711
|
-
elsif(file.kind_of?(String) or file.kind_of?(Pathname))
|
712
|
-
attachment['mimetype'] = MIME::Types.type_for(file.to_s()).to_s
|
713
|
-
else
|
714
|
-
attachment['mimetype'] = ''
|
715
|
-
end
|
716
|
-
|
717
|
-
if(file.kind_of?(String) or file.kind_of?(Pathname))
|
718
|
-
# Open in rb mode to handle Windows, which mangles binary files opened in a text mode
|
719
|
-
File.open(file.to_s(), "rb") { |fp|
|
720
|
-
attachment['attachment'] = file_encode(fp.read())
|
721
|
-
}
|
722
|
-
elsif(file.respond_to?(:read))
|
723
|
-
attachment['attachment'] = file_encode(file.read())
|
724
|
-
else
|
725
|
-
raise(Exception, "file is not a supported type (must be a String, Pathnamem, or support read method)")
|
726
|
-
end
|
727
|
-
|
728
|
-
if(attachmentheaders != nil)
|
729
|
-
if(!attachmentheaders.kind_of?(Array))
|
730
|
-
attachmentheaders = attachmentheaders.split(/\r?\n/)
|
731
|
-
end
|
732
|
-
attachment['headers'] = attachmentheaders
|
733
|
-
end
|
734
|
-
|
735
|
-
@attachments << attachment
|
736
|
-
end
|
737
|
-
|
738
|
-
|
739
|
-
alias attach add_attachment
|
740
|
-
alias attach_as add_attachment_as
|
741
|
-
|
742
|
-
protected
|
743
|
-
|
744
|
-
# returns the @headers as a properly formatted string
|
745
|
-
def headers_to_s()
|
746
|
-
return("#{@headers.join("\r\n")}\r\n\r\n")
|
747
|
-
end
|
748
|
-
|
749
|
-
|
750
|
-
# returns the body as a properly formatted string
|
751
|
-
def body_to_s()
|
752
|
-
body = Array.new()
|
753
|
-
|
754
|
-
# simple message with one part
|
755
|
-
if(!multipart?())
|
756
|
-
return(@text)
|
757
|
-
else
|
758
|
-
body << "This is a multi-part message in MIME format.\r\n\r\n--#{@attachmentboundary}\r\nContent-Type: multipart/alternative; boundary=\"#{@bodyboundary}\""
|
759
|
-
|
760
|
-
if(@attachments.length > 0)
|
761
|
-
# text part
|
762
|
-
body << "#{buildbodyboundary('text/plain; charset=ISO-8859-1; format=flowed', '7bit')}\r\n\r\n#{@text}"
|
763
|
-
|
764
|
-
# html part if one is provided
|
765
|
-
if @html
|
766
|
-
body << "#{buildbodyboundary('text/html; charset=ISO-8859-1', '7bit')}\r\n\r\n#{@html}"
|
767
|
-
end
|
768
|
-
|
769
|
-
body << "--#{@bodyboundary}--"
|
770
|
-
|
771
|
-
# and, the attachments
|
772
|
-
if(@attachments.length > 0)
|
773
|
-
@attachments.each() { |attachment|
|
774
|
-
body << "#{buildattachmentboundary(attachment)}\r\n\r\n#{attachment['attachment']}"
|
775
|
-
}
|
776
|
-
body << "\r\n--#{@attachmentboundary}--"
|
777
|
-
end
|
778
|
-
else
|
779
|
-
# text part
|
780
|
-
body << "#{buildbodyboundary('text/plain; charset=ISO-8859-1; format=flowed', '7bit')}\r\n\r\n#{@text}"
|
781
|
-
|
782
|
-
# html part
|
783
|
-
body << "#{buildbodyboundary('text/html; charset=ISO-8859-1', '7bit')}\r\n\r\n#{@html}"
|
784
|
-
|
785
|
-
body << "--#{@bodyboundary}--"
|
786
|
-
end
|
787
|
-
|
788
|
-
return(body.join("\r\n\r\n"))
|
789
|
-
end
|
790
|
-
end
|
791
|
-
|
792
|
-
|
793
|
-
# builds a boundary string for including attachments in the body, expects an attachment hash as built by
|
794
|
-
# add_attachment and add_attachment_as
|
795
|
-
def buildattachmentboundary(attachment)
|
796
|
-
disposition = "Content-Disposition: inline; filename=\"#{attachment['filename']}\""
|
797
|
-
boundary = "--#{@attachmentboundary}\r\nContent-Type: #{attachment['mimetype']}; name=\"#{attachment['filename']}\"\r\nContent-Transfer-Encoding: base64\r\n#{disposition}"
|
798
|
-
if(attachment['headers'])
|
799
|
-
boundary = boundary + "\r\n#{attachment['headers'].join("\r\n")}"
|
800
|
-
end
|
801
|
-
|
802
|
-
return(boundary)
|
803
|
-
end
|
804
|
-
|
805
|
-
|
806
|
-
# builds a boundary string for inclusion in the body of a message
|
807
|
-
def buildbodyboundary(type, encoding)
|
808
|
-
return("--#{@bodyboundary}\r\nContent-Type: #{type}\r\nContent-Transfer-Encoding: #{encoding}")
|
809
|
-
end
|
810
|
-
|
811
|
-
|
812
|
-
# returns a base64 encoded version of the contents of str
|
813
|
-
def file_encode(str)
|
814
|
-
collection = Array.new()
|
815
|
-
enc = Base64.encode64(str)
|
816
|
-
# while(enc.length > 60)
|
817
|
-
# collection << enc.slice!(0..59)
|
818
|
-
# end
|
819
|
-
# collection << enc
|
820
|
-
# return(collection.join("\n"))
|
821
|
-
return(enc)
|
822
|
-
end
|
823
|
-
|
824
|
-
end
|
825
|
-
|
826
|
-
#--}}}
|
827
|
-
|
828
|
-
}
|
829
|
-
|
830
|
-
|
831
|
-
__END__
|
832
|
-
### rqmailer
|
833
|
-
|
834
|
-
CMD:
|
835
|
-
<%= cmd %>
|
836
|
-
|
837
|
-
EXIT_STATUS:
|
838
|
-
<%= exit_status %>
|
839
|
-
|
840
|
-
STDIN:
|
841
|
-
<%= stdin %>
|
842
|
-
|
843
|
-
STDOUT:
|
844
|
-
<%= stdout %>
|
845
|
-
|
846
|
-
STDERR:
|
847
|
-
<%= stderr %>
|
data/rails/q/db
DELETED
Binary file
|
data/rails/q/db.schema
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
PRAGMA default_synchronous = FULL;
|
2
|
-
create table jobs
|
3
|
-
(
|
4
|
-
jid integer primary key,
|
5
|
-
priority,
|
6
|
-
state,
|
7
|
-
submitted,
|
8
|
-
started,
|
9
|
-
finished,
|
10
|
-
elapsed,
|
11
|
-
submitter,
|
12
|
-
runner,
|
13
|
-
stdin,
|
14
|
-
stdout,
|
15
|
-
stderr,
|
16
|
-
data,
|
17
|
-
pid,
|
18
|
-
exit_status,
|
19
|
-
tag,
|
20
|
-
restartable,
|
21
|
-
command
|
22
|
-
);
|
23
|
-
create table attributes
|
24
|
-
(
|
25
|
-
key,
|
26
|
-
value,
|
27
|
-
primary key (key)
|
28
|
-
);
|
data/rails/q/lock
DELETED
File without changes
|