2009年5月16日土曜日

blogger API: blog を ChangeLogメモ のように使う

http://0xcc.net/unimag/1/ で ChangeLogメモを知ってからずっとChangeLogメモを愛用してきたのですが、
  • メモを入力できる場所が一つに限られる
  • 画像データを入力できない
  • 公開できない. そしてあわよくばアフィリエイトとかしてみたい
あたりが物足りなくなってきたので、今更ながらblogを使ってみることにしました。 コマンドラインからさくっと入力できるのがChangeLogメモの利点なので、これをgdata API で作ってみます。 先にオチを言っておくと検索がAPIで公開されてないんですね。残念。
class Blogger:

    def __init__(self, email, password):
        # Authenticate using ClientLogin.
        self.service = service.GDataService(email, password)
        self.service.source = 'blogger.py-1.0'
        self.service.service = 'blogger'
        self.service.account_type = 'GOOGLE'
        self.service.server = 'www.blogger.com'
        self.service.ProgrammaticLogin()

        # Get the blog ID for the first blog.
        feed = self.service.Get('/feeds/default/blogs')
        self_link = feed.entry[0].GetSelfLink()
        if self_link:
            self.blog_id = self_link.href.split('/')[-1]

    def createPost(self, title, content, author_name, label, is_draft=False):
        # Create the entry to insert.
        entry = gdata.GDataEntry()
        entry.author.append(atom.Author(atom.Name(text=author_name)))
        entry.title = atom.Title(title_type='html', text=title)
        entry.content = atom.Content(content_type='html', text=content)
        if label:
            entry.category.append(atom.Category(term=label,
                scheme="http://www.blogger.com/atom/ns#"))
        if is_draft:
            control = atom.Control()
            control.draft = atom.Draft(text='yes')
            entry.control = control

        # Ask the service to insert the new entry.
        return self.service.Post(entry,
            '/feeds/' + self.blog_id + '/posts/default')
ほとんど blogger api に付属のサンプルコードそのままなんですが、これを次のように使います。
from gdata import service
import gdata
import atom
import os
import re
import sys
from ConfigParser import SafeConfigParser
from optparse import OptionParser
from tempfile import NamedTemporaryFile

PasswdFile = os.path.join(os.environ.get('HOME'), '.password')

def sub_url(text):
    pattern = r'''
    \b
    (
     (https?|ftp):[\w/#~:.?+=&%@!\-]+?
    )
    (?=
     [.:?\-]*
     (?:[^\w/#~:.?+=&%@!\-] | $)
    )'''

    regex = re.compile(pattern, re.IGNORECASE|re.VERBOSE)
    result = regex.sub(r'\1', text)

    return result

def createBlogData():
    # edit temp blog data file 
    temp_file = NamedTemporaryFile(suffix='.txt', prefix='blogger_py')
    editor = os.environ.get('EDITOR')
    if editor == '':
        editor = 'vi' # XXX: default
    stat = os.spawnlp(os.P_WAIT, editor, editor, temp_file.name)
    if stat != 0:
        raise EditError, 'edit tempfile failed: %s %s' % (editor, temp_file.name)

    # read blog data from temp file, publish a public post.
    title = temp_file.readline().rstrip('\r\n')
    label = temp_file.readline().strip()
    if label == '':
        _title = title.split(':') # title == 'LABEL: string'
        if len(_title) >= 2:
            label = _title[0]
    content = temp_file.read()
    author_name = "zakkie3"

    content = sub_url(content)
    title = title.decode('euc-jp')
    content = content.decode('euc-jp')

    temp_file.close()  # temp_file will delete automatically

    return title, content, author_name, label

def main():
    email = ''
    password = ''
    author = ''

    # parse passord file
    cParser = SafeConfigParser()
    is_exists = cParser.read(PasswdFile)
    if is_exists and cParser.has_section('blogger.py'):
        if cParser.has_option('blogger.py', 'email'):
            email = cParser.get('blogger.py', 'email')
        if cParser.has_option('blogger.py', 'password'):
            password = cParser.get('blogger.py', 'password')
        if cParser.has_option('blogger.py', 'author'):
            author = cParser.get('blogger.py', 'author')

    # parse command-line options
    oParser = OptionParser()
    oParser.add_option("-e", "--email", dest="email", help="E-mail address");
    oParser.add_option("-p", "--password", dest="password",
        help="E-mail address");
    oParser.add_option("-u", "--author", dest="author",
        help="Blog author");
    oParser.set_description('follow options can be set by ~/.password.')

    option, args = oParser.parse_args()
    if option.email: email = option.email
    if option.password: password = option.password
    if option.author: author = option.author

    if email == '' or password == '' or author == '':
        oParser.print_help()
        sys.exit(2)

    blogger = Blogger(email, password)
    title, content, label = createBlogData()
    blogger.createPost(title, content, author, label)
~/.password に blogger のアカウント情報を以下のように書いておきます。
[blogger.py] email: EMAIL@example.com password: PASSWORD author: zakkie3
やっていることは
  • EDITORを起動し、temporary file を編集
  • temporary fileの1行目をtitle
  • 2行目をlabel, なければtitleの':'の前をlabel
  • 3行目移行を本文
  • 本文のうち、URLっぽい文字列はリンクにする
  • EUC-JP固定
もっとかっこいいやり方があるんだろうけど、自分用なのでこれで十分。

0 件のコメント:

コメントを投稿