"""Generic FAQ Wizard.

This is a CGI program that maintains a user-editable FAQ.  It uses RCS
to keep track of changes to individual FAQ entries.  It is fully
configurable; everything you might want to change when using this
program to maintain some other FAQ than the Python FAQ is contained in
the configuration module, faqconf.py.

Note that this is not an executable script; it's an importable module.
The actual script to place in cgi-bin is faqw.py.

"""

import sys, string, time, os, stat, re, cgi, faqconf
from faqconf import *                   # This imports all uppercase names
now = time.time()

class FileError:
    def __init__(self, file):
        self.file = file

class InvalidFile(FileError):
    pass

class NoSuchSection(FileError):
    def __init__(self, section):
        FileError.__init__(self, NEWFILENAME %(section, 1))
        self.section = section

class NoSuchFile(FileError):
    def __init__(self, file, why=None):
        FileError.__init__(self, file)
        self.why = why

def escape(s):
    s = string.replace(s, '&', '&amp;')
    s = string.replace(s, '<', '&lt;')
    s = string.replace(s, '>', '&gt;')
    return s

def escapeq(s):
    s = escape(s)
    s = string.replace(s, '"', '&quot;')
    return s

def _interpolate(format, args, kw):
    try:
        quote = kw['_quote']
    except KeyError:
        quote = 1
    d = (kw,) + args + (faqconf.__dict__,)
    m = MagicDict(d, quote)
    return format % m

def interpolate(format, *args, **kw):
    return _interpolate(format, args, kw)

def emit(format, *args, **kw):
    try:
        f = kw['_file']
    except KeyError:
        f = sys.stdout
    f.write(_interpolate(format, args, kw))

translate_prog = None

def translate(text, pre=0):
    global translate_prog
    if not translate_prog:
        translate_prog = prog = re.compile(
            r'\b(http|ftp|https)://\S+(\b|/)|\b[-.\w]+@[-.\w]+')
    else:
        prog = translate_prog
    i = 0
    list = []
    while 1:
        m = prog.search(text, i)
        if not m:
            break
        j = m.start()
        list.append(escape(text[i:j]))
        i = j
        url = m.group(0)
        while url[-1] in '();:,.?\'"<>':
            url = url[:-1]
        i = i + len(url)
        url = escape(url)
        if not pre or (pre and PROCESS_PREFORMAT):
            if ':' in url:
                repl = '<A HREF="%s">%s</A>' % (url, url)
            else:
                repl = '<A HREF="mailto:%s">%s</A>' % (url, url)
        else:
            repl = url
        list.append(repl)
    j = len(text)
    list.append(escape(text[i:j]))
    return string.join(list, '')

def emphasize(line):
    return re.sub(r'\*([a-zA-Z]+)\*', r'<I>\1</I>', line)

revparse_prog = None

def revparse(rev):
    global revparse_prog
    if not revparse_prog:
        revparse_prog = re.compile(r'^(\d{1,3})\.(\d{1,4})$')
    m = revparse_prog.match(rev)
    if not m:
        return None
    [major, minor] = map(string.atoi, m.group(1, 2))
    return major, minor

def load_cookies():
    if not os.environ.has_key('HTTP_COOKIE'):
        return {}
    raw = os.environ['HTTP_COOKIE']
    words = map(string.strip, string.split(raw, ';'))
    cookies = {}
    for word in words:
        i = string.find(word, '=')
        if i >= 0:
            key, value = word[:i], word[i+1:]
            cookies[key] = value
    return cookies

def load_my_cookie():
    cookies = load_cookies()
    try:
        value = cookies[COOKIE_NAME]
    except KeyError:
        return {}
    import urllib
    value = urllib.unquote(value)
    words = string.split(value, '/')
    while len(words) < 3:
        words.append('')
    author = string.join(words[:-2], '/')
    email = words[-2]
    password = words[-1]
    return {'author': author,
            'email': email,
            'password': password}

def send_my_cookie(ui):
    name = COOKIE_NAME
    value = "%s/%s/%s" % (ui.author, ui.email, ui.password)
    import urllib
    value = urllib.quote(value)
    then = now + COOKIE_LIFETIME
    gmt = time.gmtime(then)
    print "Set-Cookie: %s=%s; path=/cgi-bin/;" % (name, value),
    print time.strftime("expires=%a, %d-%b-%y %X GMT", gmt)

class MagicDict:

    def __init__(self, d, quote):
        self.__d = d
        self.__quote = quote

    def __getitem__(self, key):
        for d in self.__d:
            try:
                value = d[key]
                if value:
                    value = str(value)
                    if self.__quote:
                        value = escapeq(value)
                    return value
            except KeyError:
                pass
        return ''

