アンケートご協力のお願いgihyo.jpでは,2010年度に向けて豪華プレゼントが当たる読者属性アンケートを実施しております。ご協力ください。

gihyo.jp » WEB+DESIGN STAGE » 連載 » MetaGatewayに見る次世代Webサービス » 第4回 プラグイン実装でわかるMetaGatewayのコンセプト

MetaGatewayに見る次世代Webサービス

第4回 プラグイン実装でわかるMetaGatewayのコンセプト

Web APIに柔軟に対応するために

MetaGatewayは,他のブログエディタではサポートしていないさまざまなサービスなどを,すべて同じように操作することができます。具体的には「対応サービスとサポートする機能」を参照してください。

さらにこれらのサービスだけでなく,Google Mapや各種アフィリエイト,その他さまざまなAPIを利用して,外部サイトとのマッシュアップを行っています。数だけでいえば,ある意味究極のマッシュアップサービスかもしれません。

MetaGatewayでは新しいサービス等が増えても,非常に簡単に機能追加が可能になるように注意して設計されています。APIや認証などさまざまなプラグインを配置すれば対応できるような形です。

たとえば,APIのプラグインであれば,Twitterならtwitter.py, mixiならmixi.pyというコードの中に,サービスに依存するコードがすべて集約されています。問題の切り分けがしやすく,メンテナンスコストが低い構成というのを常に意識しています。

実際はファイルを置いただけで機能を追加できるようにでもできますが,ファイルのリスティングなどのパフォーマンスをちょっとでも稼ぐために,プラグインモジュールの__init__.pyにリスト1のようなデータを定義しているので,そこは合わせて修正する必要はあります。

リスト1

SERVICE_SUPPORTS = [
    {
        'key':'twitter',
        'api':API_TYPE_TWITTER,
        'auth':AUTH_TYPE_BASIC,
        'type':SERVICE_TYPE_NO_REQUIRE,
    },
    {
        'key':'hatena_haiku',
        'api':API_TYPE_HATENA_HAIKU,
        'auth':AUTH_TYPE_BASIC,
        'type':SERVICE_TYPE_NO_REQUIRE,
    },
    ...
]

MetaGatewayのプラグイン実装

まずはMetaGatewayのコードを実際に出しながら,どういう構造になっているのかを話していこうと思います。まず具体的に,それらのプラグインがどのように実装されているのかを簡単に説明します。例として,マイクロブログに対応するためのプラグイン部分をとりあげます。マイクロブログの代表的なものに,Twitter, はてなハイク,Jaiku,cotobako,Haru.fm,もごもご,piyo,Timelog,Wassr等があります。

まず,すべてのAPIプラグインはApiPlugin抽象クラス(リスト2)からの派生クラスになります。これらのメソッドをオーバーライドすることにより,挙動を制御することができます。インターフェースに関しては,XMLRPCのインターフェース(blogger,metaweblog, movabletype, typepad)とatompubを抽象化したあとに,各種APIを参考にすべてを表現するために足りないものを追加したものになります。

リスト2

class ApiPlugin():
    DEFAULT_CHANNEL_ID = '1'

    def __init__(self, end_point, auth):
        self.end_point = end_point
        self.auth = auth
        self.error_msg = None

    def isAuthed(self):
        return False
    def getUserInfo(self, params):
        return False
    def getUserChannels(self, params):
        return False
    def getPost(self, params):
        assert( params.has_key('post_id') )

        post_id = params[ 'post_id']
        documents = self.getRecentPosts(params)
        for document in documents:
            if( document['post_id'] == post_id ):
                return document

        raise ApplicationException()

    def getRecentPosts(self, params):
        return []
    def createPost(self, params):
        raise ApplicationException()
    def isCreatePost(self):
        return True
    def deletePost(self, params):
        raise ApplicationException()
    def editPost(self, params):
        raise ApplicationException()

    def createUploadFile(self, params):
        raise ApplicationException()
    def getUploadFiles(self, params):
        raise ApplicationException()
    def deleteUploadFile(self, params):
        raise ApplicationException()

    def getCategories(self, params):
        return []
    def getPostCategories(self, params):
        return []
    def setPostCategories(self, params):
        return True
    def getTrackbackPings(self, params):
        return []
    def canTrackback(self, params={}):
        return False
    def rebuildSite(self, params):
        return True

    def formatTitle(self, title = ''):
        return title
    def formatBody(self, body = ''):
        return body

    boundary = None
    def makeBoundary(self):
        if( self.boundary == None ):
            self.boundary = '----------------------------' + str(int(time.time()))
        return self.boundary

    MULTIPART_CONTENT_TYPE = 'multipart/form-data'
    def makeMultipartHeader(self):
        content_type = ("%s; boundary=%s" % (self.MULTIPART_CONTENT_TYPE, self.makeBoundary()))
        return {'Content-Type':content_type}

    def makeMultipartBody(self, params, exinfo={}):
        boundary = self.makeBoundary()
        orderd = sorted(params.keys())
        s = ''
        for k in orderd:
            s += ( '--' + boundary + "\r\n" )
            if( exinfo.has_key(k) ):
                s += ('Content-Disposition: form-data; name=\"%s\"; filename="%s"\r\n' % (k, exinfo[k]['filename']) )
                s += ('Content-Type: %s' % (exinfo[k]['content-type']) + "\r\n")
                s += ('Content-Length: %s' % len(params[k]) + "\r\n\r\n")
            else:
                s += ('Content-Disposition: form-data; name=\"%s\"\r\n\r\n' % (k) )
            s += (params[k] + "\r\n")
        s += ( '--' + boundary + '--\r\n\r\n' )
        return s

