Mercurial > public > sg101
diff legacy/management/commands/translate_old_posts.py @ 581:ee87ea74d46b
For Django 1.4, rearranged project structure for new manage.py.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 05 May 2012 17:10:48 -0500 |
parents | gpp/legacy/management/commands/translate_old_posts.py@28de6caa4e6d |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/legacy/management/commands/translate_old_posts.py Sat May 05 17:10:48 2012 -0500 @@ -0,0 +1,134 @@ +""" +translate_old_posts.py - A management command to join the bbposts and +bbposts_text tables together and output as a .csv file, suitable for use as an +input to mysqlimport into the new database. This method bypasses the Django ORM +as it was too slow given the number of old posts to import. + +""" +from __future__ import with_statement +import csv +import optparse +from datetime import datetime + +import MySQLdb +import postmarkup + +from django.core.management.base import NoArgsCommand, CommandError + +from legacy.phpbb import unphpbb +from legacy.html2md import MarkdownWriter +from core.markup import SiteMarkup + + +def convert_ip(s): + """ + Converts a hex string representing an IP address into dotted notation. + """ + n = int(s, 16) + return "%d.%d.%d.%d" % ( + ((n >> 24) & 0xff), + ((n >> 16) & 0xff), + ((n >> 8) & 0xff), + n & 0xff) + + +class Command(NoArgsCommand): + help = """\ +This command joins the SG101 1.0 posts to 2.0 format and outputs the +data as a .csv file suitable for importing into the new database scheme with +the mysqlimport utility. +""" + option_list = NoArgsCommand.option_list + ( + optparse.make_option("-s", "--progress", action="store_true", + help="Output a . after every 100 posts to show progress"), + optparse.make_option("-a", "--host", help="set MySQL host name"), + optparse.make_option("-u", "--user", help="set MySQL user name"), + optparse.make_option("-p", "--password", help="set MySQL user password"), + optparse.make_option("-d", "--database", help="set MySQL database name"), + optparse.make_option("-o", "--out-file", help="set output filename"), + ) + bb_parser = postmarkup.create(use_pygments=False, annotate_links=False) + md_writer = MarkdownWriter() + site_markup = SiteMarkup() + + def handle_noargs(self, **opts): + + host = opts.get('host', 'localhost') or 'localhost' + user = opts.get('user', 'root') or 'root' + password = opts.get('password', '') or '' + database = opts.get('database') + out_filename = opts.get('out_file', 'forums_post.csv') or 'forums_post.csv' + + if database is None: + raise CommandError("Please specify a database option") + + out_file = open(out_filename, "wb") + + # database columns (fieldnames) for the output CSV file: + cols = ('id', 'topic_id', 'user_id', 'creation_date', 'update_date', + 'body', 'html', 'user_ip') + self.writer = csv.writer(out_file) + + # Write an initial row of fieldnames to the output file + self.writer.writerow(cols) + + # connect to the legacy database + try: + db = MySQLdb.connect(host=host, + user=user, + passwd=password, + db=database) + except MySQLdb.DatabaseError, e: + raise CommandError(str(e)) + + c = db.cursor(MySQLdb.cursors.DictCursor) + + # query the legacy database + sql = ('SELECT * FROM sln_bbposts as p, sln_bbposts_text as t WHERE ' + 'p.post_id = t.post_id ORDER BY p.post_id') + c.execute(sql) + + # convert the old data and write the output to the file + while True: + row = c.fetchone() + if row is None: + break + + self.process_row(row) + + c.close() + db.close() + out_file.close() + + def to_html(self, s): + return self.bb_parser.render_to_html(unphpbb(s), cosmetic_replace=False) + + def to_markdown(self, s): + self.md_writer.reset() + self.md_writer.feed(self.to_html(s)) + return self.md_writer.markdown() + + def process_row(self, row): + """ + This function accepts one row from the legacy database and converts the + contents to the new database format, and calls the writer to write the new + row to the output file. + """ + creation_date = datetime.fromtimestamp(float(row['post_time'])) + + if row['post_edit_time']: + update_date = datetime.fromtimestamp(float(row['post_edit_time'])) + else: + update_date = creation_date + + body = self.to_markdown(row['post_text']) + html = self.site_markup.convert(body) + + self.writer.writerow([row['post_id'], + row['topic_id'], + row['poster_id'], + creation_date, + update_date, + body.encode("utf-8"), + html.encode("utf-8"), + convert_ip(row['poster_ip'])])