inbox-sync 0.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.
- data/.gitignore +21 -0
- data/Gemfile +7 -0
- data/LICENSE +22 -0
- data/README.md +185 -0
- data/Rakefile +8 -0
- data/inbox-sync.gemspec +23 -0
- data/lib/inbox-sync/config/credentials.rb +29 -0
- data/lib/inbox-sync/config/imap_config.rb +28 -0
- data/lib/inbox-sync/config/smtp_config.rb +30 -0
- data/lib/inbox-sync/config.rb +30 -0
- data/lib/inbox-sync/mail_item.rb +78 -0
- data/lib/inbox-sync/notice/base.rb +47 -0
- data/lib/inbox-sync/notice/run_sync_error.rb +44 -0
- data/lib/inbox-sync/notice/sync_mail_item_error.rb +45 -0
- data/lib/inbox-sync/runner.rb +123 -0
- data/lib/inbox-sync/sync.rb +249 -0
- data/lib/inbox-sync/version.rb +3 -0
- data/lib/inbox-sync.rb +16 -0
- data/log/.gitkeep +0 -0
- data/test/config_test.rb +302 -0
- data/test/helper.rb +87 -0
- data/test/irb.rb +9 -0
- data/test/mail_item_test.rb +62 -0
- data/test/runner_test.rb +40 -0
- data/test/sync/basic_test.rb +62 -0
- data/test/sync/login_test.rb +110 -0
- metadata +141 -0
data/.gitignore
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
*.gem
|
2
|
+
*.log
|
3
|
+
*.rbc
|
4
|
+
.bundle
|
5
|
+
.config
|
6
|
+
.yardoc
|
7
|
+
.rvmrc
|
8
|
+
.rbenv-version
|
9
|
+
Gemfile.lock
|
10
|
+
InstalledFiles
|
11
|
+
_yardoc
|
12
|
+
coverage
|
13
|
+
doc/
|
14
|
+
lib/bundler/man
|
15
|
+
pkg
|
16
|
+
rdoc
|
17
|
+
spec/reports
|
18
|
+
test/tmp
|
19
|
+
test/version_tmp
|
20
|
+
tmp
|
21
|
+
test.rb
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Kelly Redding
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,185 @@
|
|
1
|
+
# InboxSync
|
2
|
+
|
3
|
+
Move messages from one inbox to another. Useful when server-side email forwarding is not an option. (TODO) Can apply filters to messages as they are being moved. Run on-demand, on a schedule, or as a daemon.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'inbox-sync'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install inbox-sync
|
18
|
+
|
19
|
+
# How does it work?
|
20
|
+
|
21
|
+
InboxSync uses IMAP to query a source inbox, process its messages, append them to a destination inbox, and archive them on the source. It logs each step in the process and will send notification emails when something goes wrong.
|
22
|
+
|
23
|
+
(TODO) InboxSync provides a framework for defining destination filters for post-sync mail processing (ie moving/archiving, copying/labeling, deletion, etc).
|
24
|
+
|
25
|
+
InboxSync provides a basic ruby runner class to handle polling the source on an interval and running the configured sync(s). You can call it in any number of ways: in a script, from a cron, as a daemon, or as part of a larger system.
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
It should be fairly straight-forward: create and configure a sync then run it. This will move all messages in the `source` inbox to the `dest` inbox.
|
30
|
+
|
31
|
+
### Create your Sync
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
sync = InboxSync.new
|
35
|
+
```
|
36
|
+
|
37
|
+
### Configure it
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
# manually set configs
|
41
|
+
sync.config.source.host = 'imap.source-host.com'
|
42
|
+
|
43
|
+
# or use a more DSL like approach
|
44
|
+
sync.config.source.login.user 'me'
|
45
|
+
sync.config.source.login.pw 'secret'
|
46
|
+
|
47
|
+
# or use a configure block, if you like
|
48
|
+
sync.configure do
|
49
|
+
dest.host 'imap.dest-host.com'
|
50
|
+
dest.login 'me', 'secret'
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
### Run it
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
InboxSync.run(sync, :interval => 5)
|
58
|
+
```
|
59
|
+
|
60
|
+
## Sync Definition
|
61
|
+
|
62
|
+
### `source`
|
63
|
+
|
64
|
+
IMAP settings for the source inbox.
|
65
|
+
|
66
|
+
* *host*: eg. `'imap.some-domain.com'`.
|
67
|
+
* *port*: defaults to `143`.
|
68
|
+
* *ssl*: whether to use SSL. defaults to `false`.
|
69
|
+
* *login*: credentials (user, pw).
|
70
|
+
* *inbox*: name of the inbox folder. defaults to `'INBOX'`
|
71
|
+
* *expunge*: whether to expunge the inbox before and after processing. defaults to `true`.
|
72
|
+
|
73
|
+
### `dest`
|
74
|
+
|
75
|
+
IMAP settings for the destination inbox. Has the some attributes and defaults as the `source`.
|
76
|
+
|
77
|
+
### `notify`
|
78
|
+
|
79
|
+
SMTP settings to send notifications with.
|
80
|
+
|
81
|
+
* *host*: eg. `'smtp.some-domain.com'`.
|
82
|
+
* *port*: defaults to `25`.
|
83
|
+
* *tls*: whethe to use TLS encryption. defaults to `false`.
|
84
|
+
* *helo*: the helo domain to send with.
|
85
|
+
* *login*: credentials (user, pw).
|
86
|
+
* *authtype*: defaults to `:login`.
|
87
|
+
* *from_addr*: address to send the notifications from.
|
88
|
+
* *to_addr*: address(es) to send the notifications to.
|
89
|
+
|
90
|
+
### `archive_folder`
|
91
|
+
|
92
|
+
The (optional) folder on the source to create and archive (move) source inbox messages to when processing is complete. Defaults to `"Archived"`. Set to `nil` to disable archiving on the source and delete the messages after processing.
|
93
|
+
|
94
|
+
### `logger`
|
95
|
+
|
96
|
+
A logger to use. Defaults to ruby's `Logger` on `STDOUT`.
|
97
|
+
|
98
|
+
## Running
|
99
|
+
|
100
|
+
InboxSync provides a `Runner` class that will loop indefinitely, running syncs every `:interval` seconds. Stick it in a daemon, a rake task, a CLI, or whatever depending on how you want to invoke it. Here is an example using it in a basic ruby script:
|
101
|
+
|
102
|
+
```ruby
|
103
|
+
require 'inbox-sync'
|
104
|
+
|
105
|
+
sync = InboxSync.new.configure do
|
106
|
+
source.host 'imap.gmail.com'
|
107
|
+
source.port 993
|
108
|
+
source.ssl 'Yes'
|
109
|
+
source.login 'joetest@kellyredding.com', 'joetest1'
|
110
|
+
|
111
|
+
dest.host 'imap.gmail.com'
|
112
|
+
dest.port 993
|
113
|
+
dest.ssl 'Yes'
|
114
|
+
dest.login 'suetest@kellyredding.com', 'suetest1'
|
115
|
+
|
116
|
+
notify.host 'smtp.gmail.com'
|
117
|
+
notify.port 587
|
118
|
+
notify.tls 'Yes'
|
119
|
+
notify.helo 'gmail.com'
|
120
|
+
notify.login 'joetest@kellyredding.com', 'joetest1'
|
121
|
+
notify.to_addr 'joetest@kellyredding.com'
|
122
|
+
notify.to_addr 'suetest@kellyredding.com'
|
123
|
+
|
124
|
+
logger Logger.new('log/inbox-sync.log')
|
125
|
+
end
|
126
|
+
|
127
|
+
InboxSync.run(sync, :interval => 20)
|
128
|
+
```
|
129
|
+
|
130
|
+
The `InboxSync.run` method is just a macro for creating a runner and calling its `start` method.
|
131
|
+
|
132
|
+
```ruby
|
133
|
+
InboxSync::Runner.new(sync, :interval => 5).start
|
134
|
+
```
|
135
|
+
|
136
|
+
By default, it will log to `STDOUT` but accepts a `:logger` option to override this.
|
137
|
+
|
138
|
+
```ruby
|
139
|
+
InboxSync.run(sync, {
|
140
|
+
:interval => 5,
|
141
|
+
:logger => Logger.new('/path/to/log.log')
|
142
|
+
})
|
143
|
+
```
|
144
|
+
|
145
|
+
You can pass any number of syncs to run. Each `:interval` period, it will run them sequentially:
|
146
|
+
|
147
|
+
```ruby
|
148
|
+
InboxSync.run(sync1, sync2, sync3, :interval => 5)
|
149
|
+
```
|
150
|
+
|
151
|
+
If you pass no `:interval` option (or pass a negative value for it), the runner will run the sync(s) once and then exit instead of running the syncs indefinitely on the interval.
|
152
|
+
|
153
|
+
```ruby
|
154
|
+
InboxSync.run(sync)
|
155
|
+
```
|
156
|
+
|
157
|
+
The runner traps `SIGINT` and `SIGQUIT` and will shutdown nicely once any in-progress syncs have finished.
|
158
|
+
|
159
|
+
## Filter Framework
|
160
|
+
|
161
|
+
TODO
|
162
|
+
|
163
|
+
## Error Handling
|
164
|
+
|
165
|
+
InboxSync generates detailed logs of both running its syncs and processing sync mail items. If a mail fails to append (ie rejected by the dest IMAP), InboxSync will attempt to strip the mail to its most basic (ie plain/text) form and will retry the append.
|
166
|
+
|
167
|
+
In addtion, InboxSync will notify via email when something goes wrong with a sync. You configure `notify` settings when defining your syncs. These settings determine where/how notifications are sent out. There are two types a notifications InboxSync will send: `RunSyncError` and `SyncMailItemError`.
|
168
|
+
|
169
|
+
In any case, if an `archive_folder` is set, no source messages will be permanently deleted and are always available there for reference.
|
170
|
+
|
171
|
+
### `RunSyncError` notification
|
172
|
+
|
173
|
+
This notification is sent when there is a problem running a sync in general. For example, the sync can't connect to the source to read its mail items or the runner itself has a runtime exception. This notification lets you know that something went wrong and that mail items aren't being sync'd. It also details the exception that happened with a full backtrace.
|
174
|
+
|
175
|
+
### `SyncMailItemError` notification
|
176
|
+
|
177
|
+
This notification is sent wnen there is a problem syncing a specific mail item. For example the destination rejects the append or there was a problem archiving the mail item at the source. It lets you know there was a problem and gives you some info about the email that had a problem. It also details the exception that happened with a full backtrace.
|
178
|
+
|
179
|
+
## Contributing
|
180
|
+
|
181
|
+
1. Fork it
|
182
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
183
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
184
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
185
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/inbox-sync.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/inbox-sync/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.name = "inbox-sync"
|
6
|
+
gem.version = InboxSync::VERSION
|
7
|
+
gem.description = %q{Move messages from one inbox to another}
|
8
|
+
gem.summary = %q{Move messages from one inbox to another}
|
9
|
+
|
10
|
+
gem.authors = ["Kelly Redding"]
|
11
|
+
gem.email = ["kelly@kellyredding.com"]
|
12
|
+
gem.homepage = "http://github.com/kellyredding/inbox-sync"
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split("\n")
|
15
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
|
19
|
+
gem.add_development_dependency("assert")
|
20
|
+
|
21
|
+
gem.add_dependency("ns-options", ["~> 0.4.1"])
|
22
|
+
gem.add_dependency("mail", ["~> 2.4"])
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'ns-options'
|
2
|
+
|
3
|
+
module InboxSync; end
|
4
|
+
class InboxSync::Config
|
5
|
+
|
6
|
+
class Credentials
|
7
|
+
include NsOptions::Proxy
|
8
|
+
|
9
|
+
opt :user, :required => true
|
10
|
+
opt :pw, :required => true
|
11
|
+
|
12
|
+
def initialize(*args)
|
13
|
+
the_args = args.flatten
|
14
|
+
if the_args.size == 1
|
15
|
+
self.apply(args.last)
|
16
|
+
else
|
17
|
+
self.user, self.pw = the_args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate!
|
22
|
+
if !required_set?
|
23
|
+
raise ArgumentError, "some required configs are missing"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'ns-options'
|
2
|
+
require 'ns-options/boolean'
|
3
|
+
require 'inbox-sync/config/credentials'
|
4
|
+
|
5
|
+
module InboxSync; end
|
6
|
+
class InboxSync::Config
|
7
|
+
|
8
|
+
class IMAPConfig
|
9
|
+
include NsOptions::Proxy
|
10
|
+
|
11
|
+
opt :host, :required => true
|
12
|
+
opt :port, :default => 143, :required => true
|
13
|
+
opt :ssl, NsOptions::Boolean, :default => false, :required => true
|
14
|
+
opt :login, Credentials, :required => true, :default => {}
|
15
|
+
opt :inbox, :default => "INBOX", :required => true
|
16
|
+
opt :expunge, NsOptions::Boolean, :default => true, :required => true
|
17
|
+
|
18
|
+
def validate!
|
19
|
+
if !required_set?
|
20
|
+
raise ArgumentError, "some required configs are missing"
|
21
|
+
end
|
22
|
+
|
23
|
+
login.validate!
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'ns-options'
|
2
|
+
require 'ns-options/boolean'
|
3
|
+
require 'inbox-sync/config/credentials'
|
4
|
+
|
5
|
+
module InboxSync; end
|
6
|
+
class InboxSync::Config
|
7
|
+
|
8
|
+
class SMTPConfig
|
9
|
+
include NsOptions::Proxy
|
10
|
+
|
11
|
+
opt :host, :required => true
|
12
|
+
opt :port, :default => 25, :required => true
|
13
|
+
opt :tls, NsOptions::Boolean, :default => false, :required => true
|
14
|
+
opt :helo, :required => true
|
15
|
+
opt :login, Credentials, :required => true, :default => {}
|
16
|
+
opt :authtype, :default => :login, :required => true
|
17
|
+
opt :from_addr, :required => true
|
18
|
+
opt :to_addr, :required => true
|
19
|
+
|
20
|
+
def validate!
|
21
|
+
if !required_set?
|
22
|
+
raise ArgumentError, "some required configs are missing"
|
23
|
+
end
|
24
|
+
|
25
|
+
login.validate!
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'logger'
|
2
|
+
require 'ns-options'
|
3
|
+
require 'inbox-sync/config/imap_config'
|
4
|
+
require 'inbox-sync/config/smtp_config'
|
5
|
+
|
6
|
+
module InboxSync
|
7
|
+
|
8
|
+
class Config
|
9
|
+
include NsOptions::Proxy
|
10
|
+
|
11
|
+
opt :source, IMAPConfig, :required => true, :default => {}
|
12
|
+
opt :dest, IMAPConfig, :required => true, :default => {}
|
13
|
+
opt :notify, SMTPConfig, :required => true, :default => {}
|
14
|
+
|
15
|
+
opt :archive_folder, :default => 'Archived'
|
16
|
+
opt :logger, Logger, :required => true, :default => STDOUT
|
17
|
+
|
18
|
+
def validate!
|
19
|
+
if !required_set?
|
20
|
+
raise ArgumentError, "some required configs are missing"
|
21
|
+
end
|
22
|
+
|
23
|
+
source.validate!
|
24
|
+
dest.validate!
|
25
|
+
notify.validate!
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
module InboxSync
|
4
|
+
|
5
|
+
class MailItem
|
6
|
+
|
7
|
+
def self.find(imap)
|
8
|
+
imap.uid_search(['ALL']).
|
9
|
+
map do |uid|
|
10
|
+
[uid, imap.uid_fetch(uid, ['RFC822', 'INTERNALDATE']).first]
|
11
|
+
end.
|
12
|
+
map do |uid_meta|
|
13
|
+
self.new(
|
14
|
+
uid_meta.first,
|
15
|
+
uid_meta.last.attr['RFC822'],
|
16
|
+
uid_meta.last.attr["INTERNALDATE"]
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
attr_reader :uid, :meta, :message
|
22
|
+
|
23
|
+
def initialize(uid, rfc822, internal_date)
|
24
|
+
@uid = uid
|
25
|
+
@meta = {
|
26
|
+
'RFC822' => rfc822,
|
27
|
+
'INTERNALDATE' => internal_date
|
28
|
+
}
|
29
|
+
@message = ::Mail.new(rfc822)
|
30
|
+
end
|
31
|
+
|
32
|
+
def name
|
33
|
+
"[#{@uid}] #{@message.from}: #{@message.subject.inspect} (#{time_s(@message.date)})"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns a stripped down version of the mail item
|
37
|
+
# The stripped down versions is just the 'text/plain' part of multipart
|
38
|
+
# mail items. If the original mail item was not multipart, then the
|
39
|
+
# stripped down version is the same as the original.
|
40
|
+
# This implies that stripped down mail items have no attachments.
|
41
|
+
|
42
|
+
def stripped
|
43
|
+
@stripped ||= strip_down(MailItem.new(
|
44
|
+
self.uid,
|
45
|
+
self.meta['RFC822'],
|
46
|
+
self.meta["INTERNALDATE"]
|
47
|
+
))
|
48
|
+
end
|
49
|
+
|
50
|
+
def inspect
|
51
|
+
"#<#{self.class}:#{'0x%x' % (self.object_id << 1)}: @uid=#{@uid.inspect}, from=#{@message.from.inspect}, subject=#{@message.subject.inspect}, 'INTERNALDATE'=#{@meta['INTERNALDATE'].inspect}>"
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def time_s(datetime)
|
57
|
+
datetime.strftime("%a %b %-d %Y, %I:%M %p")
|
58
|
+
end
|
59
|
+
|
60
|
+
def strip_down(mail_item)
|
61
|
+
message = mail_item.message
|
62
|
+
if message.multipart?
|
63
|
+
message.parts.delete_if do |part|
|
64
|
+
!part.content_type.match(/text\/plain/)
|
65
|
+
end
|
66
|
+
message.parts.first.body = strip_down_body_s(message.parts.first.body)
|
67
|
+
mail_item.meta['RFC822'] = message.to_s
|
68
|
+
end
|
69
|
+
mail_item
|
70
|
+
end
|
71
|
+
|
72
|
+
def strip_down_body_s(body_s)
|
73
|
+
"**[inbox-sync] stripped down to just plain text part**\n\n#{body_s}"
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'mail'
|
2
|
+
|
3
|
+
module InboxSync; end
|
4
|
+
module InboxSync::Notice
|
5
|
+
|
6
|
+
class Base
|
7
|
+
|
8
|
+
attr_reader :mail
|
9
|
+
|
10
|
+
def initialize(smtp, config)
|
11
|
+
@smtp = smtp
|
12
|
+
@config = config
|
13
|
+
|
14
|
+
@mail = ::Mail.new
|
15
|
+
@mail.from = self.from
|
16
|
+
@mail.to = self.to
|
17
|
+
@mail.subject = self.subject
|
18
|
+
@mail.body = self.body
|
19
|
+
end
|
20
|
+
|
21
|
+
def from; @config.from_addr; end
|
22
|
+
def to; @config.to_addr; end
|
23
|
+
|
24
|
+
def subject(msg="notice")
|
25
|
+
"[inbox-sync] #{msg}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def body
|
29
|
+
raise RuntimeError, "subclass `Notice::Base` and define your body"
|
30
|
+
end
|
31
|
+
|
32
|
+
def send
|
33
|
+
@smtp.start(helo, user, pw, authtype) do |smtp|
|
34
|
+
smtp.send_message(@mail.to_s, from, to)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
def helo; @config.helo; end
|
41
|
+
def user; @config.login.user; end
|
42
|
+
def pw; @config.login.pw; end
|
43
|
+
def authtype; @config.authtype; end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'inbox-sync/notice/base'
|
2
|
+
|
3
|
+
module InboxSync; end
|
4
|
+
module InboxSync::Notice
|
5
|
+
|
6
|
+
class RunSyncError < Base
|
7
|
+
|
8
|
+
BODY = %{
|
9
|
+
:sync_name
|
10
|
+
|
11
|
+
An error happened while running this sync. The error has
|
12
|
+
been logged but no mail items from this sync's source are
|
13
|
+
being sync'd. The runner will continue to attempt this
|
14
|
+
sync so mails like this will continue until the problem
|
15
|
+
is fixed.
|
16
|
+
|
17
|
+
Error
|
18
|
+
=====
|
19
|
+
:error_message (:error_name)
|
20
|
+
:error_backtrace
|
21
|
+
}.strip.freeze
|
22
|
+
|
23
|
+
def initialize(smtp, config, data={})
|
24
|
+
@error = data[:error]
|
25
|
+
@sync = data[:sync]
|
26
|
+
|
27
|
+
super(smtp, config)
|
28
|
+
end
|
29
|
+
|
30
|
+
def subject
|
31
|
+
super("sync run error (#{@sync.uid})")
|
32
|
+
end
|
33
|
+
|
34
|
+
def body
|
35
|
+
@body ||= BODY.
|
36
|
+
gsub(':sync_name', @sync.name).
|
37
|
+
gsub(':error_message', @error.message).
|
38
|
+
gsub(':error_name', @error.class.name).
|
39
|
+
gsub(':error_backtrace', @error.backtrace.join("\n "))
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'inbox-sync/notice/base'
|
2
|
+
|
3
|
+
module InboxSync; end
|
4
|
+
module InboxSync::Notice
|
5
|
+
|
6
|
+
class SyncMailItemError < Base
|
7
|
+
|
8
|
+
BODY = %{
|
9
|
+
:sync_name
|
10
|
+
:mail_item_name
|
11
|
+
|
12
|
+
An error happened while syncing this mail item. The error
|
13
|
+
has been logged and the mail item has been archived on the
|
14
|
+
source. The sync will continue processing new mail items.
|
15
|
+
|
16
|
+
Error
|
17
|
+
=====
|
18
|
+
:error_message (:error_name)
|
19
|
+
:error_backtrace
|
20
|
+
}.strip.freeze
|
21
|
+
|
22
|
+
def initialize(smtp, config, data={})
|
23
|
+
@error = data[:error]
|
24
|
+
@mail_item = data[:mail_item]
|
25
|
+
@sync = data[:sync]
|
26
|
+
|
27
|
+
super(smtp, config)
|
28
|
+
end
|
29
|
+
|
30
|
+
def subject
|
31
|
+
super("mail item sync error (#{@mail_item.uid}, #{@sync.uid})")
|
32
|
+
end
|
33
|
+
|
34
|
+
def body
|
35
|
+
@body ||= BODY.
|
36
|
+
gsub(':sync_name', @sync.name).
|
37
|
+
gsub(':mail_item_name', @mail_item.name).
|
38
|
+
gsub(':error_message', @error.message).
|
39
|
+
gsub(':error_name', @error.class.name).
|
40
|
+
gsub(':error_backtrace', @error.backtrace.join("\n "))
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|