emlog2typecho 是一个用python写的脚本,用来迁移Emlog的数据库到Typecho。正如你所看到的这个网站我的博客,就是用它迁移过来的,相信你也可以很方便的使用它。目前它可以自动迁移文章、页面、分类、标签,当然你也可以参与本工具的更新、修改和优化,Github地址在文末。
使用方法
- 在本地新建emlog数据库并导入需要转换的数据
- 再安装Typecho来建立Typecho的数据库
- 在脚本中设置两个数据库名(默认是“emlog”和“typecho”)
- 运行emlog2typecho.py
- 备份Typecho数据库,上传到你的博客
注意
此Python代码用到了MySQLdb库来连接MySQL,没有这个包的可以用pip安装:pip install MySQL-python
Typecho最好是新安装出来的空数据库,以免出现不必要的麻烦
后言
源码:https://github.com/isaced/emlog2typecho
以下是改进版本
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# 一些设置项
# Emlog 数据库名
emlog_database_name = 'blog1'
# Typecho 数据库名
typecho_database_name = 'blog'
# 数据库地址
database_host = 'localhost'
# 数据库用户名
database_port = 3306
# 数据库用户名
database_user_name = 'root'
# 数据库用户名
database_user_password = '123456'
# 字符集
database_charset = 'utf8'
emlog_prefix = 'log_'
typecho_prefix = 'typecho_'
#################################################################################
import MySQLdb
# 连接数据库...
conn=MySQLdb.connect(host = database_host,
user = database_user_name,
passwd = database_user_password,
port = database_port,
charset = database_charset)
# 切换emlog数据库...
conn.select_db(emlog_database_name)
cur=conn.cursor()
# 读取emlog所有分类
cur.execute('select sid, sortname, alias, ( select count( * ) from '+emlog_prefix+'blog where sortid = sid ) AS count FROM '+emlog_prefix+'sort')
emlog_sort_list = cur.fetchall()
# 读取Emlog所有Tag
cur.execute('select tid,tagname,gid from '+emlog_prefix+'tag')
emlog_tag_list = []
for row in cur.fetchall():
tagname = row[1]
gid_list = row[2].split(',')
# 移除列表中为空字符串的项
for gid in gid_list:
if gid == '':
gid_list.remove(gid)
# 组装
tag = {'tagname':tagname,'gidlist':gid_list}
emlog_tag_list.append(tag)
# 读取emlog blog表...
cur.execute('select gid,title,date,content,excerpt,alias,sortid,type,allow_remark from '+emlog_prefix+'blog')
emlog_blog_list = cur.fetchall()
# 读取Emlog comment表
cur.execute("SELECT * FROM `"+emlog_prefix+"comment`")
emlog_comment_list = cur.fetchall()
# ------------------------------------------
# --- Emlog表读取完毕,切换Typecho表进行写入 ---
# ------------------------------------------
# 切换Typecho数据库...
conn.select_db(typecho_database_name)
cur=conn.cursor()
# 删除Typecho 所有分类和标签...
cur.execute('delete from '+typecho_prefix+'metas')
# 插入emlog所有分类
for sort in emlog_sort_list:
sort_id = sort[0]
sort_name = sort[1]
sort_sulg = sort[2] # sort[0] if sort[1] == '' else sort[1]
sort_count = sort[3]
cur.execute("insert into "+typecho_prefix+"metas (mid, name, slug, type, description, `count`, `order`) VALUES (%s, %s, %s, 'category', NULL, %s, 0)" , (sort_id,sort_name, sort_sulg,sort_count))
# 删除Typecho 所有文章...
cur.execute('delete from '+typecho_prefix+'contents')
# 删除文章所有关系
cur.execute('delete from '+typecho_prefix+'relationships')
# 删除所有评论
cur.execute('delete from '+typecho_prefix+'comments')
# 转移所有文章
for blog in emlog_blog_list:
print blog
blog_id = blog[0]
blog_title = blog[1]
blog_create_date = blog[2]
blog_content = blog[3]
blog_excerpt = blog[4]
# 不能为空字符串
blog_alias = blog[5]
if blog_alias == '':
blog_alias = None
# emlog --> blog page
# typecho --> post page
if blog[7] == 'blog':
blog_type = 'post'
else:
blog_type = 'page'
# allow comment
if blog[8] == 'y':
blog_allow_comment = '1'
else:
blog_allow_comment = '0'
params = (blog_id,blog_title,blog_alias,blog_create_date,blog_content,blog_type,blog_allow_comment)
cur.execute("insert into `"+typecho_prefix+"contents` (`cid`, `title`, `slug`, `created`, `modified`, `text`, `order`, `authorId`, `template`, `type`, `status`, `password`, `commentsNum`, `allowComment`, `allowPing`, `allowFeed`, `parent`) VALUES (%s, %s, %s, %s, NULL, %s, '0', '1', NULL, %s, 'publish', NULL, '0', %s, '0', '0', '0')",params)
# 添加文章的relationships
blog_sortid = blog[6]
# emlog 中 分类id -1 为页面
if blog_sortid == -1:
continue
cur.execute('insert into `'+typecho_prefix+'relationships` (`cid`, `mid`) VALUES (%s, %s)',(blog_id,blog_sortid))
# 插入所有Tag(和关系)
cur.execute("select MAX( mid ) FROM `"+typecho_prefix+"metas`")
sort_max_id = (cur.fetchall()[0][0]) + 1
# 从刚插入的分类最后一个ID+1作为ID开始循环插入
for tag in emlog_tag_list:
cur.execute("insert into `"+typecho_prefix+"metas` (`mid`, `name`, `slug`, `type`, `description`, `count`, `order`) VALUES (%s, %s, %s, 'tag', NULL, %s, '0');",(sort_max_id,tag['tagname'],tag['tagname'],len(tag['gidlist'])))
for gid in tag['gidlist']:
params = (int(gid),sort_max_id)
# !有时会遇到重复项插入失败跳过
try:
cur.execute('insert into `'+typecho_prefix+'relationships` (`cid`, `mid`) VALUES (%s, %s)',params)
except:
print '失败一条Tag:%s,%s' % (params)
sort_max_id = sort_max_id + 1
# 插入评论
for comment in emlog_comment_list:
params = (comment[0],comment[1],comment[3],comment[4],comment[6],comment[7],comment[8],comment[5],comment[2])
cur.execute("INSERT INTO `"+typecho_prefix+"comments` (`coid`, `cid`, `created`, `author`, `authorId`, `ownerId`, `mail`, `url`, `ip`, `agent`, `text`, `type`, `status`, `parent`) VALUES (%s, %s, %s, %s, '0', '1', %s, %s, %s, NULL, %s, 'comment' , 'approved', %s)",params)
# 关闭数据库连接
cur.close()
conn.close()
print '转移完成...'