<p>前幾天看了用《<a href="http://my.oschina.net/javayou/blog/39107">使用Live writter 在OSCHINA上寫博客</a>》的文章,又看了站長@紅薯的<a href="http://www.oschina.net/code/snippet_12_8206">接口程序</a>,真是 Lucky,支持xmlrpc。有不少插件支持wordpress的xmlrpc接口,想嘗試着弄過去,就萌生了用VIM來寫oschina博客的想法。 </p>php
<hr />html
<h1>VIM插件的選擇</h1>java
<p>固然支持寫blog的VIM插件不少,像<a href="http://www.vim.org/scripts/script.php?script_id=3510">vimrepress</a>,<a href="http://www.vim.org/scripts/script.php?script_id=1953">vimpress</a>等等。基本原理都是利用python的xmlrpclib實現客戶端進行遠程訪問。最後我選擇了<a href="http://www.vim.org/scripts/script.php?script_id=3532">ultrablog</a>。 </p>python
<h2>選擇ultrablog緣由</h2>git
<p>由於很大啊,呵呵。ultrablog的主要由python寫的,功能不少,支持本地數據庫(sqlite),結構很不錯,做爲學習python的一個example,有消息說,VIM的做者打算在7.4的版本里完善python的支持。</p>github
<h2>要準備的工做</h2>sql
<p>之前是用SuSE來進行平常的工做,不過這回轉到ubuntu上來了(SuSE裝軟件真是太痛苦了),固然系統不是必須的,任何VIM和PYTHON支持的系統都OK啦,硬性的要求有: </p>數據庫
<ul> <li>VIM(+python), 這是選擇ubuntu的主因啦,12.04(LTS)版恰好知足 </li> <li>SQLAlchemy 0.7+,這個主要是python的SQL庫,用去進行SQLite訪問的 </li> </ul>ubuntu
<p>其餘可選的一些包: </p>vim
<ul> <li>python-markdown,用去作markdown到HTML的轉化,推薦用python-markdown2. </li> <li>python-html2text, 正好和上一個相反 </li> <li>pandoc, 各類轉換 </li> </ul>
<p>用apt-get很容易的安裝這些: </p>
<pre><code>sudo apt-get install python-markdown </code></pre>
<p>python-markdown2要去下源碼進行安裝,比前一個版本,速度更快且修復了一些BUG, 以下: </p>
<pre><code>git clone https://github.com/trentm/python-markdown2.git cd python-markdown2 sudo python2 setup.py install </code></pre>
<h2>安裝ultrablog.vim</h2>
<p>下載ultrablog,並解壓到~/.vim/下,固然,能夠用vunble等管理VIM插件,很少說了,我沒有用,剛開始的時候沒有使用,又對插件作了不少更改,也就沒有移過去 </p>
<h2>配置</h2>
<p>在.vimrc中加入如下代碼: </p>
<pre><code>let ub_blog = {'login_name':'BLOG-USER-NAME', \'password ':'USER-PASSWORD', \'url':'http://my.oschina.net/action/xmlrpc', \'db':'~/.vim/UltraBlog.db' } </code></pre>
<p>其中,用戶名和密碼就很少說了,第三個是xmlrpc的url(能在前那個幾個文章裏查到),db是SQLite的文件。由於密碼是明文的,因此,注意安全,建議放到單獨文件再source進去 </p>
<hr />
<h1>Debug</h1>
<p>OK, 都安裝配置好了,能用麼? No.還有很長很長的路要走...... </p>
<h2>根本連不上</h2>
<p>第一個錯誤就是連不服務,直接用python連沒問題:</p>
<pre><code>handle=xmlrpclib.ServerProxy('http://my.oschina.net/action/xmlrpc') </code></pre>
<p>其實vimpress不用發生這個問題,由於ultrablog太智能了,他會把url加上'xmlrpc.php',可能這個對wordpress有用,不過對OSCHINA,呵呵! 更改ultrablog/util.py裏面的 </p>
<pre><code>self.xmlrpc = self.url+'xmlrpc.php' </code></pre>
<p>成爲: </p>
<pre><code>self.xmlrpc = self.url#+'xmlrpc.php' </code></pre>
<h2>getPost找不到服務器端的函數</h2>
<p>上一個問題更正以後,用命令: </p>
<pre><code>:UBList post remote 100 </code></pre>
<p>已經成功的列出服務器的全部文章,這個命令實際上調用了遠端的函數: </p>
<pre><code>public Object getRecentPosts(String blogid, String username, String pwd, int numberOfPosts) </code></pre>
<p>實際上這個函數已經反回了Blog文章的全部東西,包括文章內容,可是ultrablog只用了postid及文章標題,多是wordpress只是返回id及標題吧,無論這個問題,繼續下去,想要列出某一文章,問題發生了,‘can't find the remote server function: getPosts(int, String, String)’,相似的問題吧,記不太準確了。 由於python的變量太靈活了,postid是隻有數字的字符串,在調用的過程當中被轉化成int了,而remote server上的函數原型是: </p>
<pre><code>public Object getPost(String postid, String username, String pwd) </code></pre>
<p>因此,因爲參數類型不對,遠程訪問失敗。在這裏作一些修正,即在遠程調用時作了類型的強制轉換: </p>
<pre><code>key = str(self.itemKey) remote_post = api.metaWeblog.getPost(key, cfg.loginName, cfg.password) </code></pre>
<h2>類型的災難,xmlrpclib.py的錯誤</h2>
<p>一樣仍是在調用getPost, 一樣的地方,調用棧的最後幾層簡單的變了下,錯誤的內容大概是'int don't have the function: encode'。估計,python類型又在不知不覺中變了,大概是要調用String的encode函數,可是 這個對象被轉成了‘int’。針對這一假設,更改下xmlrpclib.py來測試(有源代碼就是好啊,想改就改,不知道這樣改有沒有問題...),果真是這樣!!! 個人python的版本是2.7.3, xmlrpclib.py更改以下(line 183): </p>
<pre><code>return str(string).encode("ascii") </code></pre>
<p>即在出問題的string調用encode的時候作一次類型轉化。純數字的字符串還真是難搞...... <br /> Go on! 一樣仍是隻是艱難的走了幾步,尚未走出getPost這個函數,不過幸運的是,遠程調用有返回值了!錯誤的地方是數組訪問越界,奇怪的錯誤,通常不會 發生啦,居然在通用的庫裏出這種錯誤, 抓包,打樁測試,原來getPost的返回,有兩個類型不支持,致使了parse的錯誤,以至於parse dict的時候出了單數,key-value不成對了,因此...... 對xmlrpclib.py更改是在class Unmarshaller里加入對不支持的tag: </p>
<pre><code>dispatch["ex:nil"] = end_nil dispatch["ex:i8"] = end_int </code></pre>
<h2>圖片上傳的問題</h2>
<p>小小的不兼容問題,只是對圖片的返回值作修正。上傳Media的返回值只有url的dict,不作修正而還要須要file的dict。對返回值作處理:</p>
<pre><code>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 </code></pre>
<hr />
<h1>寫在本篇的最後</h1>
<p>OK, 運行沒問題,用VIM寫下了這篇文章。上圖: <img src="http://static.oschina.net/uploads/img/201305/14062215_9jw6.jpg" alt="/home/austin/Documents/screen.jpg" /></p>