用VIM写OSCHINA的博客

前几天看了用《使用Live writter 在OSCHINA上写博客》的文章,又看了站长@红薯的接口程序,真是 Lucky,支持xmlrpc。有很多插件支持wordpress的xmlrpc接口,想尝试着弄过去,就萌生了用VIM来写oschina博客的想法。

VIM插件的选择

当然支持写blog的VIM插件很多,像vimrepress,vimpress等等。基本原理都是利用python的xmlrpclib实现客户端进行远程访问。最后我选择了ultrablog。

选择ultrablog原因

因为很大啊,呵呵。ultrablog的主要由python写的,功能很多,支持本地数据库(sqlite),结构很不错,作为学习python的一个example,有消息说,VIM的作者打算在7.4的版本里完善python的支持。

要准备的工作

以前是用SuSE来进行日常的工作,不过这回转到ubuntu上来了(SuSE装软件真是太痛苦了),当然系统不是必须的,任何VIM和PYTHON支持的系统都OK啦,硬性的要求有:

  • VIM(+python), 这是选择ubuntu的主因啦,12.04(LTS)版刚好满足
  • SQLAlchemy 0.7+,这个主要是python的SQL库,用去进行SQLite访问的

其他可选的一些包:

  • python-markdown,用去做markdown到HTML的转化,推荐用python-markdown2.
  • python-html2text, 正好和上一个相反
  • pandoc, 各种转换

用apt-get很容易的安装这些:

sudo apt-get install python-markdown 

python-markdown2要去下源码进行安装,比前一个版本,速度更快且修复了一些BUG, 如下:

git clone https://github.com/trentm/python-markdown2.git 
cd python-markdown2 
sudo python2 setup.py install

安装ultrablog.vim

下载ultrablog,并解压到~/.vim/下,当然,可以用vunble等管理VIM插件,不多说了,我没有用,刚开始的时候没有使用,又对插件做了很多更改,也就没有移过去

配置

在.vimrc中加入以下代码:

let ub_blog = {'login_name':'BLOG-USER-NAME', 
        \'password
        ':'USER-PASSWORD', 
        \'url':'http://my.oschina.net/action/xmlrpc',
        \'db':'~/.vim/UltraBlog.db' }

其中,用户名和密码就不多说了,第三个是xmlrpc的url(能在前那个几个文章里查到),db是SQLite的文件。因为密码是明文的,所以,注意安全,建议放到单独文件再source进去

Debug

OK, 都安装配置好了,能用么? No.还有很长很长的路要走......

根本连不上

第一个错误就是连不服务,直接用python连没问题:

handle=xmlrpclib.ServerProxy('http://my.oschina.net/action/xmlrpc')

其实vimpress不用发生这个问题,因为ultrablog太智能了,他会把url加上'xmlrpc.php',可能这个对wordpress有用,不过对OSCHINA,呵呵! 更改ultrablog/util.py里面的

self.xmlrpc = self.url+'xmlrpc.php'

成为:

self.xmlrpc = self.url#+'xmlrpc.php'

getPost找不到服务器端的函数

上一个问题更正之后,用命令:

:UBList post remote 100

已经成功的列出服务器的所有文章,这个命令实际上调用了远端的函数:

public Object getRecentPosts(String blogid, String username, String pwd, int numberOfPosts)

实际上这个函数已经反回了Blog文章的所有东西,包括文章内容,但是ultrablog只用了postid及文章标题,可能是wordpress只是返回id及标题吧,不管这个问题,继续下去,想要列出某一文章,问题发生了,‘can't find the remote server function: getPosts(int, String, String)’,类似的问题吧,记不太准确了。 因为python的变量太灵活了,postid是只有数字的字符串,在调用的过程中被转化成int了,而remote server上的函数原型是:

public Object getPost(String postid, String username, String pwd)

所以,由于参数类型不对,远程访问失败。在这里做一些修正,即在远程调用时做了类型的强制转换:

key = str(self.itemKey) 
remote_post = api.metaWeblog.getPost(key, cfg.loginName, cfg.password)

类型的灾难,xmlrpclib.py的错误

同样还是在调用getPost, 同样的地方,调用栈的最后几层简单的变了下,错误的内容大概是'int don't have the function: encode'。估计,python类型又在不知不觉中变了,大概是要调用String的encode函数,但是 这个对象被转成了‘int’。针对这一假设,更改下xmlrpclib.py来测试(有源代码就是好啊,想改就改,不知道这样改有没有问题...),果然是这样!!! 我的python的版本是2.7.3, xmlrpclib.py更改如下(line 183):

return str(string).encode("ascii")

即在出问题的string调用encode的时候做一次类型转化。纯数字的字符串还真是难搞......
Go on! 同样还是只是艰难的走了几步,还没有走出getPost这个函数,不过幸运的是,远程调用有返回值了!错误的地方是数组访问越界,奇怪的错误,一般不会 发生啦,竟然在通用的库里出这种错误, 抓包,打桩测试,原来getPost的返回,有两个类型不支持,导致了parse的错误,以致于parse dict的时候出了单数,key-value不成对了,所以...... 对xmlrpclib.py更改是在class Unmarshaller里加入对不支持的tag:

dispatch["ex:nil"] = end_nil 
dispatch["ex:i8"] = end_int

图片上传的问题

小小的不兼容问题,只是对图片的返回值做修正。上传Media的返回值只有url的dict,不做修正而还要需要file的dict。对返回值做处理:

result = api.metaWeblog.newMediaObject('', cfg.loginName, cfg.password,
                                    dict(name=os.path.basename(file_path), type=file_type, bits=bin_data))
img_tmpl_info = ub_get_option('ub_tmpl_img_url', True)                                                                                                                                                                           
result['file'] = file_path
img_url = img_tmpl_info['tmpl'] % result

写在本篇的最后

OK, 运行没问题,用VIM写下了这篇文章。上图: 用VIM写OSCHINA的博客_第1张图片

你可能感兴趣的:(用VIM写OSCHINA的博客)