Python ではてなダイアリーに投稿
Python の atompub で使いやすいライブラリがみつからなかったので
自前でゴリゴリ
#!/usr/bin/env python # -*- coding: utf-8 -*- # http://d.hatena.ne.jp/keyword/%a4%cf%a4%c6%a4%ca%a5%c0%a5%a4%a5%a2%a5%ea%a1%bcAtomPub import base64 import random import sha import urllib2 import urllib from datetime import date,datetime import sys # 2.5 までは 201 がエラー扱いになっちゃうので if sys.version_info[0] < 3 and sys.version_info[1] < 6: def __http_response(self, request, response): code, msg, hdrs = response.code, response.msg, response.info() if not (200 <= code < 300): response = self.parent.error( 'http', request, response, code, msg, hdrs) return response urllib2.HTTPErrorProcessor.http_response = __http_response class WSSEHeader(urllib2.BaseHandler) : def __init__(self, userid, passwd): self.userid = userid self.passwd = passwd def get_nonce(self): private = str(random.random()) now = datetime.now() timestamp = now.strftime('%Y-%m-%dT%H:%M:%SZ') return '%s %s' % (timestamp, sha.new('%s:%s' % (timestamp, private)).hexdigest()) def get_wsse(self): nonce = self.get_nonce() base64_encoded_nonce = base64.encodestring(nonce).replace('\n', '') now = datetime.now() post_creation_time = now.strftime('%Y-%m-%dT%H:%M:%SZ') password_digest = base64.encodestring(sha.new(nonce + post_creation_time + self.passwd).digest()).replace('\n', '') return 'UsernameToken Username="%s", PasswordDigest="%s", Created="%s", Nonce="%s"' \ % (self.userid, password_digest, post_creation_time, base64_encoded_nonce) def http_request(self,req): req.add_header('X-WSSE', self.get_wsse()) req.add_header('User-agent', 'yoshiori\'s test(yoshiori@gmail.com)') return req class HatenaDiary: def __init__(self, userid, passwd): self.userid = userid self.passwd = passwd self.url = 'http://d.hatena.ne.jp/%s/atom/' % userid def postEntry(self, title, text, isDraft=False): entry = '''<?xml version="1.0" encoding="utf-8"?> <entry xmlns="http://purl.org/atom/ns#"> <title><![CDATA[%s]]></title> <content type="text/plain"><![CDATA[%s]]></content> </entry> ''' % (title,text) print entry url = self.url + 'draft' if isDraft else self.url + 'blog' return self._open(url,entry) def getEntrys(self): return self._open(self.url + 'blog') def get(self): return self._open(self.url) def _open(self,url,param=None): opener = urllib2.build_opener( WSSEHeader(self.userid, self.passwd)) return opener.open(url,param) if param else opener.open(url) if __name__ == '__main__': from pit import Pit hatena_conf = Pit.get('hatena.ne.jp',{'require' : {'userid':'Your hatena.ne.jp userid','password':'Your hatena.ne.jp password'}}) diary = HatenaDiary(hatena_conf['userid'],hatena_conf['password']) print diary.postEntry('日本語','**日本語\n-ほげ\n-ふぉお\n>|python|\nimport sys\n||<',True)