sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 3383653d697ee51c488847e0cb64b215ab421dbc
parent 807427e175d4806acb79ebc0fcd81104f1b720a9
Author: Eric Weikl <eric.weikl@tngtech.com>
Date:   Tue,  8 Oct 2013 02:40:57 -0700

Merge pull request #141 from ericweikl/fix-141-configurable-syncback

Maildir-syncback: Individual sync_back configuration option
Diffstat:
M bin/sup | 1 +
M bin/sup-add | 3 ++-
M bin/sup-config | 3 +++
M bin/sup-sync-back-maildir | 15 ++++++++++-----
M lib/sup.rb | 54 ++++++++++++++++++++++++++++++++++++++++--------------
M lib/sup/maildir.rb | 12 ++++++++++--
M lib/sup/message.rb | 6 +++++-
7 files changed, 71 insertions(+), 23 deletions(-)
diff --git a/bin/sup b/bin/sup
@@ -153,6 +153,7 @@ Index.lock_interactively or exit
 begin
   Redwood::start
   Index.load
+  Redwood::check_syncback_settings
   Index.start_sync_worker unless $opts[:no_threads]
 
   $die = false
diff --git a/bin/sup-add b/bin/sup-add
@@ -30,6 +30,7 @@ Options are:
 EOS
   opt :archive, "Automatically archive all new messages from these sources."
   opt :unusual, "Do not automatically poll these sources for new messages."
+  opt :sync_back, "Synchronize status flags back into messages, defaults to true (Maildir sources only).", :default => true
   opt :labels, "A comma-separated set of labels to apply to all messages from this source", :type => String
   opt :force_new, "Create a new account for this source, even if one already exists."
   opt :force_account, "Reuse previously defined account user@hostname.", :type => String
@@ -99,7 +100,7 @@ begin
     source =
       case parsed_uri.scheme
       when "maildir"
-        Redwood::Maildir.new uri, !$opts[:unusual], $opts[:archive], nil, labels
+        Redwood::Maildir.new uri, !$opts[:unusual], $opts[:archive], $opts[:sync_back], nil, labels
       when "mbox"
         Redwood::MBox.new uri, !$opts[:unusual], $opts[:archive], nil, labels
       when nil
diff --git a/bin/sup-config b/bin/sup-config
@@ -88,6 +88,8 @@ def add_source
     usual = axe_yes "Does this source ever receive new messages?", "y"
     archive = usual ? axe_yes("Should new messages be automatically archived? (I.e. not appear in your inbox, though still be accessible via search.)") : false
 
+    sync_back = (type == :maildir) ? axe_yes("Should the original Maildir messages be modified to reflect changes like read status, starred messages, etc.?", "y") : false
+
     labels_str = axe("Enter any labels to be automatically added to all messages from this source, separated by spaces (or 'none')", default_labels.join(","))
 
     labels = if labels_str =~ /^\s*none\s*$/i
@@ -99,6 +101,7 @@ def add_source
     cmd = build_cmd "sup-add"
     cmd += " --unusual" unless usual
     cmd += " --archive" if archive
+    cmd += " --no-sync-back" unless sync_back
     cmd += " --labels=#{labels.join(',')}" if labels && !labels.empty?
     cmd += " #{uri}"
 
diff --git a/bin/sup-sync-back-maildir b/bin/sup-sync-back-maildir
@@ -31,7 +31,8 @@ Usage:
   sup-sync-back-maildir [options] <source>*
 
 where <source>* is source URIs. If no source is given, the default
-behavior is to sync back all Maildir sources.
+behavior is to sync back all Maildir sources that have not disabled
+sync back using the configuration parameter sync_back = false.
 
 Options include:
 EOS
@@ -54,18 +55,22 @@ index.load
 $config[:sync_back_to_maildir] = true
 
 begin
+  sync_performed = File.readlines Redwood::SYNC_OK_FN
   sources = []
 
   ## Try to find out sources given in parameters
   sources = ARGV.map do |uri|
     s = Redwood::SourceManager.source_for(uri) or die "unknown source: #{uri}. Did you add it with sup-add first?"
     s.is_a?(Redwood::Maildir) or die "#{uri} is not a Maildir source."
+    s.sync_back_enabled? or die "#{uri} has disabled sync back - check your configuration."
     s
   end unless opts[:list_sources]
 
   ## Otherwise, check all sources in sources.yaml
   if sources.empty? or opts[:list_sources] == true
-    sources = Redwood::SourceManager.usual_sources.select { |s| s.is_a? Redwood::Maildir }
+    sources = Redwood::SourceManager.usual_sources.select do |s|
+      s.is_a? Redwood::Maildir and s.sync_back_enabled?
+    end
   end
 
   if opts[:list_sources] == true
@@ -96,10 +101,10 @@ begin
         end
       end
       print "\n"
-
-      ## Write a flag file to tell sup that the synchronization has been performed
-      File.open(Redwood::SYNC_OK_FN, 'w') {|f| f.write("OK") }
+      sync_performed << s.uri
     end
+    ## Write a flag file to tell sup that the synchronization has been performed
+    File.open(Redwood::SYNC_OK_FN, 'w') {|f| f.write(sync_performed.join("\n")) }
   end
 rescue Exception => e
   File.open("sup-exception-log.txt", "w") { |f| f.puts e.backtrace }
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -64,6 +64,7 @@ module Redwood
   YAML_DOMAIN = "supmua.org"
   LEGACY_YAML_DOMAIN = "masanjin.net"
   YAML_DATE = "2006-10-01"
