Λάδι Βιώσας

http://profile.hatena.ne.jp/kenkitii/

PythonでAtomクライアント

先日書いたMT投稿スクリプト、ほんとはLivedoorブログで使いたかったんだけどなんだかlivedoorxml-rpcはつかえないっぽい、、、今?はAtomAPIというのを使わないといけないようだ。知らなかったorz

で、AtomAPIについては、「はてなブックマークAtomAPI」と「はてなフォトライフAtomAPI」に、わかり易い解説が書いてあったので、Perlのサンプルを参考にAtomクライアントもどきを作ってみた。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import random
import datetime, time
import base64, sha
import httplib

class AtomClient:
    def __init__(self):
        self.endopoint = None
        self.wsse = None

    def credentials(self, endpoint, user, password):
        nonce = sha.sha(str(time.time() + random.random())).digest()
        now = datetime.datetime.now().isoformat() + "Z"
        digest = sha.sha(nonce + now + password).digest()

        wsse = 'UsernameToken Username="%(u)s", PasswordDigest="%(p)s", Nonce="%(n)s", Created="%(c)s"'
        value = dict(u = user, p = base64.encodestring(digest).strip(),
                     n = base64.encodestring(nonce).strip(), c = now)

        self.endpoint = endpoint
        self.wsse = wsse % value

    def atom_request(self, method, URI, body):
        con = httplib.HTTPConnection(self.endpoint)
        con.request(method, URI, body, {'X-WSSE' : self.wsse, 'Content-Type':'text/xml'})
        r = con.getresponse()

        response = dict(status = r.status,
                       reason = r.reason,
                       data   = r.read())
        con.close()
        return response

で、ライブドアブログ投稿スクリプトのサンプルはこんな感じになりました

class LdBlog(AtomClient):
    def post_blog(self, id, title, text):
        title = unicode(title).encode("utf-8")
        text = unicode(text).encode("utf-8")

        post_uri = '/atom/blog_id=' + str(id)
        entry = '''<entry xmlns="http://purl.org/atom/ns#">
  <title xmlns="http://purl.org/atom/ns#">%s</title>
  <content xmlns="http://purl.org/atom/ns#" mode="base64">%s</content>
</entry>''' % (title, base64.encodestring(text))

        return self.atom_request('POST', post_uri, entry)

# 使い方
lb = LdBlog()
lb.credentials('cms.blog.livedoor.com', 'your username', 'your password')
print lb.post_blog(your blog_id, 'てすと', 'てすとだよんだよん')

おまけ:フォトライフあっぷろーだーはこんな感じ

class HatePho(AtomClient):
    def upload_photo(self, title, filepath):
        entry = '''<entry xmlns="http://purl.org/atom/ns#">
  <title>%s</title>
  <content mode="base64" type="image/jpeg">%s</content>
</entry>'''
        photo = base64.encodestring(open(filepath, "rb").read())
        return self.atom_request('POST', '/atom/post', entry % (title, photo))

# 使い方
hp = HatePho()
hp.credentials('f.hatena.ne.jp', 'your username', 'your password')
print hp.upload_photo('Pythonで投稿テスト', './sample.jpg')