]> gitweb.michael.orlitzky.com - mailshears.git/blobdiff - lib/common/plugin.rb
Use semantic bound on pg library.
[mailshears.git] / lib / common / plugin.rb
index 0687989fe03169e3aa2e4d9c256f30bf9cbe8b67..702b621ff5da9c1ee18ccbd0fd29352950a63386 100644 (file)
+require 'common/domain'
+require 'common/user'
+
 # All plugins should include this module. It defines the basic
 # operations that all plugins are supposed to support.
 module Plugin
 
-  def Plugin.included(c)
-    # Callback, called whenever another class or module includes this
-    # one. The parameter given is the name of the class or module
-    # that included us.
-    @includers ||= []
-    @includers << c
+  module Run
+    # Module methods, meant to be extended. Includers can explicitly
+    # extend this to get a run() method defined in terms of their own
+    # runner() and dummy_runner() methods.
+
+    def included(c)
+      # Callback, called whenever another class or module includes this
+      # one. The parameter given is the name of the class or module
+      # that included us.
+      @includers ||= []
+      @includers << c
+    end
+
+    def includers
+      @includers ||= []
+      return @includers
+    end
+
+    def runner()
+      # The Runner associated with this plugin.
+      raise NotImplementedError
+    end
+
+    def dummy_runner()
+      # The DummyRunner associated with this plugin.
+      raise NotImplementedError
+    end
+
+    def run(cfg, *args)
+      includers().each do |includer|
+        plugin = includer.new(cfg)
+
+        if cfg.i_mean_business then
+          runner = runner().new()
+        else
+          runner = dummy_runner().new()
+        end
+
+        # The splat passes the correct (we hope) number of arguments to the
+        # appropriate runner. The Rm(Dummy)Runner have splats on their
+        # *target arguments as well, to turn ARGV back into an array.
+        runner.run(plugin, *args)
+      end
+    end
   end
 
-  def Plugin.includers
-    return @includers
+  def describe(target)
+    # A generic version of describe_user/describe_domain that
+    # dispatches base on the class of the target.
+    if target.is_a?(User)
+      if user_exists(target) then
+        return describe_user(target)
+      else
+        return 'User not found'
+      end
+    elsif target.is_a?(Domain)
+      if domain_exists(target) then
+        return describe_domain(target)
+      else
+        return 'Domain not found'
+      end
+    else
+      raise NotImplementedError
+    end
   end
 
   def describe_domain(domain)
-    # Provide a "description" of the domain. This is output along
-    # with the domain name and can be anything of use to the system
-    # administrator.
-    raise NotImplementedError
+    # Provide a "description" of the domain. This is output along with
+    # the domain name and can be anything of use to the system
+    # administrator. The default doesn't do anything useful and should
+    # be overridden.
+    return domain.to_s()
   end
 
-  def describe_account(account)
-    # Provide a "description" of the account. This is output along
+  def describe_user(user)
+    # Provide a "description" of the user. This is output along
     # with the domain name and can be anything of use to the system
-    # administrator.
+    # administrator. The default doesn't do anything useful and should
+    # be overridden.
+    return user.to_s()
+  end
+
+  def list_users()
+    # Return a list of all users managed by this plugin.
     raise NotImplementedError
   end
 
+  def list_domains()
+    # Compute the domains from a list of users. Obviously much worse
+    # than getting the domains the "smart" way, if such a way exists.
+    users = list_users()
+    domains = users.map{ |u| u.domain() }
+    return domains.uniq()
+  end
+
+  def user_exists(user)
+    # Does the given username exist for this plugin? We use a naive
+    # implementation here based on list_users() which is required to
+    # exist above. Plugins can override this with something fast.
+    users = list_users()
+    return users.include?(user)
+  end
+
+  def domain_exists(domain)
+    # Does the given domain exist for this plugin? We use a naive
+    # implementation here based on list_domains() which is required to
+    # exist above. Plugins can override this with something fast.
+    domains = list_domains()
+    return domains.include?(domain)
+  end
+
+  def list_domains_users(domains)
+    # Get all users belonging to the given domains. If a user has
+    # domainpart "example.com" then it belongs to the domain
+    # "example.com".
+    #
+    # This uses a naive loop, but relies only on the existence of a
+    # list_users() method which is guaranteed above. More efficient
+    # implementations can usually be made within the plugin.
+    domains_users = []
+
+    users = list_users();
+    domains.each do |d|
+      matches = users.select do |user|
+        user.domainpart() == d.to_s()
+      end
+
+      domains_users += matches
+    end
+
+    return domains_users
+  end
+
 end