#!/usr/bin/python
"""
  This script is provided AS IS, without any warranty!
  Copyright lio@lunesu.com, placed in the public domain
  Modified by Koen Werdler @ 01-05-2007
  Modified by Jason Dusek, 2008-07-14Z
 
  Requirements:
 .  python 2.5
 .  python-mysqldb

  This script dumps every version of every page as an INSERT statement that
  is compatible with the SQLite Trac schema (don't know about other
  databases). It omits some functionality, like recognizing edits by IP
  address users. It does not handle images. It separates `User:` and `Talk:`
  pages from the rest of the bunch and handles them appropriately.

  You may set the connection parameters towards the bottom of the script
  (following "main program").
                                                                           """

import os
import sys
import time
import string
import _mysql




def q(s):
    return "'" + s.replace("'", "''") + "'"

def time_fixer(mw_time):
    """ convert from mediawiki dates to epoch seconds """
    t = time.mktime(time.strptime(mw_time, "%Y%m%d%H%M%S"))
    return int(t)

def text_fixer(mw_text):
    """ convert from mediawiki text to trac text """
    mw_text = mw_text.replace("\n***","\n   *")
    mw_text = mw_text.replace("\n**", "\n  *")
    mw_text = mw_text.replace("\n*",  "\n *")
    mw_text = mw_text.replace("[[","wiki:")
    mw_text = mw_text.replace("]]","")
    mw_text = mw_text.replace("<br>","[[BR]]")
    mw_text = mw_text.replace("\n:","\n ")
    return q(mw_text)

def title_fixer(namespace, title):
    if namespace is 0:
        return q(title)
    if namespace is 1:
        return q('Talk:' + title)
    if namespace is 2:
        return q('User:' + title)

def comment_fixer(mw_comment):
    if mw_comment == '':
        return 'NULL'
    else:
        return q(mw_comment)

def row_writer(row):
    tuple = ",\n\t".join([
        title_fixer(int(row[-2]), row[0]),
        str(row[1]),
        str(time_fixer(row[2])),
        q(row[3].lower()),
        "'127.0.0.1'",
        text_fixer(row[4]),
        comment_fixer(row[5]),
        'NULL'
        ])
    return "INSERT INTO wiki VALUES\n(\t" + tuple + "\n);"

"""
  Trac's "wiki" table is layed out as follows:

CREATE TABLE wiki (
    name text,
    version integer,
    time integer,
    author text,
    ipnr text,
    text text,
    comment text,
    readonly integer,
    UNIQUE (name,version)
);
                                                                           """




"""
  Failings of this query:
 .  Does not handle "IP address" (anonymous) users.
 .  Does not handle User_talk pages. 
                                                                           """
query = string.Template("""
    SELECT
        ${p}page.page_title,
        ${p}revision.rev_timestamp,
        ${p}user.user_name,
        ${p}text.old_text,
        ${p}revision.rev_comment,
        ${p}page.page_namespace,
        ${p}revision.rev_page
      FROM
        ${p}page,
        ${p}revision,
        ${p}user,
        ${p}text
      WHERE
        ${p}page.page_id = ${p}revision.rev_page
       AND
        ${p}revision.rev_user = ${p}user.user_id
       AND
        ${p}revision.rev_text_id = ${p}text.old_id
       AND
        ${p}page.page_namespace <3
      ORDER BY
        ${p}page.page_namespace,
        ${p}revision.rev_page,
        ${p}revision.rev_id
      ;
    """).safe_substitute({
        "p" : ""
        })
"""
  Peruse these MediaWiki config file variables:
 .  $wgDBprefix
                                                                           """








"""
                  _
                 (_)
    ____   _____  _  ____     ____    ____   ___    ____   ____  _____  ____
   |    \ (____ || ||  _ \   |  _ \  / ___) / _ \  / _  | / ___)(____ ||    \
   | | | |/ ___ || || | | |  | |_| || |    | |_| |( (_| || |    / ___ || | | |
   |_|_|_|\_____||_||_| |_|  |  __/ |_|     \___/  \___ ||_|    \_____||_|_|_|
                             |_|                  (_____|                     

                                                                           """

def the_end():
    db.close()
    sys.exit()

res = ()
row = ()
def set_row():
    global res
    global row
    res = rs.fetch_row()
    if res == ():
        the_end()        ## !! This is the point at which we exit the program.
    row = res[0]

cur = ()
ver = ()
def reset_versioning():
    global cur
    global ver
    cur = row[-1]
    ver = 0

db = _mysql.connect(
     "localhost",
     "wikiuser",
     "wikipass",
     "wikidb",
     )
"""
  Peruse these MediaWiki config file variables:
 .  $wgDBserver
 .  $wgDBname
 .  $wgDBuser
 .  $wgDBpassword
 .  $wgDBport
                                                                           """

db.query(query)
rs = db.use_result()
set_row()
reset_versioning()
while True:
    while row[-1] == cur:
        ver += 1
        print row_writer(row[0:1] + (ver,) + row[1:])
        set_row()
    reset_versioning()