+  MAILDIR_SYNC_CHECK_SKIPPED = 'SKIPPED'
 
   ## record exceptions thrown in threads nicely
   @exceptions = []
@@ -177,13 +178,45 @@ module Redwood
 
     return if bypass_sync_check
 
-    if $config[:sync_back_to_maildir] and not File.exists? Redwood::SYNC_OK_FN
-      $stderr.puts <<EOS
+    if $config[:sync_back_to_maildir]
+      if not File.exists? Redwood::SYNC_OK_FN
+        Redwood.warn_syncback <<EOS
+It appears that the "sync_back_to_maildir" option has been changed
+from false to true since the last execution of sup.
+EOS
+        $stderr.puts <<EOS
+
+Should I complain about this again? (Y/n)
+EOS
+        File.open(Redwood::SYNC_OK_FN, 'w') {|f| f.write(Redwood::MAILDIR_SYNC_CHECK_SKIPPED) } if STDIN.gets.chomp.downcase == 'n'
+      elsif not $config[:sync_back_to_maildir] and File.exists? Redwood::SYNC_OK_FN
+        File.delete(Redwood::SYNC_OK_FN)
+      end
+    end
+  end
+
+  def check_syncback_settings
+    active_sync_sources = File.readlines(Redwood::SYNC_OK_FN).collect { |s| s.strip }
+    return if active_sync_sources.length == 1 and active_sync_sources[0] == Redwood::MAILDIR_SYNC_CHECK_SKIPPED
+    sources = SourceManager.sources
+    newly_synced = sources.select { |s| s.is_a? Maildir and s.sync_back_enabled? and not active_sync_sources.include? s.uri }
+    unless newly_synced.empty?
+      Redwood.warn_syncback <<EOS
+It appears that the option "sync_back" of the following source(s)
+has been changed from false to true since the last execution of
+sup:
+
+#{newly_synced.join("\n")}
+EOS
+    end
+  end
+
+  def self.warn_syncback details
+    $stderr.puts <<EOS
 WARNING
 -------
 
-It appears that the "sync_back_to_maildir" option has been changed
-from false to true since the last execution of sup.
+#{details}
 
 It is *strongly* recommended that you run "sup-sync-back-maildir"
 before continuing, otherwise you might lose informations in your
@@ -196,15 +229,7 @@ Please run "sup-sync-back-maildir -h" to see why it is useful.
 
 Are you really sure you want to continue? (y/N)
 EOS
-      abort "Aborted" unless STDIN.gets.chomp.downcase == 'y'
-      $stderr.puts <<EOS
-
-Should I complain about this again? (Y/n)
-EOS
-      File.open(Redwood::SYNC_OK_FN, 'w') {|f| f.write("SKIPPED") } if STDIN.gets.chomp.downcase == 'n'
-    elsif not $config[:sync_back_to_maildir] and File.exists? Redwood::SYNC_OK_FN
-      File.delete(Redwood::SYNC_OK_FN)
-    end
+    abort "Aborted" unless STDIN.gets.chomp.downcase == 'y'
   end
 
   def finish
@@ -336,7 +361,8 @@ EOM
   end
 
   module_function :save_yaml_obj, :load_yaml_obj, :start, :finish,
-                  :report_broken_sources, :load_config, :managers
+                  :report_broken_sources, :load_config, :managers,
+                  :check_syncback_settings
 end
 
 require 'sup/version'
diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
@@ -8,8 +8,8 @@ class Maildir < Source
   MYHOSTNAME = Socket.gethostname
 
   ## remind me never to use inheritance again.
-  yaml_properties :uri, :usual, :archived, :id, :labels
-  def initialize uri, usual=true, archived=false, id=nil, labels=[]
+  yaml_properties :uri, :usual, :archived, :sync_back, :id, :labels
+  def initialize uri, usual=true, archived=false, sync_back=true, id=nil, labels=[]
     super uri, usual, archived, id
     @expanded_uri = Source.expand_filesystem_uri(uri)
     uri = URI(@expanded_uri)
@@ -18,6 +18,10 @@ class Maildir < Source
     raise ArgumentError, "maildir URI cannot have a host: #{uri.host}" if uri.host
     raise ArgumentError, "maildir URI must have a path component" unless uri.path
 
+    @sync_back = sync_back
+    # sync by default if not specified
+    @sync_back = true if @sync_back.nil?
+
     @dir = uri.path
     @labels = Set.new(labels || [])
     @mutex = Mutex.new
@@ -32,6 +36,10 @@ class Maildir < Source
     [:draft, :starred, :forwarded, :replied, :unread, :deleted]
   end
 
+  def sync_back_enabled?
+    @sync_back
+  end
+
   def store_message date, from_email, &block
     stored = false
     new_fn = new_maildir_basefn + ':2,S'
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
@@ -732,7 +732,7 @@ class Location
 
   def sync_back labels, message
     synced = false
-    return synced unless $config[:sync_back_to_maildir] and valid? and source.respond_to? :sync_back
+    return synced unless sync_back_enabled? and valid?
     source.synchronize do
       new_info = source.sync_back(@info, labels)
       if new_info
@@ -744,6 +744,10 @@ class Location
     synced
   end
 
+  def sync_back_enabled?
+    source.respond_to? :sync_back and $config[:sync_back_to_maildir] and source.sync_back_enabled?
+  end
+
   ## much faster than raw_message
   def each_raw_message_line &b
     source.each_raw_message_line info, &b