larch 1.1.0.dev.20100209 → 1.1.0.dev.20100807
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|