gloo-email 1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 738fcacc7475ef8b8404861a76e59b6711fdd54a7423429d442f79bddf29316e
4
+ data.tar.gz: d6cfda322d190c5ebede7d8d3d811e30b89b752dafeef32f526b2a61503aa362
5
+ SHA512:
6
+ metadata.gz: cf5c545dad112ea64891fed3fd235a657c95b2a6dfa365aadf375279613089a9f1b78fb072145f2ee30a00debd8ea4a90e2d94fd32c773e05b4c18730fc1f2ee
7
+ data.tar.gz: 8f46e2fd256810f41cb87fdb026e218062920b510bc5ee8c574589b3e273b7ffc1ab0a5f62a01086bfde0c72034e08912a787ede5446b7c270fc59324a59118e
data/README.md ADDED
@@ -0,0 +1,21 @@
1
+ # gloo-email
2
+
3
+ A core gloo library for sending and fetching emails.
4
+
5
+ ## Usage
6
+
7
+ Load this library in a gloo script:
8
+
9
+ ```gloo
10
+ > load lib email
11
+ ```
12
+
13
+ ## Objects
14
+
15
+ - `email_smtp` — SMTP configuration, used to send email
16
+ - `email_imap` — an IMAP connection, used to fetch email
17
+ - `email` — an email message (recipient, sender, subject, body)
18
+
19
+ ## Full Reference
20
+
21
+ Every object's children and messages are documented in-app once the library is loaded — e.g. `help> object email_smtp`.
data/lib/config.rb ADDED
@@ -0,0 +1,19 @@
1
+ #
2
+ # An Mail Server Configuration
3
+ #
4
+
5
+ class Config
6
+
7
+ attr_accessor :host, :port, :username, :password
8
+
9
+ #
10
+ # Initialize a new SMTP email sender.
11
+ #
12
+ def initialize( host, port, username, password )
13
+ @host = host
14
+ @port = port
15
+ @username = username
16
+ @password = password
17
+ end
18
+
19
+ end
data/lib/email_imap.rb ADDED
@@ -0,0 +1,201 @@
1
+ #
2
+ # An email IMAP object
3
+ #
4
+ require 'net/imap'
5
+ require 'mail'
6
+
7
+ class EmailImap < Gloo::Core::Obj
8
+
9
+ KEYWORD = 'email_imap'.freeze
10
+ SERVER = 'server'.freeze
11
+ PORT = 'port'.freeze
12
+ USERNAME = 'username'.freeze
13
+ PASSWORD = 'password'.freeze
14
+ MAILBOX = 'mailbox'.freeze
15
+ MESSAGES = 'messages'.freeze
16
+ SEARCH = 'UNSEEN'.freeze
17
+
18
+ #
19
+ # The name of the object type.
20
+ #
21
+ def self.typename
22
+ return KEYWORD
23
+ end
24
+
25
+ #
26
+ # The short name of the object type.
27
+ # Same as the typename.
28
+ #
29
+ def self.short_typename
30
+ return KEYWORD
31
+ end
32
+
33
+ #
34
+ # Get the email server host.
35
+ #
36
+ def server
37
+ return find_child_value SERVER
38
+ end
39
+
40
+ #
41
+ # Get the email server port.
42
+ #
43
+ def port
44
+ return find_child_value PORT
45
+ end
46
+
47
+ #
48
+ # Get the email username.
49
+ #
50
+ def username
51
+ return find_child_value USERNAME
52
+ end
53
+
54
+ #
55
+ # Get the email password.
56
+ #
57
+ def password
58
+ return find_child_value PASSWORD
59
+ end
60
+
61
+ #
62
+ # Get the email mailbox.
63
+ #
64
+ def mailbox
65
+ return find_child_value MAILBOX
66
+ end
67
+
68
+
69
+ # ---------------------------------------------------------------------
70
+ # Children
71
+ # ---------------------------------------------------------------------
72
+
73
+ # Does this object have children to add when an object
74
+ # is created in interactive mode?
75
+ # This does not apply during obj load, etc.
76
+ def add_children_on_create?
77
+ return true
78
+ end
79
+
80
+ # Add children to this object.
81
+ # This is used by containers to add children needed
82
+ # for default configurations.
83
+ def add_default_children
84
+ fac = @engine.factory
85
+ fac.create_string SERVER, '', self
86
+ fac.create_string PORT, '', self
87
+ fac.create_string USERNAME, '', self
88
+ fac.create_string PASSWORD, '', self
89
+ fac.create_string MAILBOX, '', self
90
+ fac.create_can MESSAGES, self
91
+ end
92
+
93
+
94
+ # ---------------------------------------------------------------------
95
+ # Messages
96
+ # ---------------------------------------------------------------------
97
+
98
+ #
99
+ # Get a list of message names that this object receives.
100
+ #
101
+ def self.messages
102
+ return super + [ 'fetch' ]
103
+ end
104
+
105
+ #
106
+ # Fetch emails from the IMAP server.
107
+ #
108
+ def msg_fetch
109
+ # Connect to the email server
110
+ imap = Net::IMAP.new(server, port, true)
111
+ imap.login(username, password)
112
+ imap.select(mailbox)
113
+
114
+ # Search for messages matching filter
115
+ ids = imap.search([SEARCH])
116
+
117
+ if ids.empty?
118
+ puts "No new messages."
119
+ else
120
+ ids.each do |msg_id|
121
+ raw_message = imap.fetch( msg_id, "RFC822" )[0].attr["RFC822"]
122
+ mail = Mail.read_from_string( raw_message )
123
+ process_message( mail )
124
+ end
125
+ end
126
+
127
+ # -----------------------------
128
+ # CLEAN UP
129
+ # -----------------------------
130
+ imap.logout
131
+ imap.disconnect
132
+ end
133
+
134
+ #
135
+ # Process a single email message
136
+ #
137
+ def process_message( mail )
138
+ from = mail.from.join(', ')
139
+ to = mail.to.join(', ')
140
+ subject = mail.subject
141
+ dt = mail.date
142
+ body = mail.body.decoded
143
+
144
+ msg_can = find_child MESSAGES
145
+
146
+ msg = msg_can.find_add_child( msg_can.children.length.to_s, 'email' )
147
+ o = msg.find_add_child( 'from', 'string' )
148
+ o.set_value from
149
+ o = msg.find_add_child( 'to', 'string' )
150
+ o.set_value to
151
+ o = msg.find_add_child( 'subject', 'string' )
152
+ o.set_value subject
153
+ o = msg.find_add_child( 'date', 'string' )
154
+ o.set_value dt
155
+ o = msg.find_add_child( 'body', 'text' )
156
+ o.set_value body
157
+ end
158
+
159
+ # ---------------------------------------------------------------------
160
+ # Object Documentation
161
+ # ---------------------------------------------------------------------
162
+
163
+ #
164
+ # Get the object's documentation data.
165
+ #
166
+ def self.doc_data
167
+ {
168
+ :name => KEYWORD,
169
+ :shortcut => KEYWORD,
170
+ :description => 'An IMAP email connection, used to fetch ' \
171
+ 'unseen messages from a mailbox.',
172
+ :children => [
173
+ 'server (string) — The IMAP server host.',
174
+ 'port (string) — The IMAP server port.',
175
+ 'username (string) — The username with which to connect.',
176
+ "password (string) — The user's password.",
177
+ 'mailbox (string) — The mailbox to select (e.g. INBOX).',
178
+ 'messages (container) — Populated by fetch: one child per unseen message found, each an email object with from/to/subject/date/body.'
179
+ ],
180
+ :messages => [
181
+ 'fetch — Connect to the IMAP server, select the mailbox, and fetch all unseen messages, adding each as a child of messages. Logs out and disconnects when done.'
182
+ ],
183
+ :notes => 'No vault documentation exists for this object type — ' \
184
+ 'this was authored directly from the code.',
185
+ :examples => <<~EXAMPLES.strip
186
+ mail [can] :
187
+ inbox [email_imap] :
188
+ server : imap.example.com
189
+ port : 993
190
+ username : me@example.com
191
+ password : secret
192
+ mailbox : INBOX
193
+
194
+ on_load [script] :
195
+ tell mail.inbox to fetch
196
+ list mail.inbox.messages
197
+ EXAMPLES
198
+ }
199
+ end
200
+
201
+ end
data/lib/email_msg.rb ADDED
@@ -0,0 +1,165 @@
1
+ #
2
+ # An email message object
3
+ #
4
+ class EmailMsg < Gloo::Core::Obj
5
+
6
+ KEYWORD = 'email'.freeze
7
+ SUBJECT = 'subject'.freeze
8
+ BODY = 'body'.freeze
9
+ TO = 'to'.freeze
10
+ FROM = 'from'.freeze
11
+ WHEN = 'when'.freeze
12
+
13
+ #
14
+ # The name of the object type.
15
+ #
16
+ def self.typename
17
+ return KEYWORD
18
+ end
19
+
20
+ #
21
+ # The short name of the object type.
22
+ # Same as the typename.
23
+ #
24
+ def self.short_typename
25
+ return KEYWORD
26
+ end
27
+
28
+ #
29
+ # Get the email subject.
30
+ #
31
+ def subject
32
+ return find_child_value SUBJECT
33
+ end
34
+
35
+ # Get the email body.
36
+ #
37
+ def body
38
+ return find_child_value BODY
39
+ end
40
+
41
+ # Get the email to.
42
+ #
43
+ def to
44
+ return find_child_value TO
45
+ end
46
+
47
+ # Get the email from.
48
+ #
49
+ def from
50
+ return find_child_value FROM
51
+ end
52
+
53
+ #
54
+ # Get the mail message to send.
55
+ #
56
+ # Returns:
57
+ # A mail message.
58
+ #
59
+ def get_msg
60
+ return Msg.new( to, from, subject, body )
61
+ end
62
+
63
+
64
+ # ---------------------------------------------------------------------
65
+ # Children
66
+ # ---------------------------------------------------------------------
67
+
68
+ # Does this object have children to add when an object
69
+ # is created in interactive mode?
70
+ # This does not apply during obj load, etc.
71
+ def add_children_on_create?
72
+ return true
73
+ end
74
+
75
+ # Add children to this object.
76
+ # This is used by containers to add children needed
77
+ # for default configurations.
78
+ def add_default_children
79
+ fac = @engine.factory
80
+ fac.create_string TO, '', self
81
+ fac.create_string FROM, '', self
82
+ fac.create_string SUBJECT, '', self
83
+ fac.create_text BODY, '', self
84
+ end
85
+
86
+
87
+ # ---------------------------------------------------------------------
88
+ # Messages
89
+ # ---------------------------------------------------------------------
90
+
91
+ #
92
+ # Get a list of message names that this object receives.
93
+ #
94
+ def self.messages
95
+ return super + [ 'send' ]
96
+ end
97
+
98
+ #
99
+ # Send an email.
100
+ #
101
+ def msg_send
102
+ if @params&.token_count&.positive?
103
+ smtp_pn = Gloo::Core::Pn.new( @engine, @params.tokens.first )
104
+ unless smtp_pn&.exists?
105
+ @engine.err 'SMTP server does not exist'
106
+ return
107
+ end
108
+ else
109
+ @engine.err 'Email Message is required'
110
+ return
111
+ end
112
+ config = smtp_pn.resolve.get_config
113
+ msg = get_msg
114
+
115
+ smtp = Smtp.new( @engine, config )
116
+ smtp.send msg
117
+ end
118
+
119
+ # ---------------------------------------------------------------------
120
+ # Object Documentation
121
+ # ---------------------------------------------------------------------
122
+
123
+ #
124
+ # Get the object's documentation data.
125
+ #
126
+ def self.doc_data
127
+ {
128
+ :name => KEYWORD,
129
+ :shortcut => KEYWORD,
130
+ :description => 'An email message — the recipient, sender, ' \
131
+ 'subject and body to send.',
132
+ :children => [
133
+ 'to (string) — The recipient email address.',
134
+ 'from (string) — The sender email address.',
135
+ 'subject (string) — The email subject.',
136
+ 'body (text) — The email body.'
137
+ ],
138
+ :messages => [
139
+ 'send ({smtp.path}) — Send this message using the given SMTP configuration object. A parameter is required: the path to an email_smtp object.'
140
+ ],
141
+ :notes => 'No vault documentation exists for this object type — ' \
142
+ 'this was authored directly from the code.',
143
+ :examples => <<~EXAMPLES.strip
144
+ mail [can] :
145
+ smtp [email_smtp] :
146
+ server : smtp.example.com
147
+ port : 587
148
+ username : me@example.com
149
+ password : secret
150
+
151
+ msg [email] :
152
+ to : someone@example.com
153
+ from : me@example.com
154
+ subject : Hello
155
+ body [text] : BEGIN
156
+ A message sent from gloo.
157
+ END
158
+
159
+ on_load [script] :
160
+ tell mail.msg to send (mail.smtp)
161
+ EXAMPLES
162
+ }
163
+ end
164
+
165
+ end
data/lib/email_smtp.rb ADDED
@@ -0,0 +1,166 @@
1
+ #
2
+ # An email SMTP configuration object
3
+ #
4
+ require 'config'
5
+ require 'msg'
6
+ require 'smtp'
7
+
8
+ class EmailSmtp < Gloo::Core::Obj
9
+
10
+ KEYWORD = 'email_smtp'.freeze
11
+ SERVER = 'server'.freeze
12
+ PORT = 'port'.freeze
13
+ USERNAME = 'username'.freeze
14
+ PASSWORD = 'password'.freeze
15
+
16
+
17
+ #
18
+ # The name of the object type.
19
+ #
20
+ def self.typename
21
+ return KEYWORD
22
+ end
23
+
24
+ #
25
+ # The short name of the object type.
26
+ # Same as the typename.
27
+ #
28
+ def self.short_typename
29
+ return KEYWORD
30
+ end
31
+
32
+ #
33
+ # Get the email server.
34
+ #
35
+ def server
36
+ return find_child_value SERVER
37
+ end
38
+
39
+ # Get the email port.
40
+ #
41
+ def port
42
+ return find_child_value PORT
43
+ end
44
+
45
+ # Get the email username.
46
+ #
47
+ def username
48
+ return find_child_value USERNAME
49
+ end
50
+
51
+ # Get the email password.
52
+ #
53
+ def password
54
+ return find_child_value PASSWORD
55
+ end
56
+
57
+
58
+ # ---------------------------------------------------------------------
59
+ # Children
60
+ # ---------------------------------------------------------------------
61
+
62
+ # Does this object have children to add when an object
63
+ # is created in interactive mode?
64
+ # This does not apply during obj load, etc.
65
+ def add_children_on_create?
66
+ return true
67
+ end
68
+
69
+ # Add children to this object.
70
+ # This is used by containers to add children needed
71
+ # for default configurations.
72
+ def add_default_children
73
+ fac = @engine.factory
74
+ fac.create_string SERVER, '', self
75
+ fac.create_string PORT, '', self
76
+ fac.create_string USERNAME, '', self
77
+ fac.create_string PASSWORD, '', self
78
+ end
79
+
80
+
81
+ # ---------------------------------------------------------------------
82
+ # Messages
83
+ # ---------------------------------------------------------------------
84
+
85
+ #
86
+ # Get a list of message names that this object receives.
87
+ #
88
+ def self.messages
89
+ return super + [ 'send' ]
90
+ end
91
+
92
+ #
93
+ # Send an email.
94
+ #
95
+ def msg_send
96
+ if @params&.token_count&.positive?
97
+ msg_pn = Gloo::Core::Pn.new( @engine, @params.tokens.first )
98
+ unless msg_pn&.exists?
99
+ @engine.err 'Email Message does not exist'
100
+ return
101
+ end
102
+ else
103
+ @engine.err 'Email Message is required'
104
+ return
105
+ end
106
+ msg = msg_pn.resolve.get_msg
107
+
108
+ smtp = Smtp.new( @engine, get_config )
109
+ smtp.send msg
110
+ end
111
+
112
+ #
113
+ # Get the configuration for this SMTP server.
114
+ #
115
+ def get_config
116
+ config = Config.new( server, port, username, password )
117
+ return config
118
+ end
119
+
120
+ # ---------------------------------------------------------------------
121
+ # Object Documentation
122
+ # ---------------------------------------------------------------------
123
+
124
+ #
125
+ # Get the object's documentation data.
126
+ #
127
+ def self.doc_data
128
+ {
129
+ :name => KEYWORD,
130
+ :shortcut => KEYWORD,
131
+ :description => 'An email SMTP configuration object, used to ' \
132
+ 'send email messages.',
133
+ :children => [
134
+ 'server (string) — The SMTP server host.',
135
+ 'port (string) — The SMTP server port.',
136
+ 'username (string) — The username with which to connect.',
137
+ "password (string) — The user's password."
138
+ ],
139
+ :messages => [
140
+ 'send ({message.path}) — Send the given email message object using this SMTP configuration. A parameter is required: the path to an email message object.'
141
+ ],
142
+ :notes => 'No vault documentation exists for this object type — ' \
143
+ 'this was authored directly from the code.',
144
+ :examples => <<~EXAMPLES.strip
145
+ mail [can] :
146
+ smtp [email_smtp] :
147
+ server : smtp.example.com
148
+ port : 587
149
+ username : me@example.com
150
+ password [alias] : mail.get_passwd.result
151
+
152
+ msg [email] :
153
+ to : someone@example.com
154
+ from : me@example.com
155
+ subject : Hello
156
+ body [text] : BEGIN
157
+ A message sent from gloo.
158
+ END
159
+
160
+ on_load [script] :
161
+ tell mail.smtp to send (mail.msg)
162
+ EXAMPLES
163
+ }
164
+ end
165
+
166
+ end
data/lib/gloo-email.rb ADDED
@@ -0,0 +1,24 @@
1
+ #
2
+ # Shim to allow `require 'gloo-email'`
3
+ #
4
+ # This file is loaded when someone does `require 'gloo-email'`
5
+ #
6
+ require 'email_smtp'
7
+ require 'email_imap'
8
+ require 'email_msg'
9
+
10
+ #
11
+ # Registers the extension.
12
+ #
13
+ class EmailInit < Gloo::Plugin::Base
14
+
15
+ #
16
+ # Register verbs and objects.
17
+ #
18
+ def register( callback )
19
+ callback.register_obj( EmailSmtp )
20
+ callback.register_obj( EmailImap )
21
+ callback.register_obj( EmailMsg )
22
+ end
23
+
24
+ end
data/lib/msg.rb ADDED
@@ -0,0 +1,45 @@
1
+ #
2
+ # A Simple email message object
3
+ #
4
+
5
+ class Msg
6
+
7
+ attr_accessor :to, :from, :subject, :body
8
+
9
+ #
10
+ # Initialize a new email message.
11
+ #
12
+ def initialize( to = nil, from = nil, subject = nil, body = nil )
13
+ @to = to
14
+ @from = from
15
+ @subject = subject
16
+ @body = body
17
+ end
18
+
19
+ #
20
+ # Get the mail message to send.
21
+ #
22
+ # Returns:
23
+ # A mail message.
24
+ #
25
+ def get_mail
26
+ mail = Mail.new
27
+ mail.from = @from
28
+ mail.to = @to
29
+ mail.subject = @subject
30
+ mail.body = @body
31
+ return mail
32
+ end
33
+
34
+ #
35
+ # Convert the message to a string.
36
+ # This is used for debugging and logging.
37
+ #
38
+ # Returns:
39
+ # A string representation of the message.
40
+ #
41
+ def to_s
42
+ return "Msg(to: #{@to}, from: #{@from}, subject: #{@subject}, body: #{@body})"
43
+ end
44
+
45
+ end
data/lib/smtp.rb ADDED
@@ -0,0 +1,55 @@
1
+ #
2
+ # An SMTP email sender
3
+ #
4
+ require 'mail'
5
+ require 'config'
6
+ require 'msg'
7
+
8
+ class Smtp
9
+
10
+ attr_accessor :config
11
+
12
+ #
13
+ # Initialize a new SMTP email sender.
14
+ #
15
+ def initialize( engine, config )
16
+ @engine = engine
17
+ @config = config
18
+ end
19
+
20
+ #
21
+ # Send an email message.
22
+ #
23
+ def send msg
24
+ begin
25
+ configure
26
+ mail = msg.get_mail
27
+ mail.deliver!
28
+ @engine.log.info "Email sent successfully!"
29
+ rescue => ex
30
+ @engine.log_exception ex
31
+ end
32
+ end
33
+
34
+ #
35
+ # Configure the SMTP settings.
36
+ #
37
+ def configure
38
+ svr = @config.host
39
+ prt = @config.port
40
+ usr = @config.username
41
+ pwd = @config.password
42
+
43
+ Mail.defaults do
44
+ delivery_method :smtp, {
45
+ address: svr,
46
+ port: prt,
47
+ user_name: usr,
48
+ password: pwd,
49
+ authentication: :plain,
50
+ enable_starttls_auto: true
51
+ }
52
+ end
53
+ end
54
+
55
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gloo-email
3
+ version: !ruby/object:Gem::Version
4
+ version: '1.0'
5
+ platform: ruby
6
+ authors:
7
+ - Eric Crane
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: mail
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: bundler
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.1'
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 5.14.2
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - "~>"
55
+ - !ruby/object:Gem::Version
56
+ version: '5.1'
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 5.14.2
60
+ - !ruby/object:Gem::Dependency
61
+ name: rake
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '13.0'
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 13.0.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - "~>"
75
+ - !ruby/object:Gem::Version
76
+ version: '13.0'
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: 13.0.1
80
+ description: Adds Gloo Email support to Gloo.
81
+ email:
82
+ - eric.crane@mac.com
83
+ executables: []
84
+ extensions: []
85
+ extra_rdoc_files: []
86
+ files:
87
+ - README.md
88
+ - lib/config.rb
89
+ - lib/email_imap.rb
90
+ - lib/email_msg.rb
91
+ - lib/email_smtp.rb
92
+ - lib/gloo-email.rb
93
+ - lib/msg.rb
94
+ - lib/smtp.rb
95
+ homepage: https://github.com/ecrane/gloo
96
+ licenses:
97
+ - MIT
98
+ metadata:
99
+ gloo.type: core-library
100
+ documentation_uri: https://github.com/ecrane/gloo
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubygems_version: 4.0.17
116
+ specification_version: 4
117
+ summary: Gloo core library. Gloo Email support.
118
+ test_files: []