Skip to content

Instantly share code, notes, and snippets.

@yat1ma30
Last active March 24, 2019 08:09
Show Gist options
  • Save yat1ma30/6448440 to your computer and use it in GitHub Desktop.
Save yat1ma30/6448440 to your computer and use it in GitHub Desktop.
はてなブログAtomPub APIを使った簡易投稿クライアントアプリ
# -*- coding: utf-8 -*-
import base64
import datetime
import hashlib
import random
import requests
import time
USER_NAME = "******" # はてなID (ex: "ottati")
BLOG_ID = "******.hatenablog.com" # ブログID (ex: "ottati.hatenablog.com")
API_KEY = "**********" # APIキー ブログ管理画面 => 詳細設定より取得
TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:app="http://www.w3.org/2007/app">
<title>{title}</title>
<author><name>{name}</name></author>
<content type="text/plain">{content}</content>
<updated></updated>
<app:control>
<app:draft>{draft}</app:draft>
</app:control>
</entry>
"""
def create_wsse(username, password):
"""X-WSSEヘッダの内容を作成
ユーザネームとAPIキーからWSSE認証用文字列を作成し、返します。
Args:
@username: はてなID
@password: はてなブログで配布されるAPIキー
Returns:
WSSE認証用文字列
"""
nonce = hashlib.sha1(str(time.time()) + str(random.random())).digest() # セキュリティトークン
created = datetime.datetime.now().isoformat() + "Z" # Nonceの作成時刻
digest = base64.b64encode(hashlib.sha1(nonce+created+password).digest()) # PasswordDigest
# WSSE認証用文字列として整形して返す
return 'UsernameToken Username="{0}", PasswordDigest="{1}", Nonce="{2}", Created="{3}"'.format(username, digest, base64.b64encode(nonce), created)
def fix_encoding(string):
"""Shift_JISであればUTF-8に修正する関数"""
try:
return string.decode('shift-jis').encode('utf-8')
except:
return string
if __name__ == "__main__":
"""メイン処理"""
print u"\nはてぽす! - はてなブログAtomPubを使った簡易投稿アプリ\n"
title = fix_encoding(raw_input("Title: ")) # タイトル
content = fix_encoding(raw_input("Content: ")) # 本文
entry = TEMPLATE.format(
title = title, # 記事タイトル
name = USER_NAME, # 記事著者
content = content, # 記事本文
draft = "yes" # 下書きとして投稿 (yes / no)
)
url = "http://blog.hatena.ne.jp/{0}/{1}/atom/entry".format(USER_NAME, BLOG_ID) # リクエストURL
wsse = create_wsse(USER_NAME, API_KEY) # WSSE認証用文字列
r = requests.post(url, data=entry, headers={'X-WSSE': wsse}) # POST
if r.status_code == 201: # 投稿成功判定
print u"\n投稿しました。" # 成功メッセージ
else:
print u"\n投稿に失敗しました。" # 失敗メッセージ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment