community/pipermail-archives/sup-devel/2012-08.txt (36263B) - raw
1 From ezyang@MIT.EDU Tue Aug 21 14:35:45 2012
2 From: ezyang@MIT.EDU (Edward Z. Yang)
3 Date: Tue, 21 Aug 2012 10:35:45 -0400
4 Subject: [sup-devel] Maildir synchronizing other labels
5 Message-ID: <1345559230-sup-5105@javelin>
6
7 I think it would be nice if we at least support the :inbox label,
8 so that we can keep our inboxes tidy and our OfflineIMAP sync
9 times down.
10
11 Proposed implementation strategy:
12
13 - Define a label/source mapping, as well as a default source for
14 unrecognized labels and an ordering on labels if there is
15 a conflict. (Each Maildir folder is its own source.)
16
17 - Implement moving messages between Maildir sources in Sup.
18 Probably the easiest way is to do this:
19
20 1. Copy message form old Maildir to new Maildir
21 2. Add new Maildir copy to index (with all other tags
22 and metadata added on)
23 3. Delete old Maildir copy from index
24
25 OfflineIMAP will then DTRT as long as SEARCH is supported,
26 I think.
27
28 - Hook in this behavior on the right places (label change,
29 after message add)
30
31 - Implement a script to go through old mail and move it.
32
33 Edward
34
35 From ezyang@MIT.EDU Tue Aug 21 15:17:32 2012
36 From: ezyang@MIT.EDU (Edward Z. Yang)
37 Date: Tue, 21 Aug 2012 11:17:32 -0400
38 Subject: [sup-devel] inotify support for Maildir mailboxes
39 Message-ID: <1345562202-sup-2266@javelin>
40
41 I'm planning on adding inotify support for Maildir mailboxes.
42 This would mean we no longer need to 'poll' to find new messages;
43 they show up instantly. Let me know if you're interested and willing
44 to help test.
45
46 Cheers,
47 Edward
48
49 From alvherre@alvh.no-ip.org Tue Aug 21 16:00:31 2012
50 From: alvherre@alvh.no-ip.org (Alvaro Herrera)
51 Date: Tue, 21 Aug 2012 12:00:31 -0400
52 Subject: [sup-devel] inotify support for Maildir mailboxes
53 In-Reply-To: <1345562202-sup-2266@javelin>
54 References: <1345562202-sup-2266@javelin>
55 Message-ID: <1345564795-sup-3898@alvh.no-ip.org>
56
57 Excerpts from Edward Z. Yang's message of mar ago 21 11:17:32 -0400 2012:
58 > I'm planning on adding inotify support for Maildir mailboxes.
59 > This would mean we no longer need to 'poll' to find new messages;
60 > they show up instantly. Let me know if you're interested and willing
61 > to help test.
62
63 I definitely am interested and willing to test.
64
65 --
66 ?lvaro Herrera <alvherre at alvh.no-ip.org>
67
68 From ezyang@MIT.EDU Tue Aug 21 19:19:56 2012
69 From: ezyang@MIT.EDU (Edward Z. Yang)
70 Date: Tue, 21 Aug 2012 15:19:56 -0400
71 Subject: [sup-devel] [PATCH] Sync and update other threads when Maildir
72 sync-back changes location.
73 Message-ID: <1345576796-31445-1-git-send-email-ezyang@mit.edu>
74
75 From: "Edward Z. Yang" <ezyang at mit.edu>
76
77 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
78 ---
79 lib/sup/maildir.rb | 2 +-
80 lib/sup/message.rb | 6 +++++-
81 2 files changed, 6 insertions(+), 2 deletions(-)
82
83 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
84 index 0c8c563..050cfaf 100644
85 --- a/lib/sup/maildir.rb
86 +++ b/lib/sup/maildir.rb
87 @@ -226,7 +226,7 @@ private
88 new_base = (flags.include?("S")) ? "cur" : "new"
89 md_base, md_ver, md_flags = maildir_data orig_path
90
91 - return orig_path if md_flags == flags
92 + return if md_flags == flags
93
94 new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
95 orig_path = File.join @dir, orig_path
96 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
97 index 0616f75..cd9226e 100644
98 --- a/lib/sup/message.rb
99 +++ b/lib/sup/message.rb
100 @@ -288,7 +288,11 @@ EOS
101 def sync_back
102 @locations.each do |l|
103 if l.valid?
104 - l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
105 + r = l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
106 + if r
107 + Index.sync_message self, true
108 + UpdateManager.relay self, :updated, self
109 + end
110 end
111 end
112 end
113 --
114 1.7.11.3
115
116
117 From ezyang@MIT.EDU Tue Aug 21 19:25:41 2012
118 From: ezyang@MIT.EDU (Edward Z. Yang)
119 Date: Tue, 21 Aug 2012 15:25:41 -0400
120 Subject: [sup-devel] [PATCH] Sync and update other threads when Maildir
121 sync-back changes location.
122 In-Reply-To: <1345576796-31445-1-git-send-email-ezyang@mit.edu>
123 References: <1345576796-31445-1-git-send-email-ezyang@mit.edu>
124 Message-ID: <1345577064-sup-4877@javelin>
125
126 This fixes the "I changed a message from unread to read in one list (e.g. 'U')
127 and now when I open the message from inbox it can't find it" bug.
128
129 Here is a version that is theoretically more efficient, though God
130 help you if you have more than one location per message.
131
132 commit ca5b02b8ff88412f92984d6b9176ff1876886cc6
133 Author: Edward Z. Yang <ezyang at mit.edu>
134 Date: Tue Aug 21 15:19:11 2012 -0400
135
136 Sync and update other threads when Maildir sync-back changes location.
137
138 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
139
140 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
141 index 0c8c563..050cfaf 100644
142 --- a/lib/sup/maildir.rb
143 +++ b/lib/sup/maildir.rb
144 @@ -226,7 +226,7 @@ private
145 new_base = (flags.include?("S")) ? "cur" : "new"
146 md_base, md_ver, md_flags = maildir_data orig_path
147
148 - return orig_path if md_flags == flags
149 + return if md_flags == flags
150
151 new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
152 orig_path = File.join @dir, orig_path
153 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
154 index 0616f75..9af847d 100644
155 --- a/lib/sup/message.rb
156 +++ b/lib/sup/message.rb
157 @@ -286,11 +286,16 @@ EOS
158 end
159
160 def sync_back
161 + r = nil
162 @locations.each do |l|
163 if l.valid?
164 - l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
165 + r ||= l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
166 end
167 end
168 + if r
169 + Index.sync_message self, true
170 + UpdateManager.relay self, :updated, self
171 + end
172 end
173
174 def merge_labels_from_locations merge_labels
175
176 Excerpts from Edward Z. Yang's message of Tue Aug 21 15:19:56 -0400 2012:
177 > From: "Edward Z. Yang" <ezyang at mit.edu>
178 >
179 > Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
180 > ---
181 > lib/sup/maildir.rb | 2 +-
182 > lib/sup/message.rb | 6 +++++-
183 > 2 files changed, 6 insertions(+), 2 deletions(-)
184 >
185 > diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
186 > index 0c8c563..050cfaf 100644
187 > --- a/lib/sup/maildir.rb
188 > +++ b/lib/sup/maildir.rb
189 > @@ -226,7 +226,7 @@ private
190 > new_base = (flags.include?("S")) ? "cur" : "new"
191 > md_base, md_ver, md_flags = maildir_data orig_path
192 >
193 > - return orig_path if md_flags == flags
194 > + return if md_flags == flags
195 >
196 > new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
197 > orig_path = File.join @dir, orig_path
198 > diff --git a/lib/sup/message.rb b/lib/sup/message.rb
199 > index 0616f75..cd9226e 100644
200 > --- a/lib/sup/message.rb
201 > +++ b/lib/sup/message.rb
202 > @@ -288,7 +288,11 @@ EOS
203 > def sync_back
204 > @locations.each do |l|
205 > if l.valid?
206 > - l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
207 > + r = l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
208 > + if r
209 > + Index.sync_message self, true
210 > + UpdateManager.relay self, :updated, self
211 > + end
212 > end
213 > end
214 > end
215
216 From ezyang@MIT.EDU Tue Aug 21 19:43:47 2012
217 From: ezyang@MIT.EDU (Edward Z. Yang)
218 Date: Tue, 21 Aug 2012 15:43:47 -0400
219 Subject: [sup-devel] [PATCH] Sync and update other threads when Maildir
220 sync-back changes location.
221 In-Reply-To: <1345577064-sup-4877@javelin>
222 References: <1345576796-31445-1-git-send-email-ezyang@mit.edu>
223 <1345577064-sup-4877@javelin>
224 Message-ID: <1345578187-sup-5921@javelin>
225
226 Aaand here's an even prettier version.
227
228 commit f7d30410d946418a885929f20a498c10e4058243
229 Author: Edward Z. Yang <ezyang at mit.edu>
230 Date: Tue Aug 21 15:19:11 2012 -0400
231
232 Sync and update other threads when Maildir sync-back changes location.
233
234 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
235
236 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
237 index 0c8c563..050cfaf 100644
238 --- a/lib/sup/maildir.rb
239 +++ b/lib/sup/maildir.rb
240 @@ -226,7 +226,7 @@ private
241 new_base = (flags.include?("S")) ? "cur" : "new"
242 md_base, md_ver, md_flags = maildir_data orig_path
243
244 - return orig_path if md_flags == flags
245 + return if md_flags == flags
246
247 new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
248 orig_path = File.join @dir, orig_path
249 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
250 index 0616f75..3eeea66 100644
251 --- a/lib/sup/message.rb
252 +++ b/lib/sup/message.rb
253 @@ -286,10 +286,11 @@ EOS
254 end
255
256 def sync_back
257 - @locations.each do |l|
258 - if l.valid?
259 - l.sync_back @labels if $config[:sync_back_to_maildir] and l.source.is_a? Maildir
260 - end
261 + if @locations.map { |l|
262 + l.sync_back @labels if l.valid? and $config[:sync_back_to_maildir] and l.source.is_a? Maildir
263 + }.any?
264 + Index.sync_message self, true
265 + UpdateManager.relay self, :updated, self
266 end
267 end
268
269
270 From ezyang@MIT.EDU Wed Aug 22 05:45:31 2012
271 From: ezyang@MIT.EDU (Edward Z. Yang)
272 Date: Wed, 22 Aug 2012 01:45:31 -0400
273 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
274 sources based on label.
275 In-Reply-To: <1345559230-sup-5105@javelin>
276 References: <1345559230-sup-5105@javelin>
277 Message-ID: <1345614331-17294-1-git-send-email-ezyang@mit.edu>
278
279 From: "Edward Z. Yang" <ezyang at mit.edu>
280
281 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
282 ---
283 lib/sup/maildir.rb | 28 ++++++++++++++++++++++------
284 lib/sup/message.rb | 9 +++++++--
285 2 files changed, 29 insertions(+), 8 deletions(-)
286
287 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
288 index 95305c2..ff8da23 100644
289 --- a/lib/sup/maildir.rb
290 +++ b/lib/sup/maildir.rb
291 @@ -77,8 +77,17 @@ class Maildir < Source
292 end
293
294 def sync_back id, labels
295 + new_source = @id
296 + $config[:maildir_labels].each do |k,v|
297 + v.each do |lbl,i|
298 + if lbl.nil? or labels.member? lbl
299 + new_source = i
300 + break
301 + end
302 + end if v.any? { |lbl,i| i == @id }
303 + end if $config[:maildir_labels]
304 flags = maildir_reconcile_flags id, labels
305 - maildir_mark_file id, flags
306 + maildir_move_file id, new_source, flags
307 end
308
309 def raw_header id
310 @@ -221,24 +230,31 @@ private
311 new_flags.to_a.sort.join
312 end
313
314 - def maildir_mark_file orig_path, flags
315 + def maildir_move_file orig_path, new_source_id, flags
316 @mutex.synchronize do
317 new_base = (flags.include?("S")) ? "cur" : "new"
318 md_base, md_ver, md_flags = maildir_data orig_path
319
320 - return if md_flags == flags
321 + return if md_flags == flags and new_source_id == @id
322 +
323 + new_source = SourceManager[new_source_id]
324
325 new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
326 orig_path = File.join @dir, orig_path
327 - new_path = File.join @dir, new_loc
328 + new_path = File.join new_source.file_path, new_loc
329 tmp_path = File.join @dir, "tmp", "#{md_base}:#{md_ver},#{flags}"
330
331 File.link orig_path, tmp_path
332 File.unlink orig_path
333 - File.link tmp_path, new_path
334 + begin
335 + File.link tmp_path, new_path
336 + rescue SystemCallError
337 + File.unlink new_path # XXX kinda unsafe eh
338 + File.link tmp_path, new_path
339 + end
340 File.unlink tmp_path
341
342 - new_loc
343 + [new_source, new_loc]
344 end
345 end
346 end
347 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
348 index 3eeea66..d6016df 100644
349 --- a/lib/sup/message.rb
350 +++ b/lib/sup/message.rb
351 @@ -726,8 +726,13 @@ class Location
352 end
353
354 def sync_back labels
355 - new_info = source.sync_back(@info, labels) if source.respond_to? :sync_back
356 - @info = new_info if new_info
357 + pair = source.sync_back(@info, labels) if source.respond_to? :sync_back
358 + if pair
359 + new_source, new_info = pair
360 + @source = new_source if new_source
361 + @info = new_info if new_info
362 + end
363 + pair
364 end
365
366 ## much faster than raw_message
367 --
368 1.7.11.3
369
370
371 From ezyang@MIT.EDU Wed Aug 22 05:54:15 2012
372 From: ezyang@MIT.EDU (Edward Z. Yang)
373 Date: Wed, 22 Aug 2012 01:54:15 -0400
374 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
375 sources based on label.
376 In-Reply-To: <1345614331-17294-1-git-send-email-ezyang@mit.edu>
377 References: <1345559230-sup-5105@javelin>
378 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
379 Message-ID: <1345614564-sup-5523@javelin>
380
381 Usage instructions:
382
383 In config.yaml, you need to add a new option :maildir_labels:
384
385 :maildir_labels:
386 :stanford: [[:inbox, 4], [null, 6]]
387
388 Maildir labels is a dictionary of "accounts" to lists of precedences.
389 Read it as follows:
390
391 For messages in source 4 or source 6 (consult sources.yaml),
392 if the message has the :inbox tag, move it to source 4, otherwise
393 move it to source 6.
394
395 So in this case, 6 would be some sort of Archive folder, and 4 would be INBOX.
396 If you want "export-only" folders, just tack them on after the null entry;
397 the labels are checked *in order*. Multiple accounts are supported, but
398 these should be disjoint sets of sources.
399
400 This will automatically start working for any new mail you change the labels of.
401 In order to apply this to old mail, you need to run sup-sync-back-maildir.
402 OfflineIMAP will shit its pants [1] if you move too much mail, so I recommend
403 holding on until I implement the companion patch for OfflineIMAP if you have
404 a lot of mail.
405
406 Edward
407
408 [1] Namely, it will reupload every single article of mail, and if you get
409 unlucky and "Archive" is sorted before "INBOX", it will probably run you out
410 of quota too. If you arrange to delete everything from INBOX first, and then
411 sync Archive, it will probably just spend a lot of time uploading.
412
413 Excerpts from Edward Z. Yang's message of Wed Aug 22 01:45:31 -0400 2012:
414 > From: "Edward Z. Yang" <ezyang at mit.edu>
415 >
416 > Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
417 > ---
418 > lib/sup/maildir.rb | 28 ++++++++++++++++++++++------
419 > lib/sup/message.rb | 9 +++++++--
420 > 2 files changed, 29 insertions(+), 8 deletions(-)
421 >
422 > diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
423 > index 95305c2..ff8da23 100644
424 > --- a/lib/sup/maildir.rb
425 > +++ b/lib/sup/maildir.rb
426 > @@ -77,8 +77,17 @@ class Maildir < Source
427 > end
428 >
429 > def sync_back id, labels
430 > + new_source = @id
431 > + $config[:maildir_labels].each do |k,v|
432 > + v.each do |lbl,i|
433 > + if lbl.nil? or labels.member? lbl
434 > + new_source = i
435 > + break
436 > + end
437 > + end if v.any? { |lbl,i| i == @id }
438 > + end if $config[:maildir_labels]
439 > flags = maildir_reconcile_flags id, labels
440 > - maildir_mark_file id, flags
441 > + maildir_move_file id, new_source, flags
442 > end
443 >
444 > def raw_header id
445 > @@ -221,24 +230,31 @@ private
446 > new_flags.to_a.sort.join
447 > end
448 >
449 > - def maildir_mark_file orig_path, flags
450 > + def maildir_move_file orig_path, new_source_id, flags
451 > @mutex.synchronize do
452 > new_base = (flags.include?("S")) ? "cur" : "new"
453 > md_base, md_ver, md_flags = maildir_data orig_path
454 >
455 > - return if md_flags == flags
456 > + return if md_flags == flags and new_source_id == @id
457 > +
458 > + new_source = SourceManager[new_source_id]
459 >
460 > new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
461 > orig_path = File.join @dir, orig_path
462 > - new_path = File.join @dir, new_loc
463 > + new_path = File.join new_source.file_path, new_loc
464 > tmp_path = File.join @dir, "tmp", "#{md_base}:#{md_ver},#{flags}"
465 >
466 > File.link orig_path, tmp_path
467 > File.unlink orig_path
468 > - File.link tmp_path, new_path
469 > + begin
470 > + File.link tmp_path, new_path
471 > + rescue SystemCallError
472 > + File.unlink new_path # XXX kinda unsafe eh
473 > + File.link tmp_path, new_path
474 > + end
475 > File.unlink tmp_path
476 >
477 > - new_loc
478 > + [new_source, new_loc]
479 > end
480 > end
481 > end
482 > diff --git a/lib/sup/message.rb b/lib/sup/message.rb
483 > index 3eeea66..d6016df 100644
484 > --- a/lib/sup/message.rb
485 > +++ b/lib/sup/message.rb
486 > @@ -726,8 +726,13 @@ class Location
487 > end
488 >
489 > def sync_back labels
490 > - new_info = source.sync_back(@info, labels) if source.respond_to? :sync_back
491 > - @info = new_info if new_info
492 > + pair = source.sync_back(@info, labels) if source.respond_to? :sync_back
493 > + if pair
494 > + new_source, new_info = pair
495 > + @source = new_source if new_source
496 > + @info = new_info if new_info
497 > + end
498 > + pair
499 > end
500 >
501 > ## much faster than raw_message
502
503 From ezyang@MIT.EDU Wed Aug 22 20:09:40 2012
504 From: ezyang@MIT.EDU (Edward Z. Yang)
505 Date: Wed, 22 Aug 2012 16:09:40 -0400
506 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
507 sources based on label.
508 In-Reply-To: <1345614564-sup-5523@javelin>
509 References: <1345559230-sup-5105@javelin>
510 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
511 <1345614564-sup-5523@javelin>
512 Message-ID: <1345665956-sup-4988@javelin>
513
514 Here is an improved version that handles the thread/message distinction
515 better; previously, if you archived something, it's possible only some of
516 the messages got moved if you hadn't run sup-sync-back-maildir.
517
518 commit a25c345c15c8859a041cc9dc13090d7b8feb3d58
519 Author: Edward Z. Yang <ezyang at mit.edu>
520 Date: Tue Aug 21 23:40:03 2012 -0400
521
522 Implement moving message between Maildir sources based on label.
523
524 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
525
526 diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
527 index 95305c2..a7bf567 100644
528 --- a/lib/sup/maildir.rb
529 +++ b/lib/sup/maildir.rb
530 @@ -76,9 +76,23 @@ class Maildir < Source
531 with_file_for(id) { |f| RMail::Parser.read f }
532 end
533
534 + def wrong_source? labels
535 + new_source = nil
536 + $config[:maildir_labels].each do |k,v|
537 + v.each do |lbl,i|
538 + if lbl.nil? or labels.member? lbl
539 + new_source = i
540 + break
541 + end
542 + end if v.any? { |lbl,i| i == @id }
543 + end if $config[:maildir_labels]
544 + new_source
545 + end
546 +
547 def sync_back id, labels
548 + new_source = wrong_source? labels || @id
549 flags = maildir_reconcile_flags id, labels
550 - maildir_mark_file id, flags
551 + maildir_move_file id, new_source, flags
552 end
553
554 def raw_header id
555 @@ -221,24 +235,31 @@ private
556 new_flags.to_a.sort.join
557 end
558
559 - def maildir_mark_file orig_path, flags
560 + def maildir_move_file orig_path, new_source_id, flags
561 @mutex.synchronize do
562 new_base = (flags.include?("S")) ? "cur" : "new"
563 md_base, md_ver, md_flags = maildir_data orig_path
564
565 - return if md_flags == flags
566 + return if md_flags == flags and new_source_id == @id
567 +
568 + new_source = SourceManager[new_source_id]
569
570 new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
571 orig_path = File.join @dir, orig_path
572 - new_path = File.join @dir, new_loc
573 + new_path = File.join new_source.file_path, new_loc
574 tmp_path = File.join @dir, "tmp", "#{md_base}:#{md_ver},#{flags}"
575
576 File.link orig_path, tmp_path
577 File.unlink orig_path
578 - File.link tmp_path, new_path
579 + begin
580 + File.link tmp_path, new_path
581 + rescue SystemCallError
582 + File.unlink new_path # XXX kinda unsafe eh
583 + File.link tmp_path, new_path
584 + end
585 File.unlink tmp_path
586
587 - new_loc
588 + [new_source, new_loc]
589 end
590 end
591 end
592 diff --git a/lib/sup/message.rb b/lib/sup/message.rb
593 index 3eeea66..4139f3e 100644
594 --- a/lib/sup/message.rb
595 +++ b/lib/sup/message.rb
596 @@ -285,6 +285,10 @@ EOS
597 location.each_raw_message_line &b
598 end
599
600 + def wrong_source?
601 + $config[:sync_back_to_maildir] and @locations.any? { |l| l.valid? and l.source.is_a? Maildir and l.wrong_source? @labels}
602 + end
603 +
604 def sync_back
605 if @locations.map { |l|
606 l.sync_back @labels if l.valid? and $config[:sync_back_to_maildir] and l.source.is_a? Maildir
607 @@ -726,8 +730,17 @@ class Location
608 end
609
610 def sync_back labels
611 - new_info = source.sync_back(@info, labels) if source.respond_to? :sync_back
612 - @info = new_info if new_info
613 + pair = source.sync_back(@info, labels) if source.respond_to? :sync_back
614 + if pair
615 + new_source, new_info = pair
616 + @source = new_source if new_source
617 + @info = new_info if new_info
618 + end
619 + pair
620 + end
621 +
622 + def wrong_source? labels
623 + source.wrong_source? labels if source.respond_to? :wrong_source
624 end
625
626 ## much faster than raw_message
627 diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb
628 index b08bae2..c1e4b40 100644
629 --- a/lib/sup/thread.rb
630 +++ b/lib/sup/thread.rb
631 @@ -113,7 +113,7 @@ class Thread
632
633 def set_labels l; each { |m, *o| m && m.labels = l }; end
634 def has_label? t; any? { |m, *o| m && m.has_label?(t) }; end
635 - def each_dirty_message; each { |m, *o| m && m.dirty? && yield(m) }; end
636 + def each_dirty_message; each { |m, *o| m && (m.dirty? || m.wrong_source?) && yield(m) }; end
637
638 def direct_participants
639 map { |m, *o| [m.from] + m.to if m }.flatten.compact.uniq
640
641 From ezyang@MIT.EDU Thu Aug 23 14:40:22 2012
642 From: ezyang@MIT.EDU (Edward Z. Yang)
643 Date: Thu, 23 Aug 2012 10:40:22 -0400
644 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
645 sources based on label.
646 In-Reply-To: <1345665956-sup-4988@javelin>
647 References: <1345559230-sup-5105@javelin>
648 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
649 <1345614564-sup-5523@javelin> <1345665956-sup-4988@javelin>
650 Message-ID: <1345732781-sup-2983@javelin>
651
652 It looks like the current patchset will *destroy* all labels you have
653 on messages, so be careful! (This was masked for me since most of my
654 labels are from before-add-message.rb, and that hook gets reapplied)
655
656 Edward
657
658 Excerpts from Edward Z. Yang's message of Wed Aug 22 16:09:40 -0400 2012:
659 > Here is an improved version that handles the thread/message distinction
660 > better; previously, if you archived something, it's possible only some of
661 > the messages got moved if you hadn't run sup-sync-back-maildir.
662 >
663 > commit a25c345c15c8859a041cc9dc13090d7b8feb3d58
664 > Author: Edward Z. Yang <ezyang at mit.edu>
665 > Date: Tue Aug 21 23:40:03 2012 -0400
666 >
667 > Implement moving message between Maildir sources based on label.
668 >
669 > Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
670 >
671 > diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
672 > index 95305c2..a7bf567 100644
673 > --- a/lib/sup/maildir.rb
674 > +++ b/lib/sup/maildir.rb
675 > @@ -76,9 +76,23 @@ class Maildir < Source
676 > with_file_for(id) { |f| RMail::Parser.read f }
677 > end
678 >
679 > + def wrong_source? labels
680 > + new_source = nil
681 > + $config[:maildir_labels].each do |k,v|
682 > + v.each do |lbl,i|
683 > + if lbl.nil? or labels.member? lbl
684 > + new_source = i
685 > + break
686 > + end
687 > + end if v.any? { |lbl,i| i == @id }
688 > + end if $config[:maildir_labels]
689 > + new_source
690 > + end
691 > +
692 > def sync_back id, labels
693 > + new_source = wrong_source? labels || @id
694 > flags = maildir_reconcile_flags id, labels
695 > - maildir_mark_file id, flags
696 > + maildir_move_file id, new_source, flags
697 > end
698 >
699 > def raw_header id
700 > @@ -221,24 +235,31 @@ private
701 > new_flags.to_a.sort.join
702 > end
703 >
704 > - def maildir_mark_file orig_path, flags
705 > + def maildir_move_file orig_path, new_source_id, flags
706 > @mutex.synchronize do
707 > new_base = (flags.include?("S")) ? "cur" : "new"
708 > md_base, md_ver, md_flags = maildir_data orig_path
709 >
710 > - return if md_flags == flags
711 > + return if md_flags == flags and new_source_id == @id
712 > +
713 > + new_source = SourceManager[new_source_id]
714 >
715 > new_loc = File.join new_base, "#{md_base}:#{md_ver},#{flags}"
716 > orig_path = File.join @dir, orig_path
717 > - new_path = File.join @dir, new_loc
718 > + new_path = File.join new_source.file_path, new_loc
719 > tmp_path = File.join @dir, "tmp", "#{md_base}:#{md_ver},#{flags}"
720 >
721 > File.link orig_path, tmp_path
722 > File.unlink orig_path
723 > - File.link tmp_path, new_path
724 > + begin
725 > + File.link tmp_path, new_path
726 > + rescue SystemCallError
727 > + File.unlink new_path # XXX kinda unsafe eh
728 > + File.link tmp_path, new_path
729 > + end
730 > File.unlink tmp_path
731 >
732 > - new_loc
733 > + [new_source, new_loc]
734 > end
735 > end
736 > end
737 > diff --git a/lib/sup/message.rb b/lib/sup/message.rb
738 > index 3eeea66..4139f3e 100644
739 > --- a/lib/sup/message.rb
740 > +++ b/lib/sup/message.rb
741 > @@ -285,6 +285,10 @@ EOS
742 > location.each_raw_message_line &b
743 > end
744 >
745 > + def wrong_source?
746 > + $config[:sync_back_to_maildir] and @locations.any? { |l| l.valid? and l.source.is_a? Maildir and l.wrong_source? @labels}
747 > + end
748 > +
749 > def sync_back
750 > if @locations.map { |l|
751 > l.sync_back @labels if l.valid? and $config[:sync_back_to_maildir] and l.source.is_a? Maildir
752 > @@ -726,8 +730,17 @@ class Location
753 > end
754 >
755 > def sync_back labels
756 > - new_info = source.sync_back(@info, labels) if source.respond_to? :sync_back
757 > - @info = new_info if new_info
758 > + pair = source.sync_back(@info, labels) if source.respond_to? :sync_back
759 > + if pair
760 > + new_source, new_info = pair
761 > + @source = new_source if new_source
762 > + @info = new_info if new_info
763 > + end
764 > + pair
765 > + end
766 > +
767 > + def wrong_source? labels
768 > + source.wrong_source? labels if source.respond_to? :wrong_source
769 > end
770 >
771 > ## much faster than raw_message
772 > diff --git a/lib/sup/thread.rb b/lib/sup/thread.rb
773 > index b08bae2..c1e4b40 100644
774 > --- a/lib/sup/thread.rb
775 > +++ b/lib/sup/thread.rb
776 > @@ -113,7 +113,7 @@ class Thread
777 >
778 > def set_labels l; each { |m, *o| m && m.labels = l }; end
779 > def has_label? t; any? { |m, *o| m && m.has_label?(t) }; end
780 > - def each_dirty_message; each { |m, *o| m && m.dirty? && yield(m) }; end
781 > + def each_dirty_message; each { |m, *o| m && (m.dirty? || m.wrong_source?) && yield(m) }; end
782 >
783 > def direct_participants
784 > map { |m, *o| [m.from] + m.to if m }.flatten.compact.uniq
785
786 From alvherre@alvh.no-ip.org Thu Aug 23 14:52:21 2012
787 From: alvherre@alvh.no-ip.org (Alvaro Herrera)
788 Date: Thu, 23 Aug 2012 10:52:21 -0400
789 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
790 sources based on label.
791 In-Reply-To: <1345732781-sup-2983@javelin>
792 References: <1345559230-sup-5105@javelin>
793 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
794 <1345614564-sup-5523@javelin> <1345665956-sup-4988@javelin>
795 <1345732781-sup-2983@javelin>
796 Message-ID: <1345733453-sup-9957@alvh.no-ip.org>
797
798 Excerpts from Edward Z. Yang's message of jue ago 23 10:40:22 -0400 2012:
799 > It looks like the current patchset will *destroy* all labels you have
800 > on messages, so be careful! (This was masked for me since most of my
801 > labels are from before-add-message.rb, and that hook gets reapplied)
802
803 Thanks for the notice. Most of my labels come from that hook too, but a
804 few do not, so I could easily lose some! I was planning on trying out
805 your patch, but with this caveat I'm likely to refrain. Are you
806 planning on submitting a fixed version?
807
808 --
809 ?lvaro Herrera <alvherre at alvh.no-ip.org>
810
811 From ezyang@MIT.EDU Thu Aug 23 15:28:22 2012
812 From: ezyang@MIT.EDU (Edward Z. Yang)
813 Date: Thu, 23 Aug 2012 11:28:22 -0400
814 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
815 sources based on label.
816 In-Reply-To: <1345733453-sup-9957@alvh.no-ip.org>
817 References: <1345559230-sup-5105@javelin>
818 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
819 <1345614564-sup-5523@javelin> <1345665956-sup-4988@javelin>
820 <1345732781-sup-2983@javelin> <1345733453-sup-9957@alvh.no-ip.org>
821 Message-ID: <1345735597-sup-2272@javelin>
822
823 Yes. The current plan is to snoop the message ID of newly added messages
824 in maildirs, and do moved message detection based on that. If you have a
825 better idea I'm all ears. (Another possibility is to add sha1sum to the
826 index and compare that.)
827
828 Also note that it won't destroy the labels *unless you run OfflineIMAP*.
829 The trouble is OfflineIMAP reuploads your message and then reassigns
830 the UID based on the IMAP server, but doesn't communicate this back to Sup.
831
832 Edward
833
834 Excerpts from Alvaro Herrera's message of Thu Aug 23 10:52:21 -0400 2012:
835 > Excerpts from Edward Z. Yang's message of jue ago 23 10:40:22 -0400 2012:
836 > > It looks like the current patchset will *destroy* all labels you have
837 > > on messages, so be careful! (This was masked for me since most of my
838 > > labels are from before-add-message.rb, and that hook gets reapplied)
839 >
840 > Thanks for the notice. Most of my labels come from that hook too, but a
841 > few do not, so I could easily lose some! I was planning on trying out
842 > your patch, but with this caveat I'm likely to refrain. Are you
843 > planning on submitting a fixed version?
844 >
845
846 From ezyang@MIT.EDU Thu Aug 23 18:20:18 2012
847 From: ezyang@MIT.EDU (Edward Z. Yang)
848 Date: Thu, 23 Aug 2012 14:20:18 -0400
849 Subject: [sup-devel] [PATCH] Implement moving message between Maildir
850 sources based on label.
851 In-Reply-To: <1345733453-sup-9957@alvh.no-ip.org>
852 References: <1345559230-sup-5105@javelin>
853 <1345614331-17294-1-git-send-email-ezyang@mit.edu>
854 <1345614564-sup-5523@javelin> <1345665956-sup-4988@javelin>
855 <1345732781-sup-2983@javelin> <1345733453-sup-9957@alvh.no-ip.org>
856 Message-ID: <1345745979-sup-7676@javelin>
857
858 With pleasure, I report that Sup is actually doing this! So solving
859 the "hooks run too many times" is as easy as this:
860
861 commit ec3afe7ac01741bc67f68009193d2d2e73f05529
862 Author: Edward Z. Yang <ezyang at mit.edu>
863 Date: Thu Aug 23 14:19:24 2012 -0400
864
865 Don't run before-add-message hook for messages already in index.
866
867 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
868
869 diff --git a/lib/sup/poll.rb b/lib/sup/poll.rb
870 index 1b64098..7d5aaa2 100644
871 --- a/lib/sup/poll.rb
872 +++ b/lib/sup/poll.rb
873 @@ -184,7 +184,7 @@ EOS
874 m.labels.each { |l| LabelManager << l }
875 m.labels = old_m.labels + (m.labels - [:unread, :inbox]) if old_m
876 m.locations = old_m.locations + m.locations if old_m
877 - HookManager.run "before-add-message", :message => m
878 + HookManager.run "before-add-message", :message => m if not old_m
879 yield :add, m, old_m, args[:progress] if block_given?
880 Index.sync_message m, true
881
882
883
884 Excerpts from Alvaro Herrera's message of Thu Aug 23 10:52:21 -0400 2012:
885 > Excerpts from Edward Z. Yang's message of jue ago 23 10:40:22 -0400 2012:
886 > > It looks like the current patchset will *destroy* all labels you have
887 > > on messages, so be careful! (This was masked for me since most of my
888 > > labels are from before-add-message.rb, and that hook gets reapplied)
889 >
890 > Thanks for the notice. Most of my labels come from that hook too, but a
891 > few do not, so I could easily lose some! I was planning on trying out
892 > your patch, but with this caveat I'm likely to refrain. Are you
893 > planning on submitting a fixed version?
894 >
895
896 From ezyang@MIT.EDU Wed Aug 29 00:35:01 2012
897 From: ezyang@MIT.EDU (Edward Z. Yang)
898 Date: Tue, 28 Aug 2012 20:35:01 -0400
899 Subject: [sup-devel] [PATCH] Handle drafts with high ID numbers.
900 Message-ID: <1346200502-27650-1-git-send-email-ezyang@mit.edu>
901
902 From: "Edward Z. Yang" <ezyang at mit.edu>
903
904 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
905 ---
906 lib/sup/draft.rb | 16 +++++++---------
907 1 file changed, 7 insertions(+), 9 deletions(-)
908
909 diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
910 index 58c45db..1f33dc1 100644
911 --- a/lib/sup/draft.rb
912 +++ b/lib/sup/draft.rb
913 @@ -37,7 +37,6 @@ class DraftLoader < Source
914 Dir.mkdir dir unless File.exists? dir
915 super DraftManager.source_name, true, false
916 @dir = dir
917 - @cur_offset = 0
918 end
919
920 def id; DraftManager.source_id; end
921 @@ -46,14 +45,13 @@ class DraftLoader < Source
922
923 def poll
924 ids = get_ids
925 - ids.each do |id|
926 - if id >= @cur_offset
927 - @cur_offset = id + 1
928 - yield :add,
929 - :info => id,
930 - :labels => [:draft, :inbox],
931 - :progress => 0.0
932 - end
933 + old_ids = Enumerator.new(Index.instance, :each_source_info, self.id).to_a
934 + new_ids = ids - old_ids
935 + new_ids.each do |id|
936 + yield :add,
937 + :info => id,
938 + :labels => [:draft, :inbox],
939 + :progress => 0.0
940 end
941 end
942
943 --
944 1.7.11.3
945
946
947 From ezyang@MIT.EDU Wed Aug 29 00:41:15 2012
948 From: ezyang@MIT.EDU (Edward Z. Yang)
949 Date: Tue, 28 Aug 2012 20:41:15 -0400
950 Subject: [sup-devel] [PATCH] Handle drafts with high ID numbers.
951 In-Reply-To: <1346200502-27650-1-git-send-email-ezyang@mit.edu>
952 References: <1346200502-27650-1-git-send-email-ezyang@mit.edu>
953 Message-ID: <1346200850-sup-3549@javelin>
954
955 If you've ever suffered from saving a draft message, and then
956 suddenly asking, "Where did it go?" because it didn't show up
957 in your INBOX, try this patch.
958
959 Edward
960
961 Excerpts from Edward Z. Yang's message of Tue Aug 28 20:35:01 -0400 2012:
962 > From: "Edward Z. Yang" <ezyang at mit.edu>
963 >
964 > Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
965 > ---
966 > lib/sup/draft.rb | 16 +++++++---------
967 > 1 file changed, 7 insertions(+), 9 deletions(-)
968 >
969 > diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
970 > index 58c45db..1f33dc1 100644
971 > --- a/lib/sup/draft.rb
972 > +++ b/lib/sup/draft.rb
973 > @@ -37,7 +37,6 @@ class DraftLoader < Source
974 > Dir.mkdir dir unless File.exists? dir
975 > super DraftManager.source_name, true, false
976 > @dir = dir
977 > - @cur_offset = 0
978 > end
979 >
980 > def id; DraftManager.source_id; end
981 > @@ -46,14 +45,13 @@ class DraftLoader < Source
982 >
983 > def poll
984 > ids = get_ids
985 > - ids.each do |id|
986 > - if id >= @cur_offset
987 > - @cur_offset = id + 1
988 > - yield :add,
989 > - :info => id,
990 > - :labels => [:draft, :inbox],
991 > - :progress => 0.0
992 > - end
993 > + old_ids = Enumerator.new(Index.instance, :each_source_info, self.id).to_a
994 > + new_ids = ids - old_ids
995 > + new_ids.each do |id|
996 > + yield :add,
997 > + :info => id,
998 > + :labels => [:draft, :inbox],
999 > + :progress => 0.0
1000 > end
1001 > end
1002 >
1003
1004 From ezyang@MIT.EDU Wed Aug 29 01:42:10 2012
1005 From: ezyang@MIT.EDU (Edward Z. Yang)
1006 Date: Tue, 28 Aug 2012 21:42:10 -0400
1007 Subject: [sup-devel] [PATCH] Add sent-save-to hook.
1008 Message-ID: <1346204530-30793-1-git-send-email-ezyang@mit.edu>
1009
1010 From: "Edward Z. Yang" <ezyang at mit.edu>
1011
1012 Signed-off-by: Edward Z. Yang <ezyang at mit.edu>
1013 ---
1014 lib/sup/modes/edit-message-mode.rb | 13 ++++++++++++-
1015 lib/sup/sent.rb | 7 ++++---
1016 2 files changed, 16 insertions(+), 4 deletions(-)
1017
1018 diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
1019 index 5947ffd..2daffaf 100644
1020 --- a/lib/sup/modes/edit-message-mode.rb
1021 +++ b/lib/sup/modes/edit-message-mode.rb
1022 @@ -69,6 +69,16 @@ Return value:
1023 True if mail has been sent successfully, false otherwise.
1024 EOS
1025
1026 + HookManager.register "sent-save-to", <<EOS
1027 +Configures where to save sent mail to. If this hook doesn't exist,
1028 +the global sent setting will be used (possibly defaulting to sup://sent)
1029 +Variables:
1030 + message: RMail::Message instance of the mail to send.
1031 + account: Account instance matching the From address
1032 +Return value:
1033 + Source to save mail to, nil to use default
1034 +EOS
1035 +
1036 attr_reader :status
1037 attr_accessor :body, :header
1038 bool_reader :edited
1039 @@ -456,7 +466,8 @@ protected
1040 raise SendmailCommandFailed, "Couldn't execute #{acct.sendmail}" unless $? == 0
1041 end
1042
1043 - SentManager.write_sent_message(date, from_email) { |f| f.puts sanitize_body(m.to_s) }
1044 + SentManager.write_sent_message(HookManager.run("sent-save-to", :message => m, :account => acct),
1045 + date, from_email) { |f| f.puts sanitize_body(m.to_s) }
1046 BufferManager.kill_buffer buffer
1047 BufferManager.flash "Message sent!"
1048 true
1049 diff --git a/lib/sup/sent.rb b/lib/sup/sent.rb
1050 index 0ca1fb1..e712dad 100644
1051 --- a/lib/sup/sent.rb
1052 +++ b/lib/sup/sent.rb
1053 @@ -24,9 +24,10 @@ class SentManager
1054 @source
1055 end
1056
1057 - def write_sent_message date, from_email, &block
1058 - @source.store_message date, from_email, &block
1059 - PollManager.poll_from @source
1060 + def write_sent_message src, date, from_email, &block
1061 + use_src = src || @source
1062 + use_src.store_message date, from_email, &block
1063 + PollManager.poll_from use_src
1064 end
1065 end
1066
1067 --
1068 1.7.11.3
1069
1070