]> git.cworth.org Git - sup/blobdiff - lib/sup.rb
bugfix: save_yaml_obj safe=true filename
[sup] / lib / sup.rb
index a4fd388b8619bac4d81c6dc3ad0c7d5752baef89..b07ee411197cdab78499438a042a1038baac2bcd 100644 (file)
@@ -12,8 +12,26 @@ class Object
   end
 end
 
+class Module
+  def yaml_properties *props
+    props = props.map { |p| p.to_s }
+    vars = props.map { |p| "@#{p}" }
+    klass = self
+    path = klass.name.gsub(/::/, "/")
+    
+    klass.instance_eval do
+      define_method(:to_yaml_properties) { vars }
+      define_method(:to_yaml_type) { "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}" }
+    end
+
+    YAML.add_domain_type("#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}", path) do |type, val|
+      klass.new(*props.map { |p| val[p] })
+    end
+  end
+end
+
 module Redwood
-  VERSION = "0.0.7"
+  VERSION = "0.0.8"
 
   BASE_DIR   = ENV["SUP_BASE"] || File.join(ENV["HOME"], ".sup")
   CONFIG_FN  = File.join(BASE_DIR, "config.yaml")
@@ -23,6 +41,8 @@ module Redwood
   CONTACT_FN = File.join(BASE_DIR, "contacts.txt")
   DRAFT_DIR  = File.join(BASE_DIR, "drafts")
   SENT_FN    = File.join(BASE_DIR, "sent.mbox")
+  LOCK_FN    = File.join(BASE_DIR, "lock")
+  SUICIDE_FN = File.join(BASE_DIR, "please-kill-yourself")
 
   YAML_DOMAIN = "masanjin.net"
   YAML_DATE = "2006-10-01"
@@ -30,39 +50,32 @@ module Redwood
 ## record exceptions thrown in threads nicely
   $exception = nil
   def reporting_thread
-    ::Thread.new do
-      begin
-        yield
-      rescue Exception => e
-        File.open("sup-exception-log.txt", "w") do |f|
-          f.puts "--- #{e.class.name} at #{Time.now}"
-          f.puts e.message, e.backtrace
+    if $opts[:no_threads]
+      yield
+    else
+      ::Thread.new do
+        begin
+          yield
+        rescue Exception => e
+          File.open("sup-exception-log.txt", "w") do |f|
+            f.puts "--- #{e.class.name} at #{Time.now}"
+            f.puts e.message, e.backtrace
+          end
+          $exception ||= e
+          raise
         end
-        $exception ||= e
-        raise
       end
     end
   end
   module_function :reporting_thread
 
 ## one-stop shop for yamliciousness
-  def register_yaml klass, props
-    vars = props.map { |p| "@#{p}" }
-    path = klass.name.gsub(/::/, "/")
-    
-    klass.instance_eval do
-      define_method(:to_yaml_properties) { vars }
-      define_method(:to_yaml_type) { "!#{YAML_DOMAIN},#{YAML_DATE}/#{path}" }
-    end
-
-    YAML.add_domain_type("#{YAML_DOMAIN},#{YAML_DATE}", path) do |type, val|
-      klass.new(*props.map { |p| val[p] })
-    end
-  end
-
-  def save_yaml_obj object, fn, compress=false
-    if compress
-      Zlib::GzipWriter.open(fn) { |f| f.puts object.to_yaml }
+  def save_yaml_obj object, fn, safe=false
+    if safe
+      safe_fn = "#{File.dirname fn}/safe_#{File.basename fn}"
+      mode = File.stat(fn) if File.exists? fn
+      File.open(safe_fn, "w", mode) { |f| f.puts object.to_yaml }
+      FileUtils.mv safe_fn, fn
     else
       File.open(fn, "w") { |f| f.puts object.to_yaml }
     end
@@ -87,21 +100,24 @@ module Redwood
     Redwood::DraftManager.new Redwood::DRAFT_DIR
     Redwood::UpdateManager.new
     Redwood::PollManager.new
+    Redwood::SuicideManager.new Redwood::SUICIDE_FN
   end
 
   def finish
-    Redwood::LabelManager.save
-    Redwood::ContactManager.save
-    Redwood::PersonManager.save
+    Redwood::PollManager.stop
+    Redwood::LabelManager.save if Redwood::LabelManager.instantiated?
+    Redwood::ContactManager.save if Redwood::ContactManager.instantiated?
+    Redwood::PersonManager.save if Redwood::PersonManager.instantiated?
+    Redwood::BufferManager.deinstantiate! if Redwood::BufferManager.instantiated?
   end
 
   ## not really a good place for this, so I'll just dump it here.
-  def report_broken_sources
+  def report_broken_sources opts={}
     return unless BufferManager.instantiated?
 
     broken_sources = Index.usual_sources.select { |s| s.error.is_a? FatalSourceError }
     unless broken_sources.empty?
-      BufferManager.spawn "Broken source notification", TextMode.new(<<EOM)
+      BufferManager.spawn "Broken source notification", TextMode.new(<<EOM), opts
 Source error notification
 -------------------------
 
@@ -109,14 +125,14 @@ Hi there. It looks like one or more message sources is reporting
 errors. Until this is corrected, messages from these sources cannot
 be viewed, and new messages will not be detected.
 
-#{broken_sources.map { |s| "Source: " + s.to_s + "\n Error: " + s.error.message.wrap(70).join("\n        ")}.join('\n\n')}
+#{broken_sources.map { |s| "Source: " + s.to_s + "\n Error: " + s.error.message.wrap(70).join("\n        ")}.join("\n\n")}
 EOM
 #' stupid ruby-mode
     end
 
     desynced_sources = Index.usual_sources.select { |s| s.error.is_a? OutOfSyncSourceError }
     unless desynced_sources.empty?
-      BufferManager.spawn("Out-of-sync source notification", TextMode.new(<<EOM))
+      BufferManager.spawn "Out-of-sync source notification", TextMode.new(<<EOM), opts
 Out-of-sync source notification
 -------------------------------
 
@@ -137,24 +153,36 @@ EOM
     end
   end
 
-  module_function :register_yaml, :save_yaml_obj, :load_yaml_obj, :start, :finish, :report_broken_sources
+  module_function :save_yaml_obj, :load_yaml_obj, :start, :finish,
+                  :report_broken_sources
 end
 
 ## set up default configuration file
 if File.exists? Redwood::CONFIG_FN
   $config = Redwood::load_yaml_obj Redwood::CONFIG_FN
 else
+  require 'etc'
+  require 'socket'
+  name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first
+  email = ENV["USER"] + "@" + 
+    begin
+      Socket.gethostbyname(Socket.gethostname).first
+    rescue SocketError
+      Socket.gethostname
+    end
+
   $config = {
     :accounts => {
       :default => {
-        :name => "Your Name Here",
-        :email => "your.email.here@domain.tld",
+        :name => name,
+        :email => email,
         :alternates => [],
         :sendmail => "/usr/sbin/sendmail -oem -ti",
         :signature => File.join(ENV["HOME"], ".signature")
       }
     },
-    :editor => ENV["EDITOR"] || "/usr/bin/vi",
+    :editor => ENV["EDITOR"] || "/usr/bin/vim -f -c 'setlocal spell spelllang=en_us' -c 'set filetype=mail'",
+    :thread_by_subject => false,
   }
   begin
     FileUtils.mkdir_p Redwood::BASE_DIR
@@ -166,6 +194,7 @@ end
 
 require "sup/util"
 require "sup/update"
+require "sup/suicide"
 require "sup/message"
 require "sup/source"
 require "sup/mbox"