#! @PYTHON@
# 
# Copyright (C) 2002 by the Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software 
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
"""Python script to re-generate the htdig archive search files. Read 
INSTALL.htdig-mm to determine if you should be running this script.

This script has to be edited before use to provide a value for the
configuration parameter MAILMAN_PATH. The value should be the path 
to Mailman's installation directory as seen by the script.

This script should normally be run nightly from cron.  When run from the
command line, the following usage is understood:

Usage: %(program)s [-v] [-h] [listnames]

Where:
    --verbose / -v
        print each list as htdig is run for it

    --help / -h
        print this message and exit

    listnames
        Optionally, only runs htdig for the named lists.  Without 
        this, all archivable lists are processed.

"""

# this code was derived from the nightly_gzip cron script

MAILMAN_PATH = ''

import sys
import os
from stat import *
import time
import getopt
import string
from types import *
import errno

import urllib, urlparse
import paths

program = sys.argv[0]

def usage(code, msg=''):
    print >> sys.stderr, _( __doc__)
    if msg:
        print msg
    sys.exit(code)

def main():
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'vhm', ['verbose', 'help'])
    except getopt.error, msg:
        usage(1, msg)
    # defaults
    verbose = 0
    for opt, arg in opts:
        if opt in ('-h', '--help'):
            usage(0)
        elif opt in ('-v', '--verbose'):
            verbose = 1
    # limit to the specified lists?
    if args:
        listnames = map(string.lower, args)
    else:
        listnames = Utils.list_names()
    # process all the specified lists
    for name in listnames:
        mlist = MailList.MailList(name, lock=0)
        if not mlist.archive:
            continue
        archive_dir = os.path.join(mm_cfg.REMOTE_PRIVATE_ARCHIVE_FILE_DIR,
                                   name + '/')
        try:
            os.listdir(archive_dir)
        except os.error:
            # has the list received any messages?  if not, last_post_time 
            # will be zero, so it's not really a bogus archive dir.
            if mlist.last_post_time > 0:
                print _(
                     'List %(name)s has a bogus archive dir: %(archive_dir)s')
            continue
        # check htdig has been set up for this list and skip it if not
        list_htdig_dir = os.path.join(archive_dir, 'htdig')
        if not os.path.exists(list_htdig_dir):
            if verbose:
                print _(
		  'Skipping remote htdig for list; nno htdig setup: %(name)s')
            continue
        # check if there have been any archive files created since we
        # last ran htdig and skip list if not. well actually we only
        # test if the archive volume directories mod times have changed        
        recent_posts = None
        rundig_run_file = os.path.join(list_htdig_dir, 'rundig_last_run')
        archive = HyperArch.HyperArchive(mlist)
        try:      
            last_rundig_time = os.stat(rundig_run_file)[ST_MTIME]
        except OSError, e:
            if e.errno <> errno.ENOENT: raise
            open(rundig_run_file, 'w').close()
            recent_posts = 1
        else:
            for volume in archive.archives:
                archive_name = os.path.join(archive_dir, volume)
                last_archive_change = os.stat(archive_name)[ST_MTIME]
                if last_archive_change > last_rundig_time:
                    recent_posts = 1
                    break
        if not recent_posts:
            if verbose:
                print _('Skipping htdig for list; no recent posts: %(name)s')
            continue
        # ok, so running htdig is worthwhile
        if verbose:
            print _("htdig'ing archive of list: %(name)s")
        htdig_conf_file = os.path.join(list_htdig_dir, name + '.conf')
        cmd = '%s -c %s' % (mm_cfg.HTDIG_RUNDIG_PATH, htdig_conf_file)
        status = (os.system(cmd) >> 8) & 0xff
        if status:
            print _('rundig failed for list %(name)s, exit code: %(status)s')
        else:
            os.utime(rundig_run_file, None)

if __name__ == '__main__' and os.path.exists(MAILMAN_PATH):
    # Access the mailman installation
    sys.path = [MAILMAN_PATH] + sys.path
    from Mailman import MailList
    from Mailman import Utils
    from Mailman import mm_cfg
    from Mailman.Archiver import HyperArch
    from Mailman.i18n import _
    if mm_cfg.USE_HTDIG and \
       mm_cfg.ARCHIVE_TO_MBOX in (0, 2) and \
       os.path.exists(mm_cfg.HTDIG_RUNDIG_PATH):
        # we're only going to run the nightly rundig if messages are archived to
        # the internal archiver, we are using htdig to provide archive search
        # and we know where rundig is.
        omask = os.umask(002)
        try:
            main()
        finally:
            os.umask(omask)
else:
    print  'Invalid configuration variables'  
    print  'Edit this script in accordance with INSTALL.htdig-mm'
