glue 0.21.2 → 0.22.0
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.
- data/CHANGELOG +68 -0
- data/README +3 -3
- data/doc/RELEASES +9 -0
- data/lib/glue.rb +1 -1
- data/lib/glue/aspects.rb +4 -0
- data/lib/glue/fixture.rb +152 -0
- data/lib/glue/mail.rb +162 -0
- data/lib/glue/mailer.rb +51 -0
- data/lib/glue/mailer/incoming.rb +45 -0
- data/lib/glue/mailer/outgoing.rb +123 -0
- data/lib/glue/template.rb +211 -0
- data/lib/glue/validation.rb +1 -4
- data/test/fixture/article.csv +3 -0
- data/test/fixture/article.yml +13 -0
- data/test/fixture/user.yml +12 -0
- data/test/glue/tc_fixture.rb +43 -0
- data/test/glue/tc_mail.rb +98 -0
- data/test/glue/tc_template.rb +32 -0
- data/test/public/dummy_mailer/registration.xhtml +5 -0
- metadata +19 -10
- data/lib/facet/object/alias_class.rb +0 -12
- data/lib/glue/idgen.rb +0 -9
- data/lib/glue/idgen/md5.rb +0 -24
- data/lib/glue/idgen/sequential.rb +0 -15
- data/lib/glue/literal_method.rb +0 -44
data/CHANGELOG
CHANGED
@@ -1,3 +1,71 @@
|
|
1
|
+
07-08-2005 George Moschovitis <gm@navel.gr>
|
2
|
+
|
3
|
+
* doc/RELEASES: updated.
|
4
|
+
|
5
|
+
* lib/glue/mailer/incoming.rb: Added some comments about setting
|
6
|
+
the MTA.
|
7
|
+
|
8
|
+
* moved mail to mailer, rearanged.
|
9
|
+
|
10
|
+
* lib/glue/mail/handler.rb: template_root setting.
|
11
|
+
|
12
|
+
* lib/glue/mail/outgoing.rb (#initialize): handle template_root.
|
13
|
+
|
14
|
+
06-08-2005 George Moschovitis <gm@navel.gr>
|
15
|
+
|
16
|
+
* test/glue/tc_mail.rb: passes.
|
17
|
+
|
18
|
+
* lib/glue/mail/handler.rb: introduced,
|
19
|
+
copied settings from nitro/main.
|
20
|
+
|
21
|
+
* lib/glue/mail/outgoing.rb: introduced,
|
22
|
+
copied stuff from nitro/mail.
|
23
|
+
|
24
|
+
* lib/glue/mail/incoming.rb: introduced,
|
25
|
+
(##receive): implemented,
|
26
|
+
(#receive): implemented.
|
27
|
+
|
28
|
+
* lib/glue/mail.rb: moved from nitro,
|
29
|
+
(#parse_headers): implemented,
|
30
|
+
(##new_from_encoded): implemented,
|
31
|
+
better parsing in parse headers.
|
32
|
+
|
33
|
+
05-08-2005 George Moschovitis <gm@navel.gr>
|
34
|
+
|
35
|
+
* lib/glue/template.rb: small fixes.
|
36
|
+
|
37
|
+
* removed wee related stuff.
|
38
|
+
|
39
|
+
04-08-2005 George Moschovitis <gm@navel.gr>
|
40
|
+
|
41
|
+
* lib/glue/template.rb: copied from nitro,
|
42
|
+
renamed render_template to eval_template,
|
43
|
+
(Template##render): added helper.
|
44
|
+
|
45
|
+
* lib/glue/fixture.rb (Fixtures##[]=): added,
|
46
|
+
'test/fixture' the default root_dir,
|
47
|
+
keep sorted objects
|
48
|
+
(#parse_yaml): extra pass sorts objects,
|
49
|
+
Added templating support in fixture files.
|
50
|
+
|
51
|
+
03-08-2005 George Moschovitis <gm@navel.gr>
|
52
|
+
|
53
|
+
* test/glue/tc_fixture.rb: implemented,
|
54
|
+
added tests for global mode.
|
55
|
+
|
56
|
+
* lib/glue/fixture.rb: introduced,
|
57
|
+
extend from Hash,
|
58
|
+
(#instantiate): implemented,
|
59
|
+
(#parse_yaml): implemented,
|
60
|
+
(#parse_csv): implemented,
|
61
|
+
dont store in @objects.
|
62
|
+
(Fixtures): introduced as helpers,
|
63
|
+
fixes to support csv.
|
64
|
+
|
65
|
+
01-08-2005 George Moschovitis <gm@navel.gr>
|
66
|
+
|
67
|
+
* lig/glue/aspects.rb (#apply_advices): alias.
|
68
|
+
|
1
69
|
24-07-2005 George Moschovitis <gm@navel.gr>
|
2
70
|
|
3
71
|
* Rakefile: updated.
|
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Glue 0.
|
1
|
+
= Glue 0.22.0 README
|
2
2
|
|
3
3
|
Useful utilites and methods.
|
4
4
|
|
@@ -6,13 +6,13 @@ Useful utilites and methods.
|
|
6
6
|
== Purpose
|
7
7
|
|
8
8
|
Useful libraries are stored here. An attempt is made to
|
9
|
-
graduate
|
9
|
+
graduate smaller libraries to the more general Facets
|
10
10
|
ruby project.
|
11
11
|
|
12
12
|
|
13
13
|
== Licence
|
14
14
|
|
15
|
-
Copyright (c) 2004-2005, George 'gmosx' Moschovitis.
|
15
|
+
Copyright (c) 2004-2005, George 'gmosx' Moschovitis (http://www.gmosx.com)
|
16
16
|
Copyright (c) 2004-2005, Navel Ltd (http://www.navel.gr)
|
17
17
|
|
18
18
|
Glue (http://www.rubyforge.org/projects/nitro) is copyrighted free
|
data/doc/RELEASES
CHANGED
data/lib/glue.rb
CHANGED
data/lib/glue/aspects.rb
CHANGED
data/lib/glue/fixture.rb
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
require 'facet/object/constant'
|
2
|
+
require 'facet/string/underscore'
|
3
|
+
require 'facet/string/demodulize'
|
4
|
+
|
5
|
+
require 'glue/configuration'
|
6
|
+
require 'glue/template'
|
7
|
+
|
8
|
+
module Glue
|
9
|
+
|
10
|
+
# A collection of helper methods.
|
11
|
+
|
12
|
+
class Fixtures
|
13
|
+
# The directory where the fixtures are located.
|
14
|
+
|
15
|
+
setting :root_dir, :default => 'test/fixture', :doc => 'The directory where the fixtures are located'
|
16
|
+
|
17
|
+
@fixtures = {}
|
18
|
+
|
19
|
+
class << self
|
20
|
+
|
21
|
+
def load(*classes)
|
22
|
+
for klass in classes
|
23
|
+
f = Fixture.new(klass).load
|
24
|
+
@fixtures[f.name] = f
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def [](klass)
|
29
|
+
@fixtures[klass]
|
30
|
+
end
|
31
|
+
|
32
|
+
def []=(klass, fixture)
|
33
|
+
@fixtures[klass] = fixture
|
34
|
+
end
|
35
|
+
|
36
|
+
def method_missing(sym)
|
37
|
+
if f = @fixtures[sym.to_s]
|
38
|
+
return f
|
39
|
+
end
|
40
|
+
super
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Fixtures is a fancy word for ‘sample data’. Fixtures allow you
|
46
|
+
# to populate your database with predefined data. Fixtures are
|
47
|
+
# typically used during testing or when providing initial data
|
48
|
+
# (bootstrap data) for a live application.
|
49
|
+
#
|
50
|
+
# A Fixture is a collection (Hash) of objects.
|
51
|
+
|
52
|
+
class Fixture < Hash
|
53
|
+
|
54
|
+
# The name of this Fixture.
|
55
|
+
|
56
|
+
attr_accessor :name
|
57
|
+
|
58
|
+
# The class that the Fixtures refer to.
|
59
|
+
|
60
|
+
attr_accessor :klass
|
61
|
+
|
62
|
+
# Used to keep the order.
|
63
|
+
|
64
|
+
attr_accessor :objects
|
65
|
+
|
66
|
+
|
67
|
+
def initialize(klass, options = { } )
|
68
|
+
@klass = klass
|
69
|
+
@name = class_to_name(klass)
|
70
|
+
@objects = []
|
71
|
+
load(options[:root_dir] || options[:root] || Fixtures.root_dir)
|
72
|
+
end
|
73
|
+
|
74
|
+
def load(root_dir = Fixtures.root_dir)
|
75
|
+
raise("The fixture root director '#{root_dir}' doesn't exits") unless File.exist?(root_dir)
|
76
|
+
|
77
|
+
if path = "#{root_dir}/#{@name}.yml" and File.exist?(path)
|
78
|
+
parse_yaml(path)
|
79
|
+
end
|
80
|
+
|
81
|
+
if path = "#{root_dir}/#{@name}.csv" and File.exist?(path)
|
82
|
+
parse_csv(path)
|
83
|
+
end
|
84
|
+
|
85
|
+
return self
|
86
|
+
end
|
87
|
+
|
88
|
+
# Parse a fixture file in YAML format.
|
89
|
+
|
90
|
+
def parse_yaml(path)
|
91
|
+
require 'yaml'
|
92
|
+
|
93
|
+
str = Template.new.render(File.read(path))
|
94
|
+
|
95
|
+
if yaml = YAML::load(str)
|
96
|
+
for name, data in yaml
|
97
|
+
self[name] = instantiate(data)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# sort the objects.
|
102
|
+
|
103
|
+
str.scan(/^(\w*?):$/).each do |key|
|
104
|
+
@objects << self[key.to_s]
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Parse a fixture file in CSV format. Many RDBM systems and
|
109
|
+
# Spreadsheets can export to CVS, so this is a rather useful
|
110
|
+
# format.
|
111
|
+
|
112
|
+
def parse_csv(path)
|
113
|
+
require 'csv'
|
114
|
+
|
115
|
+
str = Template.new.render(File.read(path))
|
116
|
+
|
117
|
+
reader = CSV::Reader.create(str)
|
118
|
+
header = reader.shift
|
119
|
+
|
120
|
+
reader.each_with_index do |row, i|
|
121
|
+
data = {}
|
122
|
+
row.each_with_index do |cell, j|
|
123
|
+
data[header[j].to_s.strip] = cell.to_s.strip
|
124
|
+
end
|
125
|
+
self["#{@name}_#{i+1}"] = obj = instantiate(data)
|
126
|
+
@objects << obj
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
# Instantiate an actual object from the Fixture data.
|
133
|
+
|
134
|
+
def instantiate(data)
|
135
|
+
obj = @klass.allocate
|
136
|
+
|
137
|
+
for key, value in data
|
138
|
+
obj.instance_variable_set("@#{key}", value)
|
139
|
+
end
|
140
|
+
|
141
|
+
return obj
|
142
|
+
end
|
143
|
+
|
144
|
+
def class_to_name(klass)
|
145
|
+
klass.to_s.demodulize.underscore
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/mail.rb
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'net/smtp'
|
2
|
+
|
3
|
+
module Glue
|
4
|
+
|
5
|
+
# Encapsulates an email message.
|
6
|
+
|
7
|
+
class Mail
|
8
|
+
|
9
|
+
# The default charset.
|
10
|
+
|
11
|
+
setting :default_charset, :default => 'utf-8', :doc => 'The default character set'
|
12
|
+
|
13
|
+
# Encode the subject?
|
14
|
+
|
15
|
+
setting :encode_subject, :default => false, :doc => 'Encode the subject?'
|
16
|
+
|
17
|
+
# Sender, can be an array.
|
18
|
+
|
19
|
+
attr_accessor :from
|
20
|
+
|
21
|
+
# The list of the recipients, can be arrays.
|
22
|
+
|
23
|
+
attr_accessor :to, :cc, :bcc
|
24
|
+
|
25
|
+
# The subject
|
26
|
+
|
27
|
+
attr_accessor :subject
|
28
|
+
|
29
|
+
# The body of the message.
|
30
|
+
|
31
|
+
attr_accessor :body
|
32
|
+
|
33
|
+
# Reply to.
|
34
|
+
|
35
|
+
attr_accessor :reply_to
|
36
|
+
|
37
|
+
# Sent on
|
38
|
+
|
39
|
+
attr_accessor :sent_on
|
40
|
+
|
41
|
+
# Encode the subject?
|
42
|
+
|
43
|
+
attr_accessor :encode_subject
|
44
|
+
|
45
|
+
# The charset used to encode the message.
|
46
|
+
|
47
|
+
attr_accessor :charset
|
48
|
+
|
49
|
+
# Additional headers
|
50
|
+
|
51
|
+
attr_accessor :headers
|
52
|
+
|
53
|
+
def initialize(from = nil, to = nil, subject = nil, body = nil)
|
54
|
+
@from, @to, @subject, @body = from, to, subject, body
|
55
|
+
@headers = {}
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_headers
|
59
|
+
@from = @headers['From']
|
60
|
+
@to = @headers['To']
|
61
|
+
@cc = @headers['Cc']
|
62
|
+
@bcc = @headers['Bcc']
|
63
|
+
@subject = @headers['Subject']
|
64
|
+
end
|
65
|
+
|
66
|
+
# Accept string or IO.
|
67
|
+
|
68
|
+
def self.new_from_encoded(encoded)
|
69
|
+
if encoded.is_a? String
|
70
|
+
require 'stringio'
|
71
|
+
encoded = StringIO.new(encoded)
|
72
|
+
end
|
73
|
+
|
74
|
+
f = encoded
|
75
|
+
|
76
|
+
# the following code is copied from mailread.rb
|
77
|
+
|
78
|
+
unless defined? f.gets
|
79
|
+
f = open(f, "r")
|
80
|
+
opened = true
|
81
|
+
end
|
82
|
+
|
83
|
+
_headers = {}
|
84
|
+
_body = []
|
85
|
+
begin
|
86
|
+
while line = f.gets()
|
87
|
+
line.chop!
|
88
|
+
next if /^From /=~line # skip From-line
|
89
|
+
break if /^$/=~line # end of header
|
90
|
+
|
91
|
+
if /^(\S+?):\s*(.*)/=~line
|
92
|
+
(attr = $1).capitalize!
|
93
|
+
_headers[attr] = $2
|
94
|
+
elsif attr
|
95
|
+
line.sub!(/^\s*/, '')
|
96
|
+
_headers[attr] += "\n" + line
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
return unless line
|
101
|
+
|
102
|
+
while line = f.gets()
|
103
|
+
break if /^From /=~line
|
104
|
+
_body.push(line)
|
105
|
+
end
|
106
|
+
ensure
|
107
|
+
f.close if opened
|
108
|
+
end
|
109
|
+
|
110
|
+
mail = Mail.new
|
111
|
+
mail.headers = _headers
|
112
|
+
mail.body = _body.join("\n")
|
113
|
+
mail.parse_headers
|
114
|
+
|
115
|
+
return mail
|
116
|
+
end
|
117
|
+
|
118
|
+
def [](key)
|
119
|
+
@headers[key]
|
120
|
+
end
|
121
|
+
|
122
|
+
def []=(key, value)
|
123
|
+
@headers[key] = value
|
124
|
+
end
|
125
|
+
|
126
|
+
# Returns the Mail message in encoded format.
|
127
|
+
|
128
|
+
def encoded
|
129
|
+
raise 'No body defined' unless @body
|
130
|
+
raise 'No sender defined' unless @from
|
131
|
+
raise 'No recipients defined' unless @to
|
132
|
+
|
133
|
+
# gmosx: From is typically NOT an array.
|
134
|
+
|
135
|
+
from = @from.is_a?(Array) ? @from.join(', ') : @from
|
136
|
+
buf = "From: #{from}\n"
|
137
|
+
|
138
|
+
to = @to.is_a?(Array) ? @to.join(', ') : @to
|
139
|
+
buf << "To: #{to}\n"
|
140
|
+
|
141
|
+
if @cc
|
142
|
+
cc = @cc.is_a?(Array) ? @cc.join(', ') : @cc
|
143
|
+
buf << "Cc: #{cc}\n"
|
144
|
+
end
|
145
|
+
|
146
|
+
if @bcc
|
147
|
+
bcc = @bcc.is_a?(Array) ? @bcc.join(', ') : @bcc
|
148
|
+
buf << "Bcc: #{bcc}\n"
|
149
|
+
end
|
150
|
+
|
151
|
+
buf << "Subject: #@subject\n" if @subject
|
152
|
+
|
153
|
+
buf << "\n"
|
154
|
+
buf << @body
|
155
|
+
|
156
|
+
return buf
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/mailer.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'glue/mail'
|
2
|
+
require 'glue/mailer/incoming'
|
3
|
+
require 'glue/mailer/outgoing'
|
4
|
+
require 'glue/configuration'
|
5
|
+
|
6
|
+
module Glue
|
7
|
+
|
8
|
+
# Handles incoming and outgoing emails. Can be called from
|
9
|
+
# a Controller or a standalone script (target of the MTA).
|
10
|
+
|
11
|
+
class Mailer < Mail
|
12
|
+
include IncomingMailer
|
13
|
+
include OutgoingMailer
|
14
|
+
|
15
|
+
# The outgoing mail server configuration.
|
16
|
+
|
17
|
+
setting :server, :default => {
|
18
|
+
:address => 'localhost',
|
19
|
+
:port => 25,
|
20
|
+
:domain => 'localhost.localdomain',
|
21
|
+
:username => nil,
|
22
|
+
:password => nil,
|
23
|
+
:authentication => nil
|
24
|
+
}, :doc => 'The outgoing server configuration'
|
25
|
+
|
26
|
+
# The delivery method. The following options are
|
27
|
+
# supported:
|
28
|
+
#
|
29
|
+
# * :smtp
|
30
|
+
# * :sendmail
|
31
|
+
# * :test
|
32
|
+
|
33
|
+
setting :delivery_method, :default => :smtp, :doc => 'The delivery method'
|
34
|
+
|
35
|
+
# Disable deliveries, useful for testing.
|
36
|
+
|
37
|
+
setting :disable_deliveries, :default => false, :doc => 'Dissable deliveries?'
|
38
|
+
|
39
|
+
# The default template root.
|
40
|
+
|
41
|
+
setting :template_root, :default => 'template/mail', :doc => 'The default template root'
|
42
|
+
|
43
|
+
# An array to store the delivered mails, useful
|
44
|
+
# for testing.
|
45
|
+
|
46
|
+
cattr_accessor :deliveries; @@deliveries = []
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Glue
|
2
|
+
|
3
|
+
# Add support for incoming mail handling.
|
4
|
+
#
|
5
|
+
# You need to setup your MTA to support incoming email
|
6
|
+
# handling. Here is an example for Postfix. Edit these files:
|
7
|
+
#
|
8
|
+
# /etc/postfix/master.cf:
|
9
|
+
# mailman unix - n n - - pipe
|
10
|
+
# flags= user=nobody argv=/path/to/ruby /path/to/app/script/runner.rb Mailer.receive(STDIN)
|
11
|
+
#
|
12
|
+
# /etc/postfix/main.cf:
|
13
|
+
# transport_maps = hash:/etc/postfix/transport
|
14
|
+
# virtual_mailbox_domains = lists.yourdomain.com
|
15
|
+
#
|
16
|
+
# /etc/postfix/transport:
|
17
|
+
# lists.yourdomain.com mailman:
|
18
|
+
#
|
19
|
+
# Then run:
|
20
|
+
#
|
21
|
+
# sudo postmap transport
|
22
|
+
# sudo postfix stop
|
23
|
+
# sudo postfix start
|
24
|
+
|
25
|
+
module IncomingMailer
|
26
|
+
def self.included(base)
|
27
|
+
base.extend ClassMethods
|
28
|
+
end
|
29
|
+
|
30
|
+
# You can overide this class for specialized handling.
|
31
|
+
|
32
|
+
def receive(mail)
|
33
|
+
end
|
34
|
+
|
35
|
+
module ClassMethods
|
36
|
+
def receive(encoded)
|
37
|
+
mail = Glue::Mail.new_from_encoded(encoded)
|
38
|
+
self.new.receive(mail)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Glue
|
2
|
+
|
3
|
+
# Add support for outgoing mail handling.
|
4
|
+
|
5
|
+
module OutgoingMailer
|
6
|
+
# The root directory where the templates reside.
|
7
|
+
|
8
|
+
attr_accessor :template_root
|
9
|
+
|
10
|
+
def self.included(base)
|
11
|
+
base.extend ClassMethods
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(from = nil, to = nil, subject = nil, body = FileTemplate.new)
|
15
|
+
super
|
16
|
+
@charset = Mailer.default_charset.dup
|
17
|
+
@encode_subject = Mailer.encode_subject
|
18
|
+
@template_root = Mailer.template_root
|
19
|
+
end
|
20
|
+
|
21
|
+
module ClassMethods
|
22
|
+
def method_missing(method_symbol, *params) #:nodoc:
|
23
|
+
case method_symbol.id2name
|
24
|
+
when /^create_([_a-z]*)/
|
25
|
+
create_from_method($1, *params)
|
26
|
+
when /^deliver_([_a-z]*)/
|
27
|
+
begin
|
28
|
+
deliver(send("create_" + $1, *params))
|
29
|
+
rescue Object => e
|
30
|
+
raise e # FIXME
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def mail(from, to, subject, body, timestamp = nil, headers = {}, encode = Mail.encode_subject, charset = Mail.default_charset) #:nodoc:
|
36
|
+
deliver(create(from, to, subject, body, timestamp, headers, charset))
|
37
|
+
end
|
38
|
+
|
39
|
+
def create(from, to, subject, body, timestamp = nil, headers = {}, encode = Mail.encode_subject, charset = Mail.default_charset) #:nodoc:
|
40
|
+
m = Mail.new
|
41
|
+
m.to, m.subject, m.body, m.from = to, ( encode ? quoted_printable(subject, charset) : subject ), body, from
|
42
|
+
# m.date = timestamp.respond_to?("to_time") ? timestamp.to_time : (timestamp || Time.now)
|
43
|
+
# m.set_content_type "text", "plain", { "charset" => charset }
|
44
|
+
headers.each do |k, v|
|
45
|
+
m[k] = v
|
46
|
+
end
|
47
|
+
return m
|
48
|
+
end
|
49
|
+
|
50
|
+
def deliver(mail) #:nodoc:
|
51
|
+
# gmosx, FIXME: for some STUPID reason, delivery_method
|
52
|
+
# returns nil, investigate.
|
53
|
+
Mailer.delivery_method = :smtp
|
54
|
+
unless Mailer.disable_deliveries
|
55
|
+
send("perform_delivery_#{Mailer.delivery_method}", mail)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def quoted_printable(text, charset) #:nodoc:
|
60
|
+
text = text.gsub( /[^a-z ]/i ) { "=%02x" % $&[0] }.gsub( / /, "_" )
|
61
|
+
"=?#{charset}?Q?#{text}?="
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def create_from_method(method_name, *params)
|
67
|
+
mailer = new
|
68
|
+
|
69
|
+
mailer.send(method_name, *params)
|
70
|
+
|
71
|
+
unless mailer.body.is_a?(String)
|
72
|
+
mailer.body = render_body(method_name, mailer)
|
73
|
+
end
|
74
|
+
|
75
|
+
mail = create(
|
76
|
+
mailer.from, mailer.to, mailer.subject,
|
77
|
+
mailer.body, mailer.sent_on,
|
78
|
+
mailer.headers, mailer.charset
|
79
|
+
)
|
80
|
+
|
81
|
+
mail.cc = mailer.cc if mailer.cc
|
82
|
+
mail.bcc = mailer.bcc if mailer.bcc
|
83
|
+
|
84
|
+
return mail
|
85
|
+
end
|
86
|
+
|
87
|
+
# Render the body by expanding the template
|
88
|
+
|
89
|
+
def render_body(method_name, mailer)
|
90
|
+
mailer.body.template_filename = "#{mailer.template_root}/#{method_name.to_s}.xhtml"
|
91
|
+
return mailer.body.process
|
92
|
+
end
|
93
|
+
|
94
|
+
# Deliver emails using SMTP.
|
95
|
+
|
96
|
+
def perform_delivery_smtp(mail) # :nodoc:
|
97
|
+
c = Mailer.server
|
98
|
+
Net::SMTP.start(c[:address], c[:port], c[:domain], c[:username], c[:password], c[:authentication]) do |smtp|
|
99
|
+
smtp.send_message(mail.encoded, mail.from, mail.to)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Deliver emails using sendmail.
|
104
|
+
|
105
|
+
def perform_delivery_sendmail(mail) # :nodoc:
|
106
|
+
IO.popen('/usr/sbin/sendmail -i -t', 'w+') do |sm|
|
107
|
+
sm.print(mail.encoded)
|
108
|
+
sm.flush
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# Used for testing, does not actually send the
|
113
|
+
# mail.
|
114
|
+
|
115
|
+
def perform_delivery_test(mail) # :nodoc:
|
116
|
+
deliveries << mail
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'glue/flexob'
|
2
|
+
require 'glue/configuration'
|
3
|
+
|
4
|
+
module Glue
|
5
|
+
|
6
|
+
# A template is a text file with embeded Ruby code. The template
|
7
|
+
# processor converts the original text file to ruby code and
|
8
|
+
# then evaluates this code to produce the result of the
|
9
|
+
# template transformation.
|
10
|
+
|
11
|
+
module TemplateMixin
|
12
|
+
|
13
|
+
# Convert a template to actual Ruby code, ready to be
|
14
|
+
# evaluated.
|
15
|
+
#
|
16
|
+
# [+template+]
|
17
|
+
# The template as a String.
|
18
|
+
#
|
19
|
+
# [+buffer+]
|
20
|
+
# The variable to act as a buffer where the ruby code
|
21
|
+
# for this template will be generated. Passed as a|
|
22
|
+
# String.
|
23
|
+
#
|
24
|
+
# [+base_dir+]
|
25
|
+
# The base directory where the templates reside.
|
26
|
+
|
27
|
+
def compile_template(template, buffer = '@out', base_dir = Dir.pwd)
|
28
|
+
text = template.dup
|
29
|
+
|
30
|
+
# Strip the xml header! (interracts with the following gsub!)
|
31
|
+
text.gsub!(/<\?xml.*\?>/, "")
|
32
|
+
|
33
|
+
# Statically include sub-template files.
|
34
|
+
# The target file is included at compile time.
|
35
|
+
#
|
36
|
+
# gmosx: must be xformed before the <?r pi.
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
# <?include href="root/myfile.sx" ?>
|
40
|
+
|
41
|
+
text.gsub!(/<\?include href=["|'](.*?)["|'](.*)\?>/) do |match|
|
42
|
+
text = File.read("#{base_dir}/#$1")
|
43
|
+
text.gsub!(/<\?xml.*\?>/, '')
|
44
|
+
text.gsub!(/<\/?root(.*?)>/m, ' ');
|
45
|
+
text
|
46
|
+
end
|
47
|
+
|
48
|
+
# Transform include instructions <include href="xxx" />
|
49
|
+
# must be transformed before the processinc instructions.
|
50
|
+
# Useful to include fragments cached on disk
|
51
|
+
#
|
52
|
+
# gmosx, FIXME: NOT TESTED! test and add caching.
|
53
|
+
# add load_statically_included fixes.
|
54
|
+
|
55
|
+
text.gsub!(/<include href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
56
|
+
"<?r File.read( '\#\{@dispatcher.root\}/#$1' ?>"
|
57
|
+
end
|
58
|
+
|
59
|
+
# xform render/inject instructions <render href="xxx" />
|
60
|
+
# must be transformed before the processinc instructions.
|
61
|
+
|
62
|
+
text.gsub!(/<inject href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
63
|
+
"<?r render '/#$1' ?>"
|
64
|
+
end
|
65
|
+
|
66
|
+
text.gsub!(/<render href=["|'](.*?)["|'](.*)(.?)\/>/) do |match|
|
67
|
+
"<?r render '/#$1' ?>"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Remove <root> elements. typically removed by xslt but lets
|
71
|
+
# play it safe. The <root> element is typically added to
|
72
|
+
# template files to make them XHTML valid.
|
73
|
+
|
74
|
+
text.gsub!(/<(\/)?root>/, '')
|
75
|
+
|
76
|
+
# Transform the processing instructions, use <?r as
|
77
|
+
# a marker.
|
78
|
+
|
79
|
+
text.gsub!(/\?>/, "; #{buffer} << %^")
|
80
|
+
text.gsub!(/<\?r(\s?)/, "^; ")
|
81
|
+
|
82
|
+
# Transform alternative code tags.
|
83
|
+
# (very useful in xsl stylesheets)
|
84
|
+
|
85
|
+
text.gsub!(/<\/ruby>/, "; #{buffer} << %^")
|
86
|
+
text.gsub!(/<ruby>/, "^; ")
|
87
|
+
|
88
|
+
# Also handle erb/asp/jsp style tags. Those tags
|
89
|
+
# *cannot* be used with an xslt stylesheet.
|
90
|
+
|
91
|
+
text.gsub!(/%>/, "; #{buffer} << %^")
|
92
|
+
text.gsub!(/<%/, "^; ")
|
93
|
+
|
94
|
+
# Alterative versions of interpolation.
|
95
|
+
# (very useful in xsl stylesheets)
|
96
|
+
# Example: #\my_val\
|
97
|
+
|
98
|
+
text.gsub!(/\#\\(.*?)\\/, '#{\1}')
|
99
|
+
|
100
|
+
# Alternative for entities.
|
101
|
+
# (useful in xsl stylesheets)
|
102
|
+
# Examples: %nbsp;, %rquo;
|
103
|
+
|
104
|
+
text.gsub!(/%(\S*?);/, '&\1;')
|
105
|
+
|
106
|
+
# Compile time ruby code. This code is evaluated when
|
107
|
+
# compiling the template and the result injected directly
|
108
|
+
# into the result. Usefull for example to prevaluate
|
109
|
+
# localization. Just use the #[] marker instead of #{}.
|
110
|
+
|
111
|
+
text.gsub!(/\#\[(.*?)\]/) do |match|
|
112
|
+
eval($1)
|
113
|
+
end
|
114
|
+
|
115
|
+
text = "#{buffer} << %^" + text + "^"
|
116
|
+
|
117
|
+
return text
|
118
|
+
end
|
119
|
+
|
120
|
+
# Evaluate the template.
|
121
|
+
#
|
122
|
+
# [+ruby+]
|
123
|
+
# A String containing the compiled template
|
124
|
+
# code.
|
125
|
+
#
|
126
|
+
# [+binding+]
|
127
|
+
# The evaluation binding for the rendering.
|
128
|
+
|
129
|
+
def evaluate_template(ruby, the_binding = nil)
|
130
|
+
eval(ruby, the_binding)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Compile and render the template.
|
134
|
+
|
135
|
+
def process_template(template, buffer = '@out', the_binding = nil)
|
136
|
+
evaluate_template(compile_template(template, buffer), the_binding)
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
# A helper class that provides access to the Template methods
|
142
|
+
# as singleton methods.
|
143
|
+
|
144
|
+
class Template
|
145
|
+
|
146
|
+
# The default root directory where template files reside.
|
147
|
+
|
148
|
+
setting :root, :default => 'public', :doc => 'The default root directory where template files reside'
|
149
|
+
|
150
|
+
# The default template name.
|
151
|
+
|
152
|
+
setting :default, :default => 'index', :doc => 'The default template name'
|
153
|
+
|
154
|
+
# The default template file extension.
|
155
|
+
|
156
|
+
setting :extension, :default => 'xhtml', :doc => 'The default template file extension'
|
157
|
+
|
158
|
+
class << self
|
159
|
+
include TemplateMixin
|
160
|
+
alias_method :compile, :compile_template
|
161
|
+
alias_method :transform, :compile_template
|
162
|
+
alias_method :evaluate, :evaluate_template
|
163
|
+
alias_method :process, :process_template
|
164
|
+
end
|
165
|
+
|
166
|
+
include TemplateMixin
|
167
|
+
|
168
|
+
# Helper.
|
169
|
+
|
170
|
+
def render(template)
|
171
|
+
str = ''
|
172
|
+
process_template(template, 'str', binding)
|
173
|
+
return str
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# A Template that reads from files and also
|
178
|
+
# provides a simple but effective caching scheme.
|
179
|
+
# An intuitive binding mechanism provides the
|
180
|
+
# expansion environment.
|
181
|
+
|
182
|
+
class FileTemplate < Flexob
|
183
|
+
include TemplateMixin
|
184
|
+
|
185
|
+
@@compiled_template_cache = {}
|
186
|
+
|
187
|
+
attr_accessor :template_filename
|
188
|
+
|
189
|
+
def initialize(filename = nil)
|
190
|
+
super
|
191
|
+
@template_filename = filename
|
192
|
+
end
|
193
|
+
|
194
|
+
def process
|
195
|
+
__out__ = ''
|
196
|
+
|
197
|
+
unless compiled = @@compiled_template_cache[@template_filename]
|
198
|
+
template = File.read(@template_filename)
|
199
|
+
compiled = compile_template(template, '__out__')
|
200
|
+
@@compiled_template_cache[@template_filename] = compiled
|
201
|
+
end
|
202
|
+
|
203
|
+
evaluate_template(compiled, binding)
|
204
|
+
|
205
|
+
return __out__
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
end
|
210
|
+
|
211
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/glue/validation.rb
CHANGED
@@ -1,7 +1,3 @@
|
|
1
|
-
# * George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: validation.rb 182 2005-07-22 10:07:50Z gmosx $
|
4
|
-
|
5
1
|
module Glue
|
6
2
|
|
7
3
|
# Implements a meta-language for validating managed
|
@@ -459,3 +455,4 @@ class Module # :nodoc: all
|
|
459
455
|
include Glue::Validation::MetaLanguage
|
460
456
|
end
|
461
457
|
|
458
|
+
# * George Moschovitis <gm@navel.gr>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), 'lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'glue/fixture'
|
5
|
+
|
6
|
+
class TestFixture < Test::Unit::TestCase # :nodoc: all
|
7
|
+
include Glue
|
8
|
+
|
9
|
+
class User
|
10
|
+
attr_accessor :name
|
11
|
+
attr_accessor :age
|
12
|
+
end
|
13
|
+
|
14
|
+
class Article
|
15
|
+
attr_accessor :title
|
16
|
+
attr_accessor :body
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_all
|
20
|
+
users = Fixture.new(User)
|
21
|
+
|
22
|
+
assert_equal 3, users.size
|
23
|
+
george = users['george']
|
24
|
+
assert_equal 30, george.age
|
25
|
+
assert_equal 'Renos', users['renos'].name
|
26
|
+
|
27
|
+
articles = Fixture.new(Article)
|
28
|
+
|
29
|
+
assert_equal 9, articles.size
|
30
|
+
assert_equal 'This is cool', articles['article_1'].title
|
31
|
+
assert_equal 'Another', articles['article_2'].title
|
32
|
+
assert_equal 'I love this', articles['Test'].title
|
33
|
+
|
34
|
+
assert_equal 'title 3', articles['Auto3'].title
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_global
|
38
|
+
Fixtures.load User, Article
|
39
|
+
assert_equal 3, Fixtures.user.size
|
40
|
+
assert_equal 'This is cool', Fixtures.article['article_1'].title
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
2
|
+
|
3
|
+
$NITRO_NO_ENVIRONMENT = true
|
4
|
+
|
5
|
+
require 'test/unit'
|
6
|
+
require 'ostruct'
|
7
|
+
|
8
|
+
require 'nitro'
|
9
|
+
require 'glue/configuration'
|
10
|
+
require 'glue/mailer'
|
11
|
+
|
12
|
+
class TestCaseMail < Test::Unit::TestCase # :nodoc: all
|
13
|
+
include Glue
|
14
|
+
|
15
|
+
class DummyMailer < Mailer
|
16
|
+
def initialize
|
17
|
+
super
|
18
|
+
@bcc = 'gm@navel.gr'
|
19
|
+
@template_root = 'test/public/dummy_mailer'
|
20
|
+
end
|
21
|
+
|
22
|
+
def registration(to, username, token)
|
23
|
+
@to = to
|
24
|
+
@from = 'system@navel.gr'
|
25
|
+
@subject = 'Nitro.com registration'
|
26
|
+
@cc = 'gm@navel.gr'
|
27
|
+
@body.username = username
|
28
|
+
@body.token = token
|
29
|
+
end
|
30
|
+
|
31
|
+
def greek(to)
|
32
|
+
@to = to
|
33
|
+
@from = 'system@navel.gr'
|
34
|
+
@subject = 'Ελληνικός Τίτλος'
|
35
|
+
@cc = 'gm@navel.gr'
|
36
|
+
@body = 'Τί έγινε ρε παιδιά;'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
=begin
|
40
|
+
class DummyController < Controller
|
41
|
+
# mailer DummyMailer
|
42
|
+
|
43
|
+
def register
|
44
|
+
token = 999
|
45
|
+
deliver_registration('gmosx@navel.gr', 'gmosx', token)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
=end
|
49
|
+
def test_mail
|
50
|
+
m = Glue::Mail.new 'gmosx@navel.gr', 'drak@navel.gr', 'A simple test', 'This is the body of the message'
|
51
|
+
expected = %{From: gmosx@navel.gr
|
52
|
+
To: drak@navel.gr
|
53
|
+
Subject: A simple test
|
54
|
+
|
55
|
+
This is the body of the message}
|
56
|
+
assert_equal expected, m.encoded
|
57
|
+
|
58
|
+
m.to = %w{ renos@navel.gr stella@navel.gr }
|
59
|
+
expected = %{From: gmosx@navel.gr
|
60
|
+
To: renos@navel.gr, stella@navel.gr
|
61
|
+
Subject: A simple test
|
62
|
+
|
63
|
+
This is the body of the message}
|
64
|
+
assert_equal expected, m.encoded
|
65
|
+
|
66
|
+
end
|
67
|
+
=begin
|
68
|
+
def test_mailer
|
69
|
+
assert_equal 0, DummyMailer.deliveries.size
|
70
|
+
|
71
|
+
Mailer.server[:address] = 'mail.navel.gr'
|
72
|
+
# assert_equal 'mail.navel.gr', DummyMailer.server[:address]
|
73
|
+
|
74
|
+
Mailer.delivery_method = :test
|
75
|
+
Mailer.template_root = File.join(File.dirname(__FILE__), '..', 'root', 'dummy_mailer')
|
76
|
+
token = 999
|
77
|
+
DummyMailer.deliver_registration('gm@navel.gr', 'gmosx', token)
|
78
|
+
assert_equal 1, DummyMailer.deliveries.size
|
79
|
+
|
80
|
+
expected = %{From: system@navel.gr
|
81
|
+
To: gm@navel.gr
|
82
|
+
Cc: gm@navel.gr
|
83
|
+
Bcc: gm@navel.gr
|
84
|
+
Subject: =?utf-8?Q?Nitro=2ecom_registration?=
|
85
|
+
|
86
|
+
Hello gmosx
|
87
|
+
|
88
|
+
how do you feel?
|
89
|
+
|
90
|
+
Here is your <b>Token</b>: 999
|
91
|
+
}
|
92
|
+
assert_equal expected, DummyMailer.deliveries[0].encoded
|
93
|
+
|
94
|
+
DummyMailer.deliver_greek('gm@navel.gr')
|
95
|
+
assert_equal 2, DummyMailer.deliveries.size
|
96
|
+
end
|
97
|
+
=end
|
98
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', '..', 'lib')
|
2
|
+
|
3
|
+
require 'test/unit'
|
4
|
+
require 'ostruct'
|
5
|
+
|
6
|
+
require 'glue/template'
|
7
|
+
|
8
|
+
class TestTemplate < Test::Unit::TestCase # :nodoc: all
|
9
|
+
include Glue
|
10
|
+
|
11
|
+
def test_all
|
12
|
+
template = %q{
|
13
|
+
Hello #{user}
|
14
|
+
|
15
|
+
dont forget the following todo items:
|
16
|
+
|
17
|
+
<?r for item in items ?>
|
18
|
+
<li>#{item}</li>
|
19
|
+
<?r end ?>
|
20
|
+
}
|
21
|
+
|
22
|
+
user = 'gmosx'
|
23
|
+
items = %w{ nitro is really great }
|
24
|
+
out = ''
|
25
|
+
|
26
|
+
Template.process(template, :out, binding)
|
27
|
+
|
28
|
+
assert_match %r{\<li\>nitro\</li\>}, out
|
29
|
+
assert_match %r{\<li\>really\</li\>}, out
|
30
|
+
assert_match %r{Hello gmosx}, out
|
31
|
+
end
|
32
|
+
end
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: glue
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2005-07
|
6
|
+
version: 0.22.0
|
7
|
+
date: 2005-08-07 00:00:00 +03:00
|
8
8
|
summary: Glue utilities
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -40,7 +40,6 @@ files:
|
|
40
40
|
- lib/glue
|
41
41
|
- lib/html
|
42
42
|
- lib/glue.rb
|
43
|
-
- lib/facet
|
44
43
|
- lib/vendor
|
45
44
|
- lib/glue/logger.rb
|
46
45
|
- lib/glue/array.rb
|
@@ -67,22 +66,24 @@ files:
|
|
67
66
|
- lib/glue/helper.rb
|
68
67
|
- lib/glue/settings.rb
|
69
68
|
- lib/glue/builder.rb
|
69
|
+
- lib/glue/fixture.rb
|
70
70
|
- lib/glue/cache.rb
|
71
|
-
- lib/glue/
|
72
|
-
- lib/glue/idgen.rb
|
71
|
+
- lib/glue/mail.rb
|
73
72
|
- lib/glue/snapshot.rb
|
74
|
-
- lib/glue/
|
73
|
+
- lib/glue/mailer
|
74
|
+
- lib/glue/mailer.rb
|
75
|
+
- lib/glue/template.rb
|
75
76
|
- lib/glue/builder/xml.rb
|
76
|
-
- lib/glue/
|
77
|
-
- lib/glue/
|
77
|
+
- lib/glue/mailer/incoming.rb
|
78
|
+
- lib/glue/mailer/outgoing.rb
|
78
79
|
- lib/html/document.rb
|
79
80
|
- lib/html/node.rb
|
80
81
|
- lib/html/version.rb
|
81
82
|
- lib/html/tokenizer.rb
|
82
|
-
- lib/facet/object
|
83
|
-
- lib/facet/object/alias_class.rb
|
84
83
|
- lib/vendor/blankslate.rb
|
85
84
|
- test/glue
|
85
|
+
- test/fixture
|
86
|
+
- test/public
|
86
87
|
- test/glue/tc_configuration.rb
|
87
88
|
- test/glue/tc_strings.rb
|
88
89
|
- test/glue/tc_validation.rb
|
@@ -99,7 +100,15 @@ files:
|
|
99
100
|
- test/glue/tc_builder.rb
|
100
101
|
- test/glue/tc_uri.rb
|
101
102
|
- test/glue/tc_localization.rb
|
103
|
+
- test/glue/tc_fixture.rb
|
104
|
+
- test/glue/tc_mail.rb
|
105
|
+
- test/glue/tc_template.rb
|
102
106
|
- test/glue/builder/tc_xml.rb
|
107
|
+
- test/fixture/user.yml
|
108
|
+
- test/fixture/article.yml
|
109
|
+
- test/fixture/article.csv
|
110
|
+
- test/public/dummy_mailer
|
111
|
+
- test/public/dummy_mailer/registration.xhtml
|
103
112
|
test_files: []
|
104
113
|
rdoc_options:
|
105
114
|
- "--main"
|
data/lib/glue/idgen.rb
DELETED
data/lib/glue/idgen/md5.rb
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
# Returned ids might not be unique, but it should be very hard to guess the
|
2
|
-
# next id.
|
3
|
-
|
4
|
-
require 'glue/idgen'
|
5
|
-
require 'digest/md5'
|
6
|
-
|
7
|
-
class Glue::Md5IdGenerator < Glue::IdGenerator
|
8
|
-
def initialize(salt='ruby')
|
9
|
-
@salt = salt
|
10
|
-
end
|
11
|
-
|
12
|
-
def next
|
13
|
-
now = Time.now
|
14
|
-
md5 = Digest::MD5.new
|
15
|
-
md5.update(now.to_s)
|
16
|
-
md5.update(now.usec.to_s)
|
17
|
-
md5.update(rand(0).to_s)
|
18
|
-
md5.update($$.to_s)
|
19
|
-
md5.update(@salt.to_s)
|
20
|
-
md5.hexdigest
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# * Michael Neumann <mneumann@ntecs.de>
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# Returned ids are guaranteed to be unique, but they are easily guessable.
|
2
|
-
|
3
|
-
require 'glue/idgen'
|
4
|
-
|
5
|
-
class Glue::SequentialIdGenerator < Glue::IdGenerator
|
6
|
-
def initialize(initial_value=0)
|
7
|
-
@value = initial_value
|
8
|
-
end
|
9
|
-
|
10
|
-
def next
|
11
|
-
@value += 1
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
# * Michael Neumann <mneumann@ntecs.de>
|
data/lib/glue/literal_method.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
module Glue
|
2
|
-
|
3
|
-
# A serializable method.
|
4
|
-
#
|
5
|
-
# For example, you can't marshal:
|
6
|
-
#
|
7
|
-
# "ruby".method(:to_s)
|
8
|
-
#
|
9
|
-
# But you can:
|
10
|
-
#
|
11
|
-
# Glue::LiteralMethodCallback.new("ruby", :to_s)
|
12
|
-
#
|
13
|
-
# or it's equivalent:
|
14
|
-
#
|
15
|
-
# "ruby".literal_method(:to_s)
|
16
|
-
|
17
|
-
class LiteralMethod
|
18
|
-
attr_reader :obj
|
19
|
-
|
20
|
-
def initialize(obj, method_id=:call, *args)
|
21
|
-
@obj, @method_id = obj, method_id
|
22
|
-
@args = args unless args.empty?
|
23
|
-
end
|
24
|
-
|
25
|
-
def call(*args, &block)
|
26
|
-
if @args
|
27
|
-
@obj.send(@method_id, *(@args+args), &block)
|
28
|
-
else
|
29
|
-
@obj.send(@method_id, *args, &block)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
alias [] call
|
34
|
-
end
|
35
|
-
|
36
|
-
end # module Glue
|
37
|
-
|
38
|
-
class Object
|
39
|
-
def literal_method(method_id, *args)
|
40
|
-
Glue::LiteralMethodCallback.new(self, method_id, *args)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
# * Michael Neumann <mneumann@ntecs.de>
|