#! @PYTHON@
#
# Copyright (C) 1998,1999,2000,2001,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.

"""Invoked by cron, this checks for pending moderation requests and mails the
list moderators if necessary.
"""

import sys
import time
from types import UnicodeType

import paths

# Import this after paths so we get Mailman's copy of the email package
from email.Charset import Charset

from Mailman import mm_cfg
from Mailman import Utils
from Mailman import MailList
from Mailman import Message
from Mailman import i18n

# Work around known problems with some RedHat cron daemons
import signal
signal.signal(signal.SIGCHLD, signal.SIG_DFL)

NL = '\n'

_ = i18n._
i18n.set_language(mm_cfg.DEFAULT_SERVER_LANGUAGE)

def _isunicode(s):
    return isinstance(s, UnicodeType)



def main():
    for name in Utils.list_names():
        # the list must be locked in order to open the requests database
        mlist = MailList.MailList(name)
        try:
            count = mlist.NumRequestsPending()
            # While we're at it, let's evict yesterday's autoresponse data
            midnightToday = Utils.midnight()
            evictions = []
            for sender in mlist.hold_and_cmd_autoresponses.keys():
                date, respcount = mlist.hold_and_cmd_autoresponses[sender]
                if Utils.midnight(date) < midnightToday:
                    evictions.append(sender)
            if evictions:
                for sender in evictions:
                    del mlist.hold_and_cmd_autoresponses[sender]
                # Only here have we changed the list's database
                mlist.Save()
            if count:
                i18n.set_language(mlist.preferred_language)
                realname = mlist.real_name
                text = Utils.maketext(
                    'checkdbs.txt',
                    {'count'    : count,
                     'host_name': mlist.host_name,
                     'adminDB'  : mlist.GetScriptURL('admindb', absolute=1),
                     'real_name': realname,
                     }, mlist=mlist)
                text += '\n' + pending_requests(mlist)
                subject = _(
                    '%(count)d %(realname)s moderator request(s) waiting')
                msg = Message.UserNotification(mlist.GetOwnerEmail(),
                                               mlist.GetBouncesEmail(),
                                               subject, text,
                                               mlist.preferred_language)
                msg.send(mlist, **{'tomoderators': 1})
        finally:
            mlist.Unlock()




def pending_requests(mlist):
    # Must return a byte string
    pending = []
    first = 1
    for id in mlist.GetSubscriptionIds():
        if first:
            pending.append(_('Pending subscriptions:'))
            first = 0
        when, addr, fullname, passwd, digest, lang = mlist.GetRecord(id)
        if fullname:
            fullname = ' (%s)' % fullname
        pending.append('    %s%s %s' % (addr, fullname, time.ctime(when)))
    first = 1
    for id in mlist.GetHeldMessageIds():
        if first:
            pending.append(_('\nPending posts:'))
            first = 0
        info = mlist.GetRecord(id)
        when, sender, subject, reason, text, msgdata = mlist.GetRecord(id)
        date = time.ctime(when)
        pending.append(_("""\
From: %(sender)s on %(date)s
Subject: %(subject)s
Cause: %(reason)s"""))
        pending.append('')
    # Make sure that the text we return from here can be encoded to a byte
    # string in the charset of the list's language.  This could fail if for
    # example, the request was pended while the list's language was French,
    # but then it was changed to English before checkdbs ran.
    text = NL.join(pending)
    charset = Charset(Utils.GetCharSet(mlist.preferred_language))
    incodec = charset.input_codec or 'ascii'
    outcodec = charset.output_codec or 'ascii'
    if _isunicode(text):
        return text.encode(outcodec, 'replace')
    # Be sure this is a byte string encodeable in the list's charset
    utext = unicode(text, incodec, 'replace')
    return utext.encode(outcodec, 'replace')



if __name__ == '__main__':
    main()
