rgrove-larch 1.0.2.1 → 1.0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/HISTORY CHANGED
@@ -6,6 +6,7 @@ Version 1.1.0 (git)
6
6
  database, which allows Larch to resync and resume interrupted syncs much
7
7
  more quickly without having to rescan all messages. As a result, SQLite 3 is
8
8
  now a dependency.
9
+ * Folders are now copied recursively by default.
9
10
  * Progress information is now displayed regularly while scanning large
10
11
  mailboxes.
11
12
 
@@ -5,7 +5,7 @@ class Mailbox < Sequel::Model
5
5
  one_to_many :messages, :class => Larch::Database::Message
6
6
 
7
7
  before_destroy do
8
- Message.filter(:mailbox_id => id).destroy
8
+ Larch::Database::Message.filter(:mailbox_id => id).destroy
9
9
  end
10
10
  end
11
11
 
@@ -88,11 +88,17 @@ class Mailbox
88
88
 
89
89
  # Iterates through messages in this mailbox, yielding the Larch message guid
90
90
  # of each to the provided block.
91
- def each_guid
91
+ def each_guid # :yields: guid
92
92
  scan
93
93
  @db_mailbox.messages.each {|db_message| yield db_message.guid }
94
94
  end
95
95
 
96
+ # Iterates through mailboxes that are first-level children of this mailbox,
97
+ # yielding a Larch::IMAP::Mailbox object for each to the provided block.
98
+ def each_mailbox # :yields: mailbox
99
+ mailboxes.each {|mb| yield mb }
100
+ end
101
+
96
102
  # Returns a Larch::IMAP::Message struct representing the message with the
97
103
  # specified Larch _guid_, or +nil+ if the specified guid was not found in this
98
104
  # mailbox.
@@ -133,6 +139,18 @@ class Mailbox
133
139
  end
134
140
  alias size length
135
141
 
142
+ # Returns an Array of Larch::IMAP::Mailbox objects representing mailboxes that
143
+ # are first-level children of this mailbox.
144
+ def mailboxes
145
+ return [] if @attr.include?(:Noinferiors)
146
+
147
+ all = @imap.safely{ @imap.conn.list('', "#{@name_utf7}#{@delim}%") } || []
148
+ subscribed = @imap.safely{ @imap.conn.lsub('', "#{@name_utf7}#{@delim}%") } || []
149
+
150
+ all.map{|mb| Mailbox.new(@imap, mb.name, mb.delim,
151
+ subscribed.any?{|s| s.name == mb.name}, mb.attr) }
152
+ end
153
+
136
154
  # Same as fetch, but doesn't mark the message as seen.
137
155
  def peek(message_id)
138
156
  fetch(message_id, true)
@@ -220,6 +238,9 @@ class Mailbox
220
238
  end
221
239
  end
222
240
  end
241
+
242
+ expected_uids = nil
243
+ fetch_data = nil
223
244
  end
224
245
 
225
246
  if full_range && full_range.last - full_range.first > 0
@@ -242,16 +263,16 @@ class Mailbox
242
263
  fetch_data.each do |data|
243
264
  uid = data.attr['UID']
244
265
 
245
- message_data = {
266
+ Database::Message.create(
267
+ :mailbox_id => @db_mailbox.id,
246
268
  :guid => create_guid(data),
247
269
  :uid => uid,
248
270
  :message_id => parse_message_id(data.attr['BODY[HEADER.FIELDS (MESSAGE-ID)]']),
249
271
  :rfc822_size => data.attr['RFC822.SIZE'].to_i,
250
272
  :internaldate => Time.parse(data.attr['INTERNALDATE']).to_i,
251
273
  :flags => data.attr['FLAGS'].map{|f| f.to_s }.join(',')
252
- }
274
+ )
253
275
 
254
- @db_mailbox.add_message(Database::Message.create(message_data))
255
276
  last_good_uid = uid
256
277
  end
257
278
 
data/lib/larch/imap.rb CHANGED
@@ -6,7 +6,7 @@ module Larch
6
6
  # required reading if you're doing anything with IMAP in Ruby:
7
7
  # http://sup.rubyforge.org
8
8
  class IMAP
9
- attr_reader :conn, :db_account, :options
9
+ attr_reader :conn, :db_account, :mailboxes, :options
10
10
 
11
11
  # URI format validation regex.
12
12
  REGEX_URI = URI.regexp(['imap', 'imaps'])
data/lib/larch/version.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  module Larch
2
2
  APP_NAME = 'Larch'
3
- APP_VERSION = '1.0.2.1'
3
+ APP_VERSION = '1.0.2.2'
4
4
  APP_AUTHOR = 'Ryan Grove'
5
5
  APP_EMAIL = 'ryan@wonko.com'
6
6
  APP_URL = 'http://github.com/rgrove/larch/'
data/lib/larch.rb CHANGED
@@ -70,7 +70,7 @@ module Larch
70
70
  mailbox_to = imap_to.mailbox(mailbox_from.name, mailbox_from.delim)
71
71
  mailbox_to.subscribe if mailbox_from.subscribed?
72
72
 
73
- copy_messages(imap_from, mailbox_from.name, imap_to, mailbox_to.name)
73
+ copy_messages(mailbox_from, mailbox_to)
74
74
  end
75
75
 
76
76
  rescue => e
@@ -80,8 +80,8 @@ module Larch
80
80
  summary
81
81
  end
82
82
 
83
- # Copies the messages in a single IMAP folder (non-recursively) from the
84
- # source to the destination.
83
+ # Copies the messages in a single IMAP folder and all its subfolders
84
+ # (recursively) from the source to the destination.
85
85
  def copy_folder(imap_from, imap_to)
86
86
  raise ArgumentError, "imap_from must be a Larch::IMAP instance" unless imap_from.is_a?(IMAP)
87
87
  raise ArgumentError, "imap_to must be a Larch::IMAP instance" unless imap_to.is_a?(IMAP)
@@ -90,12 +90,10 @@ module Larch
90
90
  @failed = 0
91
91
  @total = 0
92
92
 
93
- from_mb_name = imap_from.uri_mailbox || 'INBOX'
94
- to_mb_name = imap_to.uri_mailbox || 'INBOX'
93
+ mailbox_from = imap_from.mailbox(imap_from.uri_mailbox || 'INBOX')
94
+ mailbox_to = imap_to.mailbox(imap_to.uri_mailbox || 'INBOX')
95
95
 
96
- return if excluded?(from_mb_name) || excluded?(to_mb_name)
97
-
98
- copy_messages(imap_from, from_mb_name, imap_to, to_mb_name)
96
+ copy_mailbox(mailbox_from, mailbox_to)
99
97
 
100
98
  imap_from.disconnect
101
99
  imap_to.disconnect
@@ -152,19 +150,34 @@ module Larch
152
150
 
153
151
  private
154
152
 
155
- def copy_messages(imap_from, mb_name_from, imap_to, mb_name_to)
156
- raise ArgumentError, "imap_from must be a Larch::IMAP instance" unless imap_from.is_a?(IMAP)
157
- raise ArgumentError, "imap_to must be a Larch::IMAP instance" unless imap_to.is_a?(IMAP)
153
+ def copy_mailbox(mailbox_from, mailbox_to)
154
+ raise ArgumentError, "mailbox_from must be a Larch::IMAP::Mailbox instance" unless mailbox_from.is_a?(Larch::IMAP::Mailbox)
155
+ raise ArgumentError, "mailbox_to must be a Larch::IMAP::Mailbox instance" unless mailbox_to.is_a?(Larch::IMAP::Mailbox)
156
+
157
+ return if excluded?(mailbox_from.name) || excluded?(mailbox_to.name)
158
+
159
+ mailbox_to.subscribe if mailbox_from.subscribed?
160
+ copy_messages(mailbox_from, mailbox_to)
158
161
 
159
- return if excluded?(mb_name_from) || excluded?(mb_name_to)
162
+ mailbox_from.each_mailbox do |child_from|
163
+ next if excluded?(child_from.name)
164
+ child_to = mailbox_to.imap.mailbox(child_from.name, child_from.delim)
165
+ copy_mailbox(child_from, child_to)
166
+ end
167
+ end
160
168
 
161
- @log.info "copying messages from #{imap_from.host}/#{mb_name_from} to #{imap_to.host}/#{mb_name_to}"
169
+ def copy_messages(mailbox_from, mailbox_to)
170
+ raise ArgumentError, "mailbox_from must be a Larch::IMAP::Mailbox instance" unless mailbox_from.is_a?(Larch::IMAP::Mailbox)
171
+ raise ArgumentError, "mailbox_to must be a Larch::IMAP::Mailbox instance" unless mailbox_to.is_a?(Larch::IMAP::Mailbox)
162
172
 
163
- mailbox_from = imap_from.mailbox(mb_name_from)
173
+ return if excluded?(mailbox_from.name) || excluded?(mailbox_to.name)
164
174
 
165
- @total += mailbox_from.length
175
+ imap_from = mailbox_from.imap
176
+ imap_to = mailbox_to.imap
166
177
 
167
- mailbox_to = imap_to.mailbox(mb_name_to)
178
+ @log.info "copying messages from #{imap_from.host}/#{mailbox_from.name} to #{imap_to.host}/#{mailbox_to.name}"
179
+
180
+ @total += mailbox_from.length
168
181
 
169
182
  mailbox_from.each_guid do |guid|
170
183
  next if mailbox_to.has_guid?(guid)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rgrove-larch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2.1
4
+ version: 1.0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Grove
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-17 00:00:00 -07:00
12
+ date: 2009-08-19 00:00:00 -07:00
13
13
  default_executable: larch
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency