6 class SSHLoader < Source
7 attr_accessor :username, :password
9 yaml_properties :uri, :username, :password, :cur_offset, :usual,
10 :archived, :id, :labels
12 def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil, labels=[]
13 raise ArgumentError, "not an mbox+ssh uri: #{uri.inspect}" unless uri =~ %r!^mbox\+ssh://!
15 super uri, start_offset, usual, archived, id
17 @parsed_uri = URI(uri)
21 @cur_offset = start_offset
22 @labels = (labels || []).freeze
25 opts[:username] = @username if @username
26 opts[:password] = @password if @password
28 @f = SSHFile.new host, filename, opts
29 @loader = Loader.new @f, start_offset, usual, archived, id
31 ## heuristic: use the filename as a label, unless the file
32 ## has a path that probably represents an inbox.
35 def self.suggest_labels_for path; Loader.suggest_labels_for(path) end
37 def connect; safely { @f.connect }; end
38 def host; @parsed_uri.host; end
39 def filename; @parsed_uri.path[1..-1] end
43 offset, labels = @loader.next
44 self.cur_offset = @loader.cur_offset # superclass keeps @cur_offset which is used by yaml
45 [offset, (labels + @labels).uniq] # add our labels
53 def cur_offset= o; @cur_offset = @loader.cur_offset = o; @dirty = true; end
54 def id; @loader.id; end
55 def id= o; @id = @loader.id = o; end
56 # def cur_offset; @loader.cur_offset; end # think we'll be ok without this
57 def to_s; @parsed_uri.to_s; end
62 rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError, IOError => e
63 m = "error communicating with SSH server #{host} (#{e.class.name}): #{e.message}"
64 raise FatalSourceError, m
68 [:start_offset, :load_header, :load_message, :raw_header, :raw_message].each do |meth|
69 define_method(meth) { |*a| safely { @loader.send meth, *a } }