larch 1.1.0.dev.20100209 → 1.1.0.dev.20100807
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/HISTORY +4 -1
- data/README.rdoc +7 -0
- data/bin/larch +1 -0
- data/lib/larch/config.rb +5 -0
- data/lib/larch/imap/mailbox.rb +5 -3
- data/lib/larch/monkeypatch/net/imap.rb +52 -13
- data/lib/larch/version.rb +1 -1
- data/lib/larch.rb +11 -12
- metadata +62 -22
data/HISTORY
CHANGED
@@ -15,7 +15,8 @@ Version 1.1.0 (git)
|
|
15
15
|
* Added experimental support for Yahoo! Mail IMAP when connecting to
|
16
16
|
imap.mail.yahoo.com or imap-ssl.mail.yahoo.com. See the README for caveats
|
17
17
|
and known issues.
|
18
|
-
* Folders are now copied recursively by default.
|
18
|
+
* Folders are now copied recursively by default. Use the --no-recurse option
|
19
|
+
for the old behavior.
|
19
20
|
* Progress information is now displayed regularly while scanning large
|
20
21
|
mailboxes.
|
21
22
|
* Added --delete option to delete messages from the source after copying them
|
@@ -39,6 +40,8 @@ Version 1.1.0 (git)
|
|
39
40
|
* Fixed an issue when trying to copy a folder with leading or trailing
|
40
41
|
whitespace in the name to Gmail, since Gmail doesn't allow whitespace around
|
41
42
|
folder names.
|
43
|
+
* Fixed an issue with bogus Exchange STATUS responses containing trailing
|
44
|
+
spaces.
|
42
45
|
|
43
46
|
Version 1.0.2 (2009-08-05)
|
44
47
|
* Fixed a bug that caused Larch to try to set the read-only \Recent flag on
|
data/README.rdoc
CHANGED
@@ -324,6 +324,13 @@ http://groups.google.com/group/larch
|
|
324
324
|
First-time senders to the list are moderated to prevent spam, so there may be a
|
325
325
|
delay before your first message shows up.
|
326
326
|
|
327
|
+
== Contributors
|
328
|
+
|
329
|
+
The following lovely people have contributed code to Larch:
|
330
|
+
|
331
|
+
* Ryan Grove <ryan@wonko.com>
|
332
|
+
* Andrew Hobson <ahobson@damballa.com>
|
333
|
+
|
327
334
|
== Credit
|
328
335
|
|
329
336
|
The Larch::IMAP class borrows heavily from Sup[http://sup.rubyforge.org] by
|
data/bin/larch
CHANGED
@@ -36,6 +36,7 @@ EOS
|
|
36
36
|
opt :exclude, "List of mailbox names/patterns that shouldn't be copied", :short => :none, :type => :strings, :multi => true
|
37
37
|
opt :exclude_file, "Filename containing mailbox names/patterns that shouldn't be copied", :short => :none, :type => :string
|
38
38
|
opt :expunge, "Expunge deleted messages from the source", :short => '-x'
|
39
|
+
opt :no_recurse, "Don't copy subfolders recursively (cannot be used with --all or --all_subscribed)", :short => :none
|
39
40
|
opt :sync_flags, "Sync message flags from the source to the destination for messages that already exist at the destination", :short => '-S'
|
40
41
|
|
41
42
|
text "\nGeneral Options:"
|
data/lib/larch/config.rb
CHANGED
@@ -19,6 +19,7 @@ class Config
|
|
19
19
|
'from-user' => nil,
|
20
20
|
'max-retries' => 3,
|
21
21
|
'no-create-folder' => false,
|
22
|
+
'no-recurse' => false,
|
22
23
|
'ssl-certs' => nil,
|
23
24
|
'ssl-verify' => false,
|
24
25
|
'sync-flags' => false,
|
@@ -94,6 +95,10 @@ class Config
|
|
94
95
|
# 'all' wins over 'all-subscribed'
|
95
96
|
@cached['all-subscribed'] = false
|
96
97
|
end
|
98
|
+
|
99
|
+
# 'no-recurse' is not compatible with 'all' and 'all-subscribed'
|
100
|
+
raise Error, "'no-recurse' option cannot be used with 'all' or 'all-subscribed'" if @cached['no-recurse']
|
101
|
+
|
97
102
|
else
|
98
103
|
@cached['from-folder'] ||= 'INBOX'
|
99
104
|
@cached['to-folder'] ||= 'INBOX'
|
data/lib/larch/imap/mailbox.rb
CHANGED
@@ -246,6 +246,8 @@ class Mailbox
|
|
246
246
|
need_flag_scan = flag_range && flag_range.max && flag_range.min && flag_range.max - flag_range.min > 0
|
247
247
|
need_full_scan = full_range && full_range.max && full_range.min && full_range.max - full_range.min > 0
|
248
248
|
|
249
|
+
return unless need_flag_scan || need_full_scan
|
250
|
+
|
249
251
|
fetch_flags(flag_range) if need_flag_scan
|
250
252
|
|
251
253
|
if need_full_scan
|
@@ -592,10 +594,10 @@ class Mailbox
|
|
592
594
|
end
|
593
595
|
|
594
596
|
elsif set.is_a?(Range)
|
595
|
-
pos = set.
|
597
|
+
pos = set.min - 1
|
596
598
|
|
597
|
-
while pos < set.
|
598
|
-
blocks << ((pos + 1)..[set.
|
599
|
+
while pos < set.max
|
600
|
+
blocks << ((pos + 1)..[set.max, pos += block_size].min)
|
599
601
|
end
|
600
602
|
end
|
601
603
|
|
@@ -1,16 +1,54 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
1
|
+
# Monkeypatches for Net::IMAP.
|
2
|
+
|
3
|
+
module Net # :nodoc:
|
4
|
+
class IMAP # :nodoc:
|
5
|
+
class ResponseParser # :nodoc:
|
6
|
+
private
|
7
|
+
|
8
|
+
# Fixes an issue with bogus STATUS responses from Exchange that contain
|
9
|
+
# trailing whitespace. This monkeypatch works cleanly against Ruby 1.8.x
|
10
|
+
# and 1.9.x.
|
11
|
+
def status_response
|
12
|
+
token = match(T_ATOM)
|
13
|
+
name = token.value.upcase
|
14
|
+
match(T_SPACE)
|
15
|
+
mailbox = astring
|
16
|
+
match(T_SPACE)
|
17
|
+
match(T_LPAR)
|
18
|
+
attr = {}
|
19
|
+
while true
|
20
|
+
token = lookahead
|
21
|
+
case token.symbol
|
22
|
+
when T_RPAR
|
23
|
+
shift_token
|
24
|
+
break
|
25
|
+
when T_SPACE
|
26
|
+
shift_token
|
27
|
+
end
|
28
|
+
token = match(T_ATOM)
|
29
|
+
key = token.value.upcase
|
30
|
+
match(T_SPACE)
|
31
|
+
val = number
|
32
|
+
attr[key] = val
|
33
|
+
end
|
34
|
+
|
35
|
+
# Monkeypatch starts here...
|
36
|
+
token = lookahead
|
37
|
+
shift_token if token.symbol == T_SPACE
|
38
|
+
# ...and ends here.
|
39
|
+
|
40
|
+
data = StatusData.new(mailbox, attr)
|
41
|
+
return UntaggedResponse.new(name, data, @str)
|
42
|
+
end
|
43
|
+
|
44
|
+
if RUBY_VERSION <= '1.9.1'
|
45
|
+
|
46
|
+
# Monkeypatches Net::IMAP in Ruby <= 1.9.1 to fix broken response
|
47
|
+
# handling, particularly when changing mailboxes on a Dovecot 1.2+
|
48
|
+
# server.
|
49
|
+
#
|
50
|
+
# This monkeypatch shouldn't be necessary in Ruby 1.9.2 and higher.
|
51
|
+
# It's included in Ruby 1.9 SVN trunk as of 2010-02-08.
|
14
52
|
def resp_text_code
|
15
53
|
@lex_state = EXPR_BEG
|
16
54
|
match(T_LBRA)
|
@@ -44,5 +82,6 @@ if RUBY_VERSION <= '1.9.1'
|
|
44
82
|
end
|
45
83
|
|
46
84
|
end
|
85
|
+
|
47
86
|
end
|
48
87
|
end
|
data/lib/larch/version.rb
CHANGED
data/lib/larch.rb
CHANGED
@@ -131,14 +131,11 @@ module Larch
|
|
131
131
|
# Ensure that the database schema is up to date.
|
132
132
|
migration_dir = File.join(LIB_DIR, 'db', 'migrate')
|
133
133
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
@log.fatal "unable to migrate message database: #{e}"
|
140
|
-
abort
|
141
|
-
end
|
134
|
+
begin
|
135
|
+
Sequel::Migrator.apply(db, migration_dir)
|
136
|
+
rescue => e
|
137
|
+
@log.fatal "unable to migrate message database: #{e}"
|
138
|
+
abort
|
142
139
|
end
|
143
140
|
|
144
141
|
require 'larch/db/message'
|
@@ -165,10 +162,12 @@ module Larch
|
|
165
162
|
mailbox_to.subscribe if mailbox_from.subscribed?
|
166
163
|
copy_messages(mailbox_from, mailbox_to)
|
167
164
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
165
|
+
unless @config['no-recurse']
|
166
|
+
mailbox_from.each_mailbox do |child_from|
|
167
|
+
next if excluded?(child_from.name)
|
168
|
+
child_to = mailbox_to.imap.mailbox(child_from.name, child_from.delim)
|
169
|
+
copy_mailbox(child_from, child_to)
|
170
|
+
end
|
172
171
|
end
|
173
172
|
end
|
174
173
|
|
metadata
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: larch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
4
|
+
hash: 1678109927
|
5
|
+
prerelease: true
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
- dev
|
11
|
+
- 20100807
|
12
|
+
version: 1.1.0.dev.20100807
|
5
13
|
platform: ruby
|
6
14
|
authors:
|
7
15
|
- Ryan Grove
|
@@ -9,49 +17,71 @@ autorequire:
|
|
9
17
|
bindir: bin
|
10
18
|
cert_chain: []
|
11
19
|
|
12
|
-
date: 2010-
|
20
|
+
date: 2010-08-07 00:00:00 -07:00
|
13
21
|
default_executable:
|
14
22
|
dependencies:
|
15
23
|
- !ruby/object:Gem::Dependency
|
16
24
|
name: highline
|
17
|
-
|
18
|
-
|
19
|
-
|
25
|
+
prerelease: false
|
26
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
20
28
|
requirements:
|
21
29
|
- - ~>
|
22
30
|
- !ruby/object:Gem::Version
|
31
|
+
hash: 3
|
32
|
+
segments:
|
33
|
+
- 1
|
34
|
+
- 5
|
35
|
+
- 0
|
23
36
|
version: 1.5.0
|
24
|
-
|
37
|
+
type: :runtime
|
38
|
+
version_requirements: *id001
|
25
39
|
- !ruby/object:Gem::Dependency
|
26
40
|
name: sequel
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
prerelease: false
|
42
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
30
44
|
requirements:
|
31
45
|
- - ~>
|
32
46
|
- !ruby/object:Gem::Version
|
33
|
-
|
34
|
-
|
47
|
+
hash: 27
|
48
|
+
segments:
|
49
|
+
- 3
|
50
|
+
- 14
|
51
|
+
version: "3.14"
|
52
|
+
type: :runtime
|
53
|
+
version_requirements: *id002
|
35
54
|
- !ruby/object:Gem::Dependency
|
36
55
|
name: sqlite3-ruby
|
37
|
-
|
38
|
-
|
39
|
-
|
56
|
+
prerelease: false
|
57
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
40
59
|
requirements:
|
41
60
|
- - ~>
|
42
61
|
- !ruby/object:Gem::Version
|
62
|
+
hash: 21
|
63
|
+
segments:
|
64
|
+
- 1
|
65
|
+
- 2
|
66
|
+
- 5
|
43
67
|
version: 1.2.5
|
44
|
-
|
68
|
+
type: :runtime
|
69
|
+
version_requirements: *id003
|
45
70
|
- !ruby/object:Gem::Dependency
|
46
71
|
name: trollop
|
47
|
-
|
48
|
-
|
49
|
-
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
50
75
|
requirements:
|
51
76
|
- - ~>
|
52
77
|
- !ruby/object:Gem::Version
|
78
|
+
hash: 21
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 13
|
53
82
|
version: "1.13"
|
54
|
-
|
83
|
+
type: :runtime
|
84
|
+
version_requirements: *id004
|
55
85
|
description:
|
56
86
|
email: ryan@wonko.com
|
57
87
|
executables:
|
@@ -88,21 +118,31 @@ rdoc_options: []
|
|
88
118
|
require_paths:
|
89
119
|
- lib
|
90
120
|
required_ruby_version: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
91
122
|
requirements:
|
92
123
|
- - ">="
|
93
124
|
- !ruby/object:Gem::Version
|
125
|
+
hash: 59
|
126
|
+
segments:
|
127
|
+
- 1
|
128
|
+
- 8
|
129
|
+
- 6
|
94
130
|
version: 1.8.6
|
95
|
-
version:
|
96
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
+
none: false
|
97
133
|
requirements:
|
98
134
|
- - ">"
|
99
135
|
- !ruby/object:Gem::Version
|
136
|
+
hash: 25
|
137
|
+
segments:
|
138
|
+
- 1
|
139
|
+
- 3
|
140
|
+
- 1
|
100
141
|
version: 1.3.1
|
101
|
-
version:
|
102
142
|
requirements: []
|
103
143
|
|
104
144
|
rubyforge_project:
|
105
|
-
rubygems_version: 1.3.
|
145
|
+
rubygems_version: 1.3.7
|
106
146
|
signing_key:
|
107
147
|
specification_version: 3
|
108
148
|
summary: Larch copies messages from one IMAP server to another. Awesomely.
|