]> git.cworth.org Git - sup/blobdiff - lib/sup/mbox/ssh-loader.rb
Merge branch 'sup-sync-improvements' into next
[sup] / lib / sup / mbox / ssh-loader.rb
index 6a41900ff9c5103ec3f9da83747d14ee9899da85..e422a481b5c3a5639ac023d0aa264b30509f465d 100644 (file)
@@ -3,35 +3,72 @@ require 'net/ssh'
 module Redwood
 module MBox
 
-class SSHLoader < Loader
-  def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil
-    raise ArgumentError, "not an mbox+ssh uri" unless uri =~ %r!^mbox\+ssh://!
+class SSHLoader < Source
+  attr_accessor :username, :password
+
+  yaml_properties :uri, :username, :password, :cur_offset, :usual, 
+                  :archived, :id, :labels
+
+  def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil, labels=[]
+    raise ArgumentError, "not an mbox+ssh uri: #{uri.inspect}" unless uri =~ %r!^mbox\+ssh://!
+
+    super uri, start_offset, usual, archived, id
 
     @parsed_uri = URI(uri)
     @username = username
     @password = password
-    @f = nil
+    @uri = uri
+    @cur_offset = start_offset
+    @labels = (labels || []).freeze
 
     opts = {}
     opts[:username] = @username if @username
     opts[:password] = @password if @password
     
     @f = SSHFile.new host, filename, opts
-    super @f, start_offset, usual, archived, id
-    @uri = uri
+    @loader = Loader.new @f, start_offset, usual, archived, id
+    
     ## heuristic: use the filename as a label, unless the file
     ## has a path that probably represents an inbox.
-    @labels << File.basename(filename).intern unless File.dirname(filename) =~ /\b(var|usr|spool)\b/
   end
 
+  def self.suggest_labels_for path; Loader.suggest_labels_for(path) end
+
+  def connect; safely { @f.connect }; end
   def host; @parsed_uri.host; end
-  def filename; @parsed_uri.path[1..-1] end ##XXXX TODO handle nil
+  def filename; @parsed_uri.path[1..-1] end
+
+  def next
+    safely do
+      offset, labels = @loader.next
+      self.cur_offset = @loader.cur_offset # superclass keeps @cur_offset which is used by yaml
+      [offset, (labels + @labels).uniq] # add our labels
+    end
+  end
+
+  def end_offset
+    safely { @f.size }
+  end
 
-  def end_offset; @f.size; end
+  def cur_offset= o; @cur_offset = @loader.cur_offset = o; @dirty = true; end
+  def id; @loader.id; end
+  def id= o; @id = @loader.id = o; end
+  # def cur_offset; @loader.cur_offset; end # think we'll be ok without this
   def to_s; @parsed_uri.to_s; end
-end
 
-Redwood::register_yaml(SSHLoader, %w(uri username password cur_offset usual archived id))
+  def safely
+    begin
+      yield
+    rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError, IOError => e
+      m = "error communicating with SSH server #{host} (#{e.class.name}): #{e.message}"
+      raise FatalSourceError, m
+    end
+  end
+
+  [:start_offset, :load_header, :load_message, :raw_header, :raw_message].each do |meth|
+    define_method(meth) { |*a| safely { @loader.send meth, *a } }
+  end
+end
 
 end
 end