#! @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.
#
"""Re-generate the htdig archive search files.

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

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

    --help / -h
        print this message and exit

"""

# this code was derived from the nightly_gzip cron script

import sys
import os
from stat import *
import time
from types import *
import getopt
import paths
import errno
from Mailman import MailList
from Mailman import Utils
from Mailman import mm_cfg
from Mailman.Archiver import HyperArch
from Mailman.i18n import _

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:], 'vh', ['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 = 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 = mlist.archive_dir()
        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 htdig for list; no 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)
            archive.write_TOC()

if __name__ == '__main__' and \
   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)
