#! @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 values for the
configuration parameters REMOTE_PRIVATE_ARCHIVE_FILE_DIR and
HTDIG_RUNDIG_PATH. The values should be the same as those acquired by
other of Mailman's python code from $prefix/Mailman/Defaults.py or 
overridden in $prefix/Mailman/mm_cfg.py.

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

REMOTE_PRIVATE_ARCHIVE_FILE_DIR = ''
HTDIG_RUNDIG_PATH = ''

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

program = sys.argv[0]

def usage(code, msg=''):
    print __doc__ % globals()
    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 = filter(lambda m: m[-5:] != '.mbox',
                           os.listdir(REMOTE_PRIVATE_ARCHIVE_FILE_DIR))
    # process all the specified lists
    listnames.sort()
    for name in listnames:
        archive_dir = os.path.join(REMOTE_PRIVATE_ARCHIVE_FILE_DIR, name)
        # check if this list has an archive and skip it if not
        if not os.path.exists(archive_dir):
            if verbose:
                print 'Skipping remote htdig for list', name, 'no archive'
            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', name, 'no htdig setup'
            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')
        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 os.listdir(archive_dir):
                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', name, 'no recent posts'
            continue
        # ok, so running htdig is worthwhile
        if verbose:
            print "htdig'ing archive of list", name
        htdig_conf_file = os.path.join(list_htdig_dir, name + '.conf')
        cmd = '%s -c %s' % (HTDIG_RUNDIG_PATH, htdig_conf_file)
        status = (os.system(cmd) >> 8) & 0xff
        if status:
            print 'rundig failed for list %s, exit code: %s' % (name, status)
        else:
            os.utime(rundig_run_file, None)

if __name__ == '__main__' and \
   os.path.exists(REMOTE_PRIVATE_ARCHIVE_FILE_DIR) and \
   os.path.exists(HTDIG_RUNDIG_PATH):
    # we're only going to run the nightly rundig if we have a sensible
    # set of configuration variables 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"