class UserInput:

    def __init__(self):
        self.__form = cgi.FieldStorage()

    def __getattr__(self, name):
        if name[0] == '_':
            raise AttributeError
        try:
            value = self.__form[name].value
        except (TypeError, KeyError):
            value = ''
        else:
            value = string.strip(value)
        setattr(self, name, value)
        return value

    def __getitem__(self, key):
        return getattr(self, key)

class FaqEntry:

    def __init__(self, fp, file, sec_num):
        self.file = file
        self.sec, self.num = sec_num
        if fp:
            import rfc822
            self.__headers = rfc822.Message(fp)
            self.body = string.strip(fp.read())
        else:
            self.__headers = {'title': "%d.%d. " % sec_num}
            self.body = ''

    def __getattr__(self, name):
        if name[0] == '_':
            raise AttributeError
        key = string.join(string.split(name, '_'), '-')
        try:
            value = self.__headers[key]
        except KeyError:
            value = ''
        setattr(self, name, value)
        return value

    def __getitem__(self, key):
        return getattr(self, key)

    def load_version(self):
        command = interpolate(SH_RLOG_H, self)
        p = os.popen(command)
        version = ''
        while 1:
            line = p.readline()
            if not line:
                break
            if line[:5] == 'head:':
                version = string.strip(line[5:])
        p.close()
        self.version = version

    def getmtime(self):
        if not self.last_changed_date:
            return 0
        try:
            return os.stat(self.file)[stat.ST_MTIME]
        except os.error:
            return 0

    def emit_marks(self):
        mtime = self.getmtime()
        if mtime >= now - DT_VERY_RECENT:
            emit(MARK_VERY_RECENT, self)
        elif mtime >= now - DT_RECENT:
            emit(MARK_RECENT, self)

    def show(self, edit=1):
        emit(ENTRY_HEADER1, self)
        self.emit_marks()
        emit(ENTRY_HEADER2, self)
        pre = 0
        raw = 0
        for line in string.split(self.body, '\n'):
            # Allow the user to insert raw html into a FAQ answer
            # (Skip Montanaro, with changes by Guido)
            tag = string.lower(string.rstrip(line))
            if tag == '<html>':
                raw = 1
                continue
            if tag == '</html>':
                raw = 0
                continue
            if raw:
                print line
                continue
            if not string.strip(line):
                if pre:
                    print '</PRE>'
                    pre = 0
                else:
                    print '<P>'
            else:
                if line[0] not in string.whitespace:
                    if pre:
                        print '</PRE>'
                        pre = 0
                else:
                    if not pre:
                        print '<PRE>'
                        pre = 1
                if '/' in line or '@' in line:
                    line = translate(line, pre)
                elif '<' in line or '&' in line:
                    line = escape(line)
                if not pre and '*' in line:
                    line = emphasize(line)
                print line
        if pre:
            print '</PRE>'
            pre = 0
        if edit:
            print '<P>'
            emit(ENTRY_FOOTER, self)
            if self.last_changed_date:
                emit(ENTRY_LOGINFO, self)
        print '<P>'

class FaqDir:

    entryclass = FaqEntry

    __okprog = re.compile(OKFILENAME)

    def __init__(self, dir=os.curdir):
        self.__dir = dir
        self.__files = None

    def __fill(self):
        if self.__files is not None:
            return
        self.__files = files = []
        okprog = self.__okprog
        for file in os.listdir(self.__dir):
            if self.__okprog.match(file):
                files.append(file)
        files.sort()

    def good(self, file):
        return self.__okprog.match(file)

    def parse(self, file):
        m = self.good(file)
        if not m:
            return None
        sec, num = m.group(1, 2)
        return string.atoi(sec), string.atoi(num)

    def list(self):
        # XXX Caller shouldn't modify result
        self.__fill()
        return self.__files

    def open(self, file):
        sec_num = self.parse(file)
        if not sec_num:
            raise InvalidFile(file)
        try:
            fp = open(file)
        except IOError, msg:
            raise NoSuchFile(file, msg)
        try:
            return self.entryclass(fp, file, sec_num)
        finally:
            fp.close()

    def show(self, file, edit=1):
        self.open(file).show(edit=edit)

    def new(self, section):
        if not SECTION_TITLES.has_key(section):
            raise NoSuchSection(section)
        maxnum = 0
        for file in self.list():
            sec, num = self.parse(file)
            if sec == section:
                maxnum = max(maxnum, num)
        sec_num = (section, maxnum+1)
        file = NEWFILENAME % sec_num
        return self.entryclass(None, file, sec_num)

