ゴミ箱の中のメモ帳

まだ見ぬ息子たちへ綴る手記

はてなブログの記事の編集モードを一括で変更する

昨日の記事で「はてなブログ エクスポートスクリプト in Python」を作ったが、その中で「エクスポートしたものをはてなブログにインポートすると編集モードが見たままモードでインポートされる」と書いたが、それの対策スクリプト

これははてなブログの仕様のようだが、はてなブログのAtomPub APIから記事を上書きすると、ブログに設定している編集モードが採用されるとのこと。

これは「はてなブログ Atom Pub」の「ブログエントリの編集」に「新規ブログエントリの投稿と同じく、編集時にもブログに登録された記法が適用されます。」とあることから「仕様」であることがわかる。今気付いたがBloggerのように記事単位で編集モードを変えることはできない様子。

初めてのPython 第3版

初めてのPython 第3版


と言う事でスクリプトは例のごとく最下部に貼りつけておく。これも例のごとく使い方は「はてなブログ AtomPub APIのPython WSSEサンプルコード」と同じ。

注意としては、「全ての記事」を上書きするので全ての記事を設定の編集モードにしてしまう。その為記事数が多いブログではそこそこ時間がかかる可能性がある。また、スクリプトを編集する際は間違ってもHTTP DELETE命令を出さないように注意してほしい。

また、PythonでHTTP PUTをするのが少々手間が掛かる様子であったため、requestsモジュールを使うことにした。pipからインストールできるがこれは便利なものだ。


#!/usr/bin/python


import datetime
import random
import hashlib
import base64
import urllib2
import requests
from xml.dom import minidom

userid = "User ID"
apikey = "API Key"
blogid = "Blog ID"
apiurl = "http://blog.hatena.ne.jp/%s/%s/atom/entry" % ( userid, blogid)



def make_wsse( userid, apikey):
    created_at = datetime.datetime.now().isoformat() + "Z"
    nonce = hashlib.sha1( str( random.random())).digest()
    digest = hashlib.sha1( nonce + created_at + apikey).digest()

    return 'UsernameToken Username="%s", PasswordDigest="%s", Nonce="%s", Created="%s"' % ( userid, base64.b64encode( digest), base64.b64encode( nonce), created_at)


wsse = make_wsse( userid, apikey)
headers = { "X-WSSE": wsse}

url = apiurl
end = False
while True:
    request = urllib2.Request( url, headers=headers)
    response = urllib2.urlopen( request)
    dom = minidom.parseString( response.read())
    links = dom.getElementsByTagName( "link")
    for link in links:
        if link.attributes["rel"].value == "next":
            url = link.attributes["href"].value
            break
    else:
        end = True

    for entry in dom.getElementsByTagName( "entry"):
        entry_links = entry.getElementsByTagName( "link")
        for entry_link in entry_links:
            if entry_link.attributes["rel"].value == "edit":
                edit_url = entry_link.attributes["href"].value

        for node in entry.getElementsByTagName( "hatena:formatted-content"):
            entry.removeChild( node)

        entry.setAttribute( "xmlns", "http://www.w3.org/2005/Atom")
        entry.setAttribute( "xmlns:app", "http://www.w3.org/2007/app")

        new_entry = '<?xml version="1.0" encoding="utf-8"?>\n' + entry.toxml()

        edit_request = requests.put( edit_url, headers={ "Content-Type": "text/xml", "X-WSSE": wsse}, data=new_entry.encode( "UTF-8"))

    if end:
        break

Pythonスタートブック

Pythonスタートブック

パーフェクトPython (PERFECT SERIES 5)

パーフェクトPython (PERFECT SERIES 5)

初めてのPython 第3版

初めてのPython 第3版

エキスパートPythonプログラミング

エキスパートPythonプログラミング

Pythonプロフェッショナルプログラミング

Pythonプロフェッショナルプログラミング