phpBB3导入帖子的Python脚本

关联的数据表

在phpBB3中导入用户时, 需要处理的有两张表, 一个是 topics, 一个是 posts.
为了方便与原数据关联, 需要在这两个表上新增一个字段并建立唯一索引

ALTER TABLE `topics` ADD COLUMN `ori_id` VARCHAR(32) NOT NULL DEFAULT ‘‘ AFTER `poll_vote_change`;
ALTER TABLE `posts` ADD COLUMN `ori_id` VARCHAR(32) NOT NULL DEFAULT ‘‘ AFTER `post_edit_locked`;
ALTER TABLE `topics` ADD UNIQUE INDEX `ori_id` USING BTREE (`ori_id`);
ALTER TABLE `posts` ADD UNIQUE INDEX `ori_id` USING BTREE (`ori_id`);

如果是新安装的论坛, 在每次导入之前, 用以下语句初始化:

TRUNCATE `topics`;
TRUNCATE `posts`;

需要的最小数据集

posts表, 需要的最小字段集为 `topic_id`, `forum_id`, `poster_id`, `poster_ip`, `post_time`, `enable_sig`, `post_username`, `post_subject`, `post_text`, `post_checksum`, `post_attachment`, `ori_id`
topics表, 需要的最小字段集为 `forum_id`, `topic_title`, `topic_time`, `ori_id`

导入topic和post时的处理逻辑
按创建时间将post正序排列后, 依次处理: 检查是否是topic的第一篇, 如果是则创建topic, 如果不是则去查找(目标db, 源db, 如果找不的第一篇时, 需要将自己设为第一篇), 这样topicId确定后就可以写入post了, 然后再拿写入产生的postId, 去更新topic的信息

Python代码

子函数

import rbcommon
import re

def getTopic(cursor, articleId):
    sql = ‘SELECT topic_id FROM phpbb_topics WHERE ori_id = %s‘
    cursor.execute(sql, (articleId))
    row = cursor.fetchone()
    if (row is not None):
        return row[‘topic_id‘]
    else:
        return 0

def getAuthor(cursor, name):
    sql = ‘SELECT user_id FROM phpbb_users WHERE username_clean = %s‘
    cursor.execute(sql, (name.lower()))
    row = cursor.fetchone()
    if (row is not None):
        return row[‘user_id‘]
    else:
        print(‘Not exists:{}‘.format(name))
        exit()

def insertTopic(cursor, forum_id, topic_title, topic_time, ori_id):
    sql = ‘INSERT IGNORE INTO `phpbb_topics` (`forum_id`, `topic_title`, `topic_time`, `ori_id`) ‘           ‘VALUES (%s, %s, %s, %s)‘
    cursor.execute(sql, (forum_id, topic_title, topic_time, ori_id))
    lastId = cursor.lastrowid
    return lastId

def insertPost(cursor, topic_id, forum_id, poster_id, poster_ip, post_time, post_username, post_subject, post_text, post_attachment, ori_id):
    sql = ‘INSERT IGNORE INTO `phpbb_posts` (`topic_id`, `forum_id`, `poster_id`, `poster_ip`, `post_time`, `enable_sig`, ‘           ‘`post_username`, `post_subject`, `post_text`, `post_checksum`, `post_attachment`, `ori_id`) ‘           ‘VALUES (%s, %s, %s, %s, %s, 0, %s, %s, %s, \‘\‘, %s, %s)‘
    cursor.execute(sql, (topic_id, forum_id, poster_id, poster_ip, post_time, post_username, post_subject, post_text, post_attachment, ori_id))
    lastId = cursor.lastrowid
    if (lastId == 0):
        print(‘Duplicate ID:>{}<‘.format(ori_id))
    return lastId

def updateTopicFirst(cursor, authorId, postId, author, title, createdAt, topicId):
    sql = ‘UPDATE phpbb_topics SET ‘           ‘topic_poster=%s, topic_first_post_id=%s, topic_first_poster_name=%s, ‘           ‘topic_last_poster_id=%s, topic_last_post_id=%s, topic_last_poster_name=%s, topic_last_post_subject=%s, topic_last_post_time=%s WHERE `topic_id`=%s‘

    cursor.execute(sql, (authorId, postId, author, authorId, postId, author, title, createdAt, topicId))

def updateTopic(cursor, authorId, postId, author, title, createdAt, topicId):
    sql = ‘UPDATE phpbb_topics SET topic_replies=topic_replies+1, topic_replies_real=topic_replies_real+1, ‘           ‘topic_last_poster_id=%s, topic_last_post_id=%s, topic_last_poster_name=%s, topic_last_post_subject=%s, topic_last_post_time=%s WHERE `topic_id`=%s‘
    cursor.execute(sql, (authorId, postId, author, title, createdAt, topicId))

主方法

tb_article_all = rbcommon.db[‘article_all‘]
limit = 1000
total = tb_article_all.estimated_document_count()
for i in range(0, total, limit):
    print("\n" + ‘######## Start:‘ + str(i) + ‘, limit:‘ + str(limit) + ‘ ########‘)
    articles = tb_article_all.find().sort(‘createdAt‘, 1).limit(limit).skip(i)
    for article in articles:
        # extract the forumId, author, etc
        pos = article[‘_id‘].find(‘.‘)
        forumId = article[‘_id‘][0:pos]
        author = article[‘author‘].strip()
        posterIp = ‘‘ if (not ‘ip‘ in article) else article[‘ip‘]
        attachments = 0 if (len(article[‘attachments‘]) == 0) else 1
        # content = article[‘content‘].replace(‘\\n‘, ‘\n‘)
        content = re.sub(r‘\\n‘, ‘\n‘, article[‘content‘])
        content = re.sub(r‘\\r\[[;\d]{0,8}m‘, ‘‘, content)
        content = re.sub(r‘\\(/|"|\‘)‘, r‘\1‘, content)

        with rbcommon.mysqlclient.cursor() as cursor:
            # get author Id
            authorId = getAuthor(cursor, author)

            # Check if it is a topic
            firstPostFlag = False
            if (article[‘_id‘] == article[‘parentId‘]):
                firstPostFlag = True
                # if yes, check if it exists
                topicId = getTopic(cursor, article[‘_id‘])
                if (topicId == 0):
                    # if not, insert a topic, get the topicId
                    topicId = insertTopic(cursor, forumId, article[‘title‘], article[‘createdAt‘], article[‘_id‘])
            else:
                # if not a topic, get the topic ID
                topicId = getTopic(cursor, article[‘parentId‘])
                if (topicId == 0):
                    # if not exists, find it and insert it(topic record), and get the topic ID
                    dummy = tb_article_all.find_one({‘_id‘: article[‘parentId‘]})
                    # if dummy not exists, make this post the first post
                    if (dummy is None):
                        dummy_title = article[‘title‘]
                        dummy_createdAt = article[‘createdAt‘]
                        dummy_author = article[‘author‘].strip()
                        dummy_ori_id = article[‘parentId‘]
                        firstPostFlag = True
                    else:
                        dummy_title = dummy[‘title‘]
                        dummy_createdAt = dummy[‘createdAt‘]
                        dummy_author = dummy[‘author‘].strip()
                        dummy_ori_id = dummy[‘_id‘]
                    topicId = insertTopic(cursor, forumId, dummy_title, dummy_createdAt, dummy_ori_id)

            # should not be 0 at this point
            if (topicId == 0):
                print(‘Failed to get topicId for {}‘.format(article[‘_id‘]))
                exit()

            # perform the actual post insert
            postId = insertPost(cursor, topicId, forumId, authorId, posterIp, article[‘createdAt‘], author, article[‘title‘], content, attachments, article[‘_id‘])
            if (postId == 0):
                print(‘Post already exists: {}‘.format(article[‘_id‘]))
                rbcommon.mysqlclient.rollback()
                continue

            # update the topic
            if (firstPostFlag):
                updateTopicFirst(cursor, authorId, postId, author, article[‘title‘], article[‘createdAt‘], topicId)
            else:
                updateTopic(cursor, authorId, postId, author, article[‘title‘], article[‘createdAt‘], topicId)

        # commit all changes at last
        rbcommon.mysqlclient.commit()

同步版面数据

导入结束后, 即使同步后台数据和清空缓存, 在前台也是看不到版面文章的, 显示都是空. 可以在后台的版面管理中, 点击版面右侧的同步图标, 对每个版面进行手动同步. 如果版面较多不合适手工处理, 则可以在论坛的根目录下, 创建下面这个脚本 tmp.php:

<?php
define(‘IN_PHPBB‘, true);
$phpbb_root_path = (defined(‘PHPBB_ROOT_PATH‘)) ? PHPBB_ROOT_PATH : ‘./‘;
$phpEx = substr(strrchr(__FILE__, ‘.‘), 1);
include($phpbb_root_path . ‘common.‘ . $phpEx);
include($phpbb_root_path . ‘includes/functions_display.‘ . $phpEx);
require($phpbb_root_path . ‘includes/functions_admin.‘ . $phpEx);
echo ‘Start‘;
sync(‘forum‘, ‘‘, ‘‘, false, true);
echo ‘Done‘;
$cache->destroy(‘sql‘, FORUMS_TABLE);
?>

在命令行下执行命令 php tmp.php 版面的数据就全部同步了.

.

原文地址:https://www.cnblogs.com/milton/p/10262916.html

时间: 2024-11-08 06:59:00

phpBB3导入帖子的Python脚本的相关文章

phpBB3导入用户的Python脚本

关联的数据表 在phpBB3中导入用户时, 需要处理的有两张表, 一个是 users, 一个是 user_group. 如果是新安装的论坛, 在每次导入之前, 用以下语句初始化: DELETE FROM phpbb_users WHERE user_id > 47; alter table phpbb_users auto_increment = 48; DELETE FROM phpbb_user_group where user_id > 48; DELETE FROM phpbb_use

phpBB3.0.X导入版面的Python脚本

关联的数据表 在phpBB3.0中导入版面时, 需要处理的有两张表, 一个是 forums, 一个是 acl_groups. 如果是干净的论坛, 可以不保留安装时填入的默认分区和版面, 直接用以下语句初始化: -- 清空 forums 表 TRUNCATE phpbb_forums; -- 清空 acl_groups 表 TRUNCATE phpbb3015.phpbb_acl_groups; -- 填入初始化权限 INSERT INTO `phpbb_acl_groups` VALUES (1

用 Python 脚本实现对 Linux 服务器的监控

hon 分享到:8 原文出处: 曹江华 目前 Linux 下有一些使用 Python 语言编写的 Linux 系统监控工具 比如 inotify-sync(文件系统安全监控软件).glances(资源监控工具)在实际工作中,Linux 系统管理员可以根据自己使用的服务器的具体情况编写一下简单实用的脚本实现对 Linux 服务器的监控. 本文介绍一下使用 Python 脚本实现对 Linux 服务器 CPU 内存 网络的监控脚本的编写. Python 版本说明 Python 是由 Guido va

2. 蛤蟆Python脚本学习笔记二基本命令畅玩

2. 蛤蟆Python脚本学习笔记二基本命令畅玩 本篇名言:"成功源于发现细节,没有细节就没有机遇,留心细节意味着创造机遇.一件司空见惯的小事或许就可能是打开机遇宝库的钥匙!" 下班回家,咱先来看下一些常用的基本命令. 欢迎转载,转载请标明出处:http://blog.csdn.net/notbaron/article/details/48092873 1.  数字和表达式 看下图1一就能说明很多问题: 加法,整除,浮点除,取模,幂乘方等.是不是很直接也很粗暴. 关于上限,蛤蟆不太清楚

某互联网后台自动化组合测试框架RF+Sikuli+Python脚本

某互联网后台自动化组合测试框架RF+Sikuli+Python脚本 http://www.jianshu.com/p/b3e204c8651a 字数949 阅读323 评论1 喜欢0 一.**RobotFramework 1.**工具介绍:Robotframework在测试中作为组织测试用例和BDD关键字的平台,主要使用RIDE进行管理,它不是一个工具,而仅仅是一个框架,使用Python进行开发,同时支持WEB测试(Selenium).Java GUI 测试,启动线程.终端.SSH等.支持BDD

利用pyinstaller将python脚本打包发布

之前写了一个小工具,将excel配置表转换为json.xml.lua等配置文件.最近在学习egret,正好需要转换配置文件,刚好就用上了.然而当我想把工具拷到工作目录时,就发愁了.之前我为了方便扩展,把程序拆分得太细: [email protected]:~/Documents/code/github/py_exceltools$ ls -lh 总用量 80K drwxrwxr-x 2 xzc xzc 4.0K 7月 27 23:03 bin drwxrwxr-x 2 xzc xzc 4.0K

使用Python脚本强化LLDB调试器

LLDB是Xcode自带的调试器,作为一个iOS应用开发程序员,平时我在开发应用时会使用LLDB来调试代码.在逆向应用时,也会用到LLDB来跟踪应用的执行过程. LLDB还内置了一个Python解析器,使用Python脚本可以方便LLDB的调试,比如自动化执行一些命令,或者自动化处理数据之类的,具体说明可以参考官方的文档:LLDB Python Reference. 以下就以一个具体的例子来演示一个Python脚本的编写过程: 一.获取方法的偏移地址 运行系统自带的计算器Calculator.a

JAVA读写Python脚本

1.在Eclipse或者Myeclipse的java工程中导入Jython.jar包.http://down.51cto.com/data/2094597 2.编写读取Python的工具类. import org.python.util.PythonInterpreter; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayLi

Python脚本调用C#代码数据交互示例(hello world)

原地址: http://www.djangochina.cn/forum.php?mod=viewthread&tid=247 随着项目的逐渐收尾, 对IronPython脚本也越来越熟悉,这里为IronPython脚本感兴趣但不入门的朋友写几篇使用心得,这是第一个:最简单的hello world程序.        首先,我们必须有一个IronPython脚本引擎库(IronPython.dll),我用的版本是V1.0,你可以在网上直接下到相关源码,编译后即生成IronPython.dll.1