class FaqWizard:

    def __init__(self):
        self.ui = UserInput()
        self.dir = FaqDir()

    def go(self):
        print 'Content-type: text/html'
        req = self.ui.req or 'home'
        mname = 'do_%s' % req
        try:
            meth = getattr(self, mname)
        except AttributeError:
            self.error("Bad request type %s." % `req`)
        else:
            try:
                meth()
            except InvalidFile, exc:
                self.error("Invalid entry file name %s" % exc.file)
            except NoSuchFile, exc:
                self.error("No entry with file name %s" % exc.file)
            except NoSuchSection, exc:
                self.error("No section number %s" % exc.section)
        self.epilogue()

    def error(self, message, **kw):
        self.prologue(T_ERROR)
        emit(message, kw)

    def prologue(self, title, entry=None, **kw):
        emit(PROLOGUE, entry, kwdict=kw, title=escape(title))

    def epilogue(self):
        emit(EPILOGUE)

    def do_home(self):
        self.prologue(T_HOME)
        emit(HOME)

    def do_debug(self):
        self.prologue("FAQ Wizard Debugging")
        form = cgi.FieldStorage()
        cgi.print_form(form)
        cgi.print_environ(os.environ)
        cgi.print_directory()
        cgi.print_arguments()

    def do_search(self):
        query = self.ui.query
        if not query:
            self.error("Empty query string!")
            return
        if self.ui.querytype == 'simple':
            query = re.escape(query)
            queries = [query]
        elif self.ui.querytype in ('anykeywords', 'allkeywords'):
            words = filter(None, re.split('\W+', query))
            if not words:
                self.error("No keywords specified!")
                return
            words = map(lambda w: r'\b%s\b' % w, words)
            if self.ui.querytype[:3] == 'any':
                queries = [string.join(words, '|')]
            else:
                # Each of the individual queries must match
                queries = words
        else:
            # Default to regular expression
            queries = [query]
        self.prologue(T_SEARCH)
        progs = []
        for query in queries:
            if self.ui.casefold == 'no':
                p = re.compile(query)
            else:
                p = re.compile(query, re.IGNORECASE)
            progs.append(p)
        hits = []
        for file in self.dir.list():
            try:
                entry = self.dir.open(file)
            except FileError:
                constants
            for p in progs:
                if not p.search(entry.title) and not p.search(entry.body):
                    break
            else:
                hits.append(file)
        if not hits:
            emit(NO_HITS, self.ui, count=0)
        elif len(hits) <= MAXHITS:
            if len(hits) == 1:
                emit(ONE_HIT, count=1)
            else:
                emit(FEW_HITS, count=len(hits))
            self.format_all(hits, headers=0)
        else:
            emit(MANY_HITS, count=len(hits))
            self.format_index(hits)

    def do_all(self):
        self.prologue(T_ALL)
        files = self.dir.list()
        self.last_changed(files)
        self.format_index(files, localrefs=1)
        self.format_all(files)

    def do_compat(self):
        files = self.dir.list()
        emit(COMPAT)
        self.last_changed(files)
        self.format_index(files, localrefs=1)
        self.format_all(files, edit=0)
        sys.exit(0)                     # XXX Hack to suppress epilogue

    def last_changed(self, files):
        latest = 0
        for file in files:
            entry = self.dir.open(file)
            if entry:
                mtime = mtime = entry.getmtime()
                if mtime > latest:
                    latest = mtime
        print time.strftime(LAST_CHANGED, time.localtime(latest))
        emit(EXPLAIN_MARKS)

    def format_all(self, files, edit=1, headers=1):
        sec = 0
        for file in files:
            try:
                entry = self.dir.open(file)
            except NoSuchFile:
                continue
            if headers and entry.sec != sec:
                sec = entry.sec
                try:
                    title = SECTION_TITLES[sec]
                except KeyError:
                    title = "Untitled"
                emit("\n<HR>\n<H1>%(sec)s. %(title)s</H1>\n",
                     sec=sec, title=title)
            entry.show(edit=edit)

    def do_index(self):
        self.prologue(T_INDEX)
        files = self.dir.list()
        self.last_changed(files)
        self.format_index(files, add=1)

    def format_index(self, files, add=0, localrefs=0):
        sec = 0
        for file in files:
            try:
                entry = self.dir.open(file)
            except NoSuchFile:
                continue
            if entry.sec != sec:
                if sec:
                    if add:
                        emit(INDEX_ADDSECTION, sec=sec)
                    emit(INDEX_ENDSECTION, sec=sec)
                sec = entry.sec
                try:
                    title = SECTION_TITLES[sec]
                except KeyError:
                    title = "Untitled"
                emit(INDEX_SECTION, sec=sec, title=title)
            if localrefs:
                emit(LOCAL_ENTRY, entry)
            else:
                emit(INDEX_ENTRY, entry)
            entry.emit_marks()
        if sec:
            if add:
                emit(INDEX_ADDSECTION, sec=sec)
            emit(INDEX_ENDSECTION, sec=sec)

    def do_recent(self):
        if not self.ui.days:
            days = 1
        else:
            days = string.atof(self.ui.days)
        try:
            cutoff = now - days * 24 * 3600
        except OverflowError:
            cutoff = 0
        list = []
        for file in self.dir.list():
            entry = self.dir.open(file)
            if not entry:
                continue
            mtime = entry.getmtime()
            if mtime >= cutoff:
                list.append((mtime, file))
        list.sort()
        list.reverse()
        self.prologue(T_RECENT)
        if days <= 1:
            period = "%.2g hours" % (days*24)
        else:
            period = "%.6g days" % days
        if not list:
            emit(NO_RECENT, period=period)
        elif len(list) == 1:
            emit(ONE_RECENT, period=period)
        else:
            emit(SOME_RECENT, period=period, count=len(list))
        self.format_all(map(lambda (mtime, file): file, list), headers=0)
        emit(TAIL_RECENT)

    def do_roulette(self):
        import random
        files = self.dir.list()
        if not files: 
            self.error("No entries.")
            return
        file = random.choice(files)
        self.prologue(T_ROULETTE)
        emit(ROULETTE)
        self.dir.show(file)

    def do_help(self):
        self.prologue(T_HELP)
        emit(HELP)

    def do_show(self):
        entry = self.dir.open(self.ui.file)
        self.prologue(T_SHOW)
        entry.show()

    def do_add(self):
        self.prologue(T_ADD)
        emit(ADD_HEAD)
        sections = SECTION_TITLES.items()
        sections.sort()
        for section, title in sections:
            emit(ADD_SECTION, section=section, title=title)
        emit(ADD_TAIL)

    def do_delete(self):
        self.prologue(T_DELETE)
        emit(DELETE)

    def do_log(self):
        entry = self.dir.open(self.ui.file)
        self.prologue(T_LOG, entry)
        emit(LOG, entry)
        self.rlog(interpolate(SH_RLOG, entry), entry)

    def rlog(self, command, entry=None):
        output = os.popen(command).read()
        sys.stdout.write('<PRE>')
        athead = 0
        lines = string.split(output, '\n')
        while lines and not lines[-1]:
            del lines[-1]
        if lines:
            line = lines[-1]
            if line[:1] == '=' and len(line) >= 40 and \
               line == line[0]*len(line):
                del lines[-1]
        headrev = None
        for line in lines:
            if entry and athead and line[:9] == 'revision ':
                rev = string.strip(line[9:])
                mami = revparse(rev)
                if not mami:
                    print line
                else:
                    emit(REVISIONLINK, entry, rev=rev, line=line)
                    if mami[1] > 1:
                        prev = "%d.%d" % (mami[0], mami[1]-1)
                        emit(DIFFLINK, entry, prev=prev, rev=rev)
                    if headrev:
                        emit(DIFFLINK, entry, prev=rev, rev=headrev)
                    else:
                        headrev = rev
                    print
                athead = 0
            else:
                athead = 0
                if line[:1] == '-' and len(line) >= 20 and \
                   line == len(line) * line[0]:
                    athead = 1
                    sys.stdout.write('<HR>')
                else:
                    print line
        print '</PRE>'

    def do_revision(self):
        entry = self.dir.open(self.ui.file)
        rev = self.ui.rev
        mami = revparse(rev)
        if not mami:
            self.error("Invalid revision number: %s." % `rev`)
        self.prologue(T_REVISION, entry)
        self.shell(interpolate(SH_REVISION, entry, rev=rev))

    def do_diff(self):
        entry = self.dir.open(self.ui.file)
        prev = self.ui.prev
        rev = self.ui.rev
        mami = revparse(rev)
        if not mami:
            self.error("Invalid revision number: %s." % `rev`)
        if prev:
            if not revparse(prev):
                self.error("Invalid previous revision number: %s." % `prev`)
        else:
            prev = '%d.%d' % (mami[0], mami[1])
        self.prologue(T_DIFF, entry)
        self.shell(interpolate(SH_RDIFF, entry, rev=rev, prev=prev))

    def shell(self, command):
        output = os.popen(command).read()
        sys.stdout.write('<PRE>')
        print escape(output)
        print '</PRE>'

    def do_new(self):
        entry = self.dir.new(section=string.atoi(self.ui.section))
        entry.version = '*new*'
        self.prologue(T_EDIT)
        emit(EDITHEAD)
        emit(EDITFORM1, entry, editversion=entry.version)
        emit(EDITFORM2, entry, load_my_cookie())
        emit(EDITFORM3)
        entry.show(edit=0)

    def do_edit(self):
        entry = self.dir.open(self.ui.file)
        entry.load_version()
        self.prologue(T_EDIT)
        emit(EDITHEAD)
        emit(EDITFORM1, entry, editversion=entry.version)
        emit(EDITFORM2, entry, load_my_cookie())
        emit(EDITFORM3)
        entry.show(edit=0)

    def do_review(self):
        send_my_cookie(self.ui)
        if self.ui.editversion == '*new*':
            sec, num = self.dir.parse(self.ui.file)
            entry = self.dir.new(section=sec)
            entry.version = "*new*"
            if entry.file != self.ui.file:
                self.error("Commit version conflict!")
                emit(NEWCONFLICT, self.ui, sec=sec, num=num)
                return
        else:
            entry = self.dir.open(self.ui.file)
            entry.load_version()
        # Check that the FAQ entry number didn't change
        if string.split(self.ui.title)[:1] != string.split(entry.title)[:1]:
            self.error("Don't change the entry number please!")
            return
        # Check that the edited version is the current version
        if entry.version != self.ui.editversion:
            self.error("Commit version conflict!")
            emit(VERSIONCONFLICT, entry, self.ui)
            return
        commit_ok = ((not PASSWORD
                      or self.ui.password == PASSWORD) 
                     and self.ui.author
                     and '@' in self.ui.email
                     and self.ui.log)
        if self.ui.commit:
            if not commit_ok:
                self.cantcommit()
            else:
                self.commit(entry)
            return
        self.prologue(T_REVIEW)
        emit(REVIEWHEAD)
        entry.body = self.ui.body
        entry.title = self.ui.title
        entry.show(edit=0)
        emit(EDITFORM1, self.ui, entry)
        if commit_ok:
            emit(COMMIT)
        else:
            emit(NOCOMMIT)
        emit(EDITFORM2, self.ui, entry, load_my_cookie())
        emit(EDITFORM3)

    def cantcommit(self):
        self.prologue(T_CANTCOMMIT)
        print CANTCOMMIT_HEAD
        if not self.ui.passwd:
            emit(NEED_PASSWD)
        if not self.ui.log:
            emit(NEED_LOG)
        if not self.ui.author:
            emit(NEED_AUTHOR)
        if not self.ui.email:
            emit(NEED_EMAIL)
        print CANTCOMMIT_TAIL

    def commit(self, entry):
        file = entry.file
        # Normalize line endings in body
        if '\r' in self.ui.body:
            self.ui.body = re.sub('\r\n?', '\n', self.ui.body)
        # Normalize whitespace in title
        self.ui.title = string.join(string.split(self.ui.title))
        # Check that there were any changes
        if self.ui.body == entry.body and self.ui.title == entry.title:
            self.error("You didn't make any changes!")
            return
        # XXX Should lock here
        try:
            os.unlink(file)
        except os.error:
            pass
        try:
            f = open(file, 'w')
        except IOError, why:
            self.error(CANTWRITE, file=file, why=why)
            return
        date = time.ctime(now)
        emit(FILEHEADER, self.ui, os.environ, date=date, _file=f, _quote=0)
        f.write('\n')
        f.write(self.ui.body)
        f.write('\n')
        f.close()

        import tempfile
        tfn = tempfile.mktemp()
        f = open(tfn, 'w')
        emit(LOGHEADER, self.ui, os.environ, date=date, _file=f)
        f.close()

        command = interpolate(
            SH_LOCK + '\n' + SH_CHECKIN,
            file=file, tfn=tfn)

        p = os.popen(command)
        output = p.read()
        sts = p.close()
        # XXX Should unlock here
        if not sts:
            self.prologue(T_COMMITTED)
            emit(COMMITTED)
        else:
            self.error(T_COMMITFAILED)
            emit(COMMITFAILED, sts=sts)
        print '<PRE>%s</PRE>' % escape(output)

        try:
            os.unlink(tfn)
        except os.error:
            pass

        entry = self.dir.open(file)
        entry.show()

wiz = FaqWizard()
wiz.go()