リスト2のコードは,だいたい先に挙げたインターフェースと1対1にマップされているのですが,いくつかわかりにくいものもあるので説明しておきます。

isAuthedは,getUserChannels時に認証できない場合,実際に記事を取得してみて認証を行うためにあります(ただ,実際には書き込んでみないと合っているかどうが一切かわからないサイトも多く,「開発者泣かせ」も結構あります)。

isCreatePostは,本当にデータが書き込まれたかをチェックするためにあります(Twitterなどでは,連続で同じステータスを書き込むと成功であるにもかかわらず,1つにまとめられてしまい書き込まれないため)。

rebuildSiteは,MovableTypeのようにmt.publishPostしないと再構築されないサイトが数多くあるので,そのためにあります。formatTitle, formatBodyはMicroformatsなどが必要なサイトの場合,そこを変換するためにあります。さらに,Google App Engineのfetchでは,postのContent-Typeが常にapplication/x-www-form-urlencodedのになってしまうので,multipart/form-dataできるようにメソッドを追加しています。

著者プロフィール

Techmonkey

コンビのWebビジネスプロデューサー。

社内マイクロブログ - しゃべるエンタープライズサーチ - どこかな?次世代投稿管理サービス - MetaGateway などを2人で開発。今はクラウド型の究極のチームコラボレーションソフトウェアを開発中です。

コメント

コメントの記入

パスサポ

多数の情報処理技術者試験対策書籍の発行実績を誇る技術評論社がお届けする,資格試験合格サイト「めざせ! 情報処理試験 パスサポ」が開設されました。

ピックアップ

サクセスストーリーに続く,快適サーバー運用管理のヒント!

データの増大,煩雑な管理,システムダウン,セキュリティなど,迫りくる課題からシステム管理者の負担を軽くするポイントを解説します。

gihyo.jp インフラエンジニア情報局

ネットワークやITにかかわるあらゆる業種で必要とされるインフラエンジニアに向けた技術情報や心構え,その魅力について多角的に紹介。

テストエンジニア ステーション

いま,ITに関わるあらゆる開発業務で注目されつつあるテスト系エンジニアをターゲットにしたコンテンツサイトを展開します。

一行クイックアンケート

gihyo.jpで取り上げてほしいネタは?

※検索はページ右上の検索ボックスをご利用ください。

その他の連載

読むウェブ ~本とインタラクション

ディスプレイで読む活字とそのインタラクション(interaction:相互作用)について,最新Webを紹介しながら読み解いていく。

いま,見ておきたいウェブサイト

この連載では,国内外の最新のウェブサイトを隔週更新で取り上げ,これら最新サイトの特徴や素晴らしい部分を,さまざまな角度から解説していきます。

Windows phoneアプリケーション開発入門

Windows Marcketplace for Mobileがサービス開始され,作成したアプリケーションを個人でも世界をターゲットに公開できる環境が整ってきました。これを機にWindows phoneアプリケーションの開発をしてみませんか?

ここは知っておくべき!Windows Server 2008技術TIPS

5年ぶりのサーバOSとなったWindows Server 2008が出荷されて早2年。2009年にはR2が出荷され,再び注目を集めています。発売前から実施したトレーニングによって感じた,インフラエンジニアの方々に知っておいていただきたい機能を中心にご紹介します。

キーパーソンが見るWeb業界

本連載はWeb Site Expert/gihyo.jpとの連動企画です。阿部淳也, 長谷川敦士, 森田雄のお三方による,Web業界をテーマにした座談会です。

きたみりゅうじの聞かせて珍プレー

ソフトウェア開発の現場で体験したトホホな失敗,思わずうなる珍プレーをきたみりゅうじ氏が四コママンガで紹介。みなさんからの投稿もお待ちしてます!

ActionScript 3.0で始めるオブジェクト指向スクリプティング

野中文雄氏が,簡単なスクリプトは書いたことがあるという初級者を対象に,ActionScript 3.0の基本からクラス定義までを解説します。

まだ間に合う「ITパスポート」受験対策 原山先生の短期合格塾

この連載では,4月18日のITパスポート試験の受験に向けて,短い期間で効率良く受験対策を行う方法や,確実に得点するための裏ワザなどを伝授していきます。

連載一覧

gihyo.jp

  • DEVELOPER STAGE
  • ADMINISTRATOR STAGE
  • WEB+DESIGN STAGE
  • LIFESTYLE STAGE
  • SCIENCE STAGE
  • NEWS & REPORT

書籍案内

  • 新刊書籍
  • 書籍ジャンル一覧
  • 書籍シリーズ一覧
  • 新刊ピックアップ
  • ロングセラー
  • 電脳会議

定期刊行物一覧

  • Software Design
  • WEB+DB PRESS
  • Web Site Expert
  • 組込みプレス