First round of modernizing after a long absence.

Much work to be done.
This commit is contained in:
Mahlon E. Smith 2017-02-01 15:35:35 -08:00
parent 0c8f66ac29
commit 3f96c8bb0f
21 changed files with 556 additions and 2054 deletions

View file

@ -1,39 +1,29 @@
#!/usr/bin/ruby
# vim: set nosta noet ts=4 sw=4:
#
# A Ruby interface to a single Ezmlm-idx mailing list directory
# A Ruby interface to a single Ezmlm-idx mailing list directory.
#
# == Version
#
# $Id$
#
# == Authors
#
# * Michael Granger <mgranger@laika.com>
# * Jeremiah Jordan <jjordan@laika.com>
#
# :include: LICENSE
#
#---
#
# Please see the file LICENSE in the base directory for licensing details.
#
require 'pathname'
require 'ezmlm'
require 'tmail'
require 'mail'
### A Ruby interface to an ezmlm-idx mailing list directory
###
class Ezmlm::List
### Create a new Ezmlm::List object for the specified +listdir+, which should be
### an ezmlm-idx mailing list directory.
###
def initialize( listdir )
listdir = Pathname.new( listdir ) if !listdir.is_a?( Pathname )
listdir = Pathname.new( listdir ) unless listdir.is_a?( Pathname )
@listdir = listdir
# Cached lookups
@config = nil
end
@ -49,20 +39,20 @@ class Ezmlm::List
def name
return self.config[ 'L' ]
end
### Return the configured host of the list
def host
return self.config[ 'H' ]
end
### Return the configured address of the list (in list@host form)
def address
return "%s@%s" % [ self.name, self.host ]
end
alias_method :fullname, :address
### Return the number of messages in the list archive
def message_count
@ -91,23 +81,23 @@ class Ezmlm::List
unless @config
configfile = self.listdir + 'config'
raise "List config file %p does not exist" % [ configfile ] unless configfile.exist?
@config = configfile.read.scan( /^(\S):([^\n]*)$/m ).inject({}) do |h,pair|
key,val = *pair
h[key] = val
h
end
end
return @config
end
### Return the email address of the list's owner.
def owner
self.config['5']
end
### Fetch an Array of the email addresses for all of the list's subscribers.
def subscribers
@ -132,10 +122,10 @@ class Ezmlm::List
### of a closed list.
def subscription_moderators
return [] unless self.closed?
modsubfile = self.listdir + 'modsub'
remotefile = self.listdir + 'remote'
subdir = nil
if modsubfile.exist? && modsubfile.read(1) == '/'
subdir = Pathname.new( modsubfile.read.chomp )
@ -144,29 +134,29 @@ class Ezmlm::List
else
subdir = self.listdir + 'mod/subscribers'
end
return self.read_subscriber_dir( subdir )
end
### Returns an Array of email addresses of people responsible for moderating posts
### sent to the list.
def message_moderators
return [] unless self.moderated?
modpostfile = self.listdir + 'modpost'
subdir = nil
if modpostfile.exist? && modpostfile.read(1) == '/'
subdir = Pathname.new( modpostfile.read.chomp )
else
subdir = self.listdir + 'mod/subscribers'
end
return self.read_subscriber_dir( subdir )
end
### Return a TMail::Mail object loaded from the last post to the list. Returns
### +nil+ if there are no archived posts.
def last_post
@ -189,25 +179,23 @@ class Ezmlm::List
last_post = TMail::Mail.load( last_post_path.to_s )
end
#########
protected
#########
### Read the hashed subscriber email addresses from the specified +directory+ and return them in
### Read the hashed subscriber email addresses from the specified +directory+ and return them in
### an Array.
def read_subscriber_dir( directory )
rval = []
Pathname.glob( directory + '*' ) do |hashfile|
rval.push( hashfile.read.scan(/T([^\0]+)\0/) )
end
return rval.flatten
end
end
# vim: set nosta noet ts=4 sw=4:
end # class Ezmlm::List

View file

@ -1,153 +0,0 @@
#!/usr/bin/ruby
#
# A DRb interface to one or more ezmlm-idx mailing lists.
#
# == Version
#
# $Id$
#
# == Authors
#
# * Michael Granger <mgranger@laika.com>
# * Jeremiah Jordan <jjordan@laika.com>
#
# :include: LICENSE
#
#---
#
# Please see the file LICENSE in the base directory for licensing details.
#
require 'pathname'
require 'ezmlm'
require 'ezmlm/list'
require 'drb'
require 'ostruct'
### A DRb interface to one or more ezmlm-idx mailing lists
class Ezmlm::ListDaemon
# The default port to listen on
DEFAULT_PORT = 32315
# The default address to bind to
DEFAULT_ADDRESS = '127.0.0.1'
### The interface that is presented to DRb
class Service
include Enumerable
### Create a new service endpoint for the specified +listsdir+, which is a directory
### which contains ezmlm-idx list directories.
def initialize( listsdir )
listsdir = Pathname.new( listsdir )
@listsdir = listsdir
end
######
public
######
# The directory which contains the list directories that should be served.
attr_reader :listsdir
### Create a new Ezmlm::List object for the list directory with the specified +name+.
def get_list( name )
name = validate_listdir_name( name )
return Ezmlm::List.new( self.listsdir + name )
end
### Iterate over each current list in the Service's listsdir, yielding an Ezmlm::List object
### for each one.
def each_list( &block ) # :yields: list_object
Ezmlm.each_list( self.listsdir, &block )
end
alias_method :each, :each_list
#######
private
#######
VALID_LISTNAME_PATTERN = /^[a-z0-9.-]+$/i
### Ensure that the given +name+ is a valid list name, raising an exception if not. Returns
### an untainted copy of +name+.
def validate_listdir_name( name )
unless match = VALID_LISTNAME_PATTERN.match( name )
raise ArgumentError, "invalid list name %p" % [ name ]
end
return match[0].untaint
end
end # class Service
### Return an OpenStruct that contains the default options
def self::default_options
opts = OpenStruct.new
opts.bind_addr = DEFAULT_ADDRESS
opts.bind_port = DEFAULT_PORT
opts.debugmode = false
opts.helpmode = false
opts.foreground = false
return opts
end
#################################################################
### I N S T A N C E M E T H O D S
#################################################################
### Create a new Ezmlm::ListDaemon that will serve objects for the list directories
### contained in +listsdir+. The +options+ argument, if given, is an object (such as the one
### returned from ::default_options) that contains values for the following methods:
###
### bind_addr::
### The address to bind to. Defaults to DEFAULT_ADDRESS.
### bind_port::
### The port to listen on. Defaults to DEFAULT_PORT.
### debugmode::
### Whether to run in debugging mode, which causes the daemon to run in the foreground
### and send any output to STDERR. Defaults to +false+.
### foreground::
### Don't go into the background.
def initialize( listsdir, options=nil )
@service = Service.new( listsdir )
@options = options || self.class.default_options
end
######
public
######
# The daemon's configuration options
attr_reader :options
# The Ezmlm::ListDaemon::Service object that serves as the DRb interface
attr_reader :service
### Daemonize unless configured otherwise, start the DRb service and return the listening
### Thread object
def start
uri = "druby://%s:%d" % [ self.options.bind_addr, self.options.bind_port ]
DRb.start_service( uri, @service )
return DRb.thread
end
end # class Ezmlm::ListDaemon
# vim: set nosta noet ts=4 sw=4: