rgrove-larch 1.0.2.1 → 1.0.2.2

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 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