commit 2faf46026d3d7ba637718d5d1e34ceef845652f1
parent 9ec08ed5fc47ffb65e3dceb9ab25334c380abe3c
Author: wmorgan <wmorgan@5c8cc53c-5e98-4d25-b20a-d8db53a31250>
Date: Wed, 30 May 2007 17:43:30 +0000
better yamlication (and misc comment tweaks)
git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@423 5c8cc53c-5e98-4d25-b20a-d8db53a31250
Diffstat:
11 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/doc/TODO b/doc/TODO
@@ -1,5 +1,6 @@
for 0.0.9
---------
+_ add arbitrary labels to sources
_ detect other sup instances and do something intelligent (because ferret crashes violently with more than one index writer open)
_ bugfix: need a way to force an address to a particular name, for things like evite addresses
_ bugfix: read before thread-index has finished loading then hides the thread?!? wtf. (on jamie)
diff --git a/lib/sup.rb b/lib/sup.rb
@@ -12,6 +12,24 @@ 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.8"
@@ -50,20 +68,6 @@ module Redwood
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 }
@@ -142,7 +146,7 @@ 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
diff --git a/lib/sup/draft.rb b/lib/sup/draft.rb
@@ -42,6 +42,7 @@ end
class DraftLoader < Source
attr_accessor :dir
+ yaml_properties :cur_offset
def initialize cur_offset=0
dir = Redwood::DRAFT_DIR
@@ -119,6 +120,4 @@ private
end
end
-Redwood::register_yaml(DraftLoader, %w(cur_offset))
-
end
diff --git a/lib/sup/imap.rb b/lib/sup/imap.rb
@@ -35,7 +35,8 @@ require 'rmail'
## of the spec actually happens in practice. you'll request flags for
## one message, and get it interspersed with a random bunch of flags
## for some other messages, including a different set of flags for the
-## same message! totally ok by the imap spec. totally retarded.
+## same message! totally ok by the imap spec. totally retarded by any
+## other metric.
##
## fuck you, imap committee. you managed to design something nearly as
## shitty as mbox but goddamn THIRTY YEARS LATER.
@@ -48,6 +49,8 @@ class IMAP < Source
RECOVERABLE_ERRORS = [ Errno::EPIPE, Errno::ETIMEDOUT, OpenSSL::SSL::SSLError ]
attr_accessor :username, :password
+ yaml_properties :uri, :username, :password, :cur_offset, :usual,
+ :archived, :id
def initialize uri, username, password, last_idate=nil, usual=true, archived=false, id=nil
raise ArgumentError, "username and password must be specified" unless username && password
@@ -282,6 +285,4 @@ private
end
-Redwood::register_yaml(IMAP, %w(uri username password cur_offset usual archived id))
-
end
diff --git a/lib/sup/index.rb b/lib/sup/index.rb
@@ -310,7 +310,7 @@ protected
File.chmod 0600, fn
FileUtils.mv fn, bakfn, :force => true unless File.exists?(bakfn) && File.size(bakfn) > File.size(fn)
end
- Redwood::save_yaml_obj @sources.values, fn
+ Redwood::save_yaml_obj @sources.values.sort_by { |s| s.id.to_i }, fn
File.chmod 0600, fn
end
@sources_dirty = false
diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
@@ -11,6 +11,7 @@ module Redwood
class Maildir < Source
SCAN_INTERVAL = 30 # seconds
+ yaml_properties :uri, :cur_offset, :usual, :archived, :id
def initialize uri, last_date=nil, usual=true, archived=false, id=nil
super
uri = URI(uri)
@@ -122,6 +123,4 @@ private
end
end
-Redwood::register_yaml(Maildir, %w(uri cur_offset usual archived id))
-
end
diff --git a/lib/sup/mbox/loader.rb b/lib/sup/mbox/loader.rb
@@ -5,6 +5,7 @@ module Redwood
module MBox
class Loader < Source
+ yaml_properties :uri, :cur_offset, :usual, :archived, :id
def initialize uri_or_fp, start_offset=nil, usual=true, archived=false, id=nil
super
@@ -131,7 +132,5 @@ class Loader < Source
end
end
-Redwood::register_yaml(Loader, %w(uri cur_offset usual archived id))
-
end
end
diff --git a/lib/sup/mbox/ssh-loader.rb b/lib/sup/mbox/ssh-loader.rb
@@ -6,6 +6,9 @@ module MBox
class SSHLoader < Source
attr_accessor :username, :password
+ yaml_properties :uri, :username, :password, :cur_offset, :usual,
+ :archived, :id
+
def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil
raise ArgumentError, "not an mbox+ssh uri: #{uri.inspect}" unless uri =~ %r!^mbox\+ssh://!
@@ -66,7 +69,5 @@ class SSHLoader < Source
end
end
-Redwood::register_yaml(SSHLoader, %w(uri username password cur_offset usual archived id))
-
end
end
diff --git a/lib/sup/sent.rb b/lib/sup/sent.rb
@@ -30,6 +30,8 @@ class SentManager
end
class SentLoader < MBox::Loader
+ yaml_properties :cur_offset
+
def initialize cur_offset=0
filename = Redwood::SENT_FN
File.open(filename, "w") { } unless File.exists? filename
@@ -42,6 +44,4 @@ class SentLoader < MBox::Loader
def labels; [:sent, :inbox]; end
end
-Redwood::register_yaml(SentLoader, %w(cur_offset))
-
end
diff --git a/lib/sup/source.rb b/lib/sup/source.rb
@@ -5,15 +5,15 @@ class OutOfSyncSourceError < SourceError; end
class FatalSourceError < SourceError; end
class Source
- ## Implementing a new source is typically quite easy, because Sup
- ## only needs to be able to:
+ ## Implementing a new source should be easy, because Sup only needs
+ ## to be able to:
## 1. See how many messages it contains
## 2. Get an arbitrary message
## 3. (optional) see whether the source has marked it read or not
##
## In particular, Sup doesn't need to move messages, mark them as
- ## read, delete them, or anything else. (Well, at some point it will
- ## need to delete them, but that will be an optional capability.)
+ ## read, delete them, or anything else. (Well, it's nice to be able
+ ## to delete them, but that is optional.)
##
## On the other hand, Sup assumes that you can assign each message a
## unique integer id, such that newer messages have higher ids than
@@ -33,7 +33,8 @@ class Source
## - raw_header offset
## - raw_full_message offset
## - check
- ## - next (or each, if you prefer)
+ ## - next (or each, if you prefer): should return a message and an
+ ## array of labels.
##
## ... where "offset" really means unique id. (You can tell I
## started with mbox.)
@@ -46,7 +47,7 @@ class Source
## else (e.g. the imap server is down or the maildir is missing.)
##
## Finally, be sure the source is thread-safe, since it WILL be
- ## pummeled from multiple threads at once.
+ ## pummelled from multiple threads at once.
##
## Examples for you to look at: mbox/loader.rb, imap.rb, and
## maildir.rb.
@@ -97,6 +98,4 @@ protected
end
end
-Redwood::register_yaml(Source, %w(uri cur_offset usual archived id))
-
end
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -344,6 +344,10 @@ end
## h2[:a].val # => 0
## h2[:a].val = 1
## h2[:a].val # => 1
+##
+## important note: you REALLY want to use #member? to test existence,
+## because just checking h[anything] will always evaluate to true
+## (except for degenerate constructor blocks that return nil or false)
class SavingHash
def initialize &b
@constructor = b