Discuz停更后需要替代论坛选择,实验了好几种,简单的说下感受和迁移方法。

以下按Github排名顺序

discourse

这个是排第一的论坛,但是是基于ror的,ror的性能差的不是一点点,内存占用也大。

我们之前的登录系统就是ror做的,爬虫在爬我们的discuz论坛时,由于每个帖子下都有一个登录链接,带了from参数都不一样,有些弱智爬虫都会爬一遍,该页面只是渲染登录框,就直接把ror的登录系统给干趴下了,而同样在被爬的discuz却无丝毫波动。习惯discuz的速度和经济性的做好准备,看你是否能忍受了。

flarum

这个界面非常不错。基于php+mysql,理应性能问题不大,但是论坛的sql查询没有做好,空论坛访问初始帖子会有100个sql查询,本地数据库打开速度100ms起,如果用低配云数据库200ms都是正常的。

nodebb

这个是用nosql+nodejs做的,速度没问题,而且是基于websocket长链接的,响应速度非常快。内存占用起始1G,但增长慢。插件和api齐全所以选择了这个。

apache / answer

这个也很不错,类似知乎stackoverflow。但是我找了一圈没有把提问,采纳这种功能去掉的方法,如果能去掉的话,就是一个以文章(长篇主帖)为中心的论坛了,适合不需要太多交流功能,攻略向的论坛。

flaskbb / flaskbb

python的论坛,性能很不错,但是很久没更新了。

rafalp / Misago

一眼二次元论坛,同样python的,作者刚开始开发没多几年,但倒是很勤奋。看了下他用了python的SocialAuth库,可以集成qq,weixin,google等各种登录方式包括集成自己的网站也是很容易的。

另外国人有2个论坛看着也不错,一个Casbin高仿v2ex,还有bbs-go和symphony看着类似csdn的blog,但我都没实验。

Discuz 迁移 nodebb

如果有自己的网站,nodebb迁移通行证可以用nodebb-plugin-session-sharing或者nodebb-plugin-sso-oauth2-multiple这2个官方插件。

至于discuz导入,只能自己写代码了,让AI用python帮你写一个框架,剩下的自己改。

如果只需要导入帖子的话,循环discuz的posts表,每行就是一个帖子,first=1就是主题贴。

对于主题帖,调用nodebb的api/v3/topics/接口,对于回复,调用api/v3/topics/{tid}接口。用户的话可以用用户创建的接口,由于我用的session-sharing,用的是api/session-sharing/user接口,查询用户是api/session-sharing/lookup?id={passport_id}

调用示例:

async def create_topic(title, body, timestamp, category, tags, uid):
    # 创建主题 POST
    data = {
        "cid": category,  # 板块号
        "title": title,
        "content": body,
        "timestamp": int(timestamp),  # 毫秒时间
        "tags": tags,
        "_uid": uid   # 发帖人
    }
    # api管理员密钥
    headers = {"Authorization": f"Bearer 1239383-3323-2323-2323-asd123123123"}
    # 调用
    async with aiohttp.ClientSession() as session:
        async with session.post(
                'https://xxx.com/api/v3/topics/',
                headers=headers,
                json=data
        ) as response:
            if response.status != 200:
                # 如果是“请增添发帖内容,不能少于 1 个”这种错误,就是content没escape
                response_text = await response.text()
                raise Exception(f"Error creating topic {title}: {response_text}")
            result = await response.json()
            topic_object = result['response']
            return topic_object['tid']

注意,API发帖和用户发帖是一个逻辑,受到论坛的所有字数限制,另外同样,timestamp也因为这个,导致设置了无效,会依然按最新时间发表,解决办法是修改 src/api/helpers.js 16行的时间戳,直接注释掉data.timestamp = Date.now();这行就行了。迁移完记得改回来,不然用户也能改时间了。