2008/03/18


fukaz55さんの所に置いてあった「Amazon Web Services から情報を取得する blosxom 向けプラグイン」を貰ってきて AWSWORD:ほにゃらら: ※「ほにゃらら」は英数字もしくは「_」
と指定出来るようにした。
これまでの様に ASIN:4844322893 と書けば

となるし
AWSWORD:perl: と書けば
AWSWORD:perl:
となる。
結果は一覧されるうちの先頭で表示され、キャッシュは全件「検索語.xml」で保存される。ファイル名の都合で英数字+「_」が制限になってます。
なおblosxom::templateを使ってないのは、mobrowserと干渉しても構わないようにです。
パッチは以下の通り。
--- awsxom.orig Thu Nov 30 22:12:17 2006
+++ awsxom  Tue Mar 18 09:32:22 2008
@@ -57,17 +57,20 @@
 
    # ASIN/ISBNが書かれていたら置き換える
    # テンプレート指定版
-   s/(?:ASIN|ISBN):([A-Z0-9]{10}):(.*?):/to_html($1,$2)/ge;
+   s/(?:ASIN|ISBN):([A-Z0-9]{10}):(.*?):/to_html_asin($1,$2)/ge;
 
    # テンプレート無指定版
-   s/(?:ASIN|ISBN):([A-Z0-9]{10})/to_html($1,$default_template)/ge;
+   s/(?:ASIN|ISBN):([A-Z0-9]{10})/to_html_asin($1,$default_template)/ge;
+
+   # テンプレート無指定版
+   s/(?:AWSWORD):([a-zA-Z0-9_]*?):/to_html_word($1,$default_template)/ge;
 
    return $_;
 }
 
 # ---------------------------------------------------------------------
 # ASINからAmazonのアフィリエイト用HTMLを作成
-sub to_html {
+sub to_html_asin {
    my ($asin, $template) = @_; # ASINとテンプレ名称
    my $cache = "$cachedir/$asin.xml";
    my $url = "http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&SubscriptionId=$devkey&AssociateTag=$asoid&Operation=ItemLookup&ItemId=$asin&ResponseGroup=Medium,Offers";
@@ -90,8 +93,57 @@
    # テンプレートを展開。エラーの場合はエラー文字列を返す
    my $form;
    if (!defined($detail{"ErrorMsg"})) {
-       $form = &$blosxom::template($blosxom::path, $template, 'html');
-       $form =~ s/\$(\w+)/$detail{$1}/ge;
+       #$form = &$blosxom::template($blosxom::path, $template, 'html');
+        my $fh = new FileHandle;
+        if ($fh->open("< $blosxom::datadir/$template.html")) {
+            $form = join '', <$fh>;
+           $form =~ s/\$(\w+)/$detail{$1}/ge;
+            $fh->close();
+        }
+   }
+   else {
+       $form = "<p>" . $detail{"ErrorMsg"} . "</p>";
+   }
+
+   return $form;
+}
+
+# ---------------------------------------------------------------------
+# ASINからAmazonのアフィリエイト用HTMLを作成
+sub to_html_word {
+   my ($word, $template) = @_; # ASINとテンプレ名称
+   my $cache = "$cachedir/$word.xml";
+   my $url = "http://webservices.amazon.co.jp/onca/xml?Service=AWSECommerceService&SubscriptionId=$devkey&AssociateTag=$asoid&Operation=ItemSearch&Keywords=$word&SearchIndex=Books&ResponseGroup=Medium,Offers";
+   my $outfile = "$cachedir/$word.html";
+
+   # 取り込み直す必要はあるか?
+   if (!(-e $cache) || (-M $cache > ($EXPIRE / 24))) {
+   # AWSから情報を取得してキャッシュファイルに保存
+       # UserAgent初期化
+       my $ua = new LWP::UserAgent;
+       $ua->agent($ua_name);
+       $ua->timeout(60);
+       my $rtn = $ua->mirror($url, $cache);
+   }
+
+   # キャッシュからXMLを読み込んで解析
+   my $content = getFile($cache);
+    $content =~ s!.*?(<Item>.*?</Item>).*!$1!is;
+   my $asin = "";
+    $asin = $1 if ($content =~ /<ASIN>([^<]*)<\/ASIN>/);
+    return "" if !$asin;
+   my %detail = parseXML($content, $asin);
+
+   # テンプレートを展開。エラーの場合はエラー文字列を返す
+   my $form;
+   if (!defined($detail{"ErrorMsg"})) {
+       #$form = &$blosxom::template($blosxom::path, $template, 'html');
+        my $fh = new FileHandle;
+        if ($fh->open("< $blosxom::datadir/$template.html")) {
+            $form = join '', <$fh>;
+           $form =~ s/\$(\w+)/$detail{$1}/ge;
+            $fh->close();
+        }
    }
    else {
        $form = "<p>" . $detail{"ErrorMsg"} . "</p>";
ちなみに、先日図書館で見つけた本で面白いの見つけた。
子供向け絵本らしいが、ちょっと笑った。
Posted at by



2008/03/17


vimではあまり使い道がないだろうけど...
スクリプトは " DO NOT EDIT
scriptencoding utf-8
let s:self = expand("<sfile>")
com! UseDataToken exe join(map(remove(readfile(s:self),5,8),"strpart(v:val,1)"),"|")
"__DATA__
"silent! unlet datatoken
"let datatoken=readfile(expand("<sfile>"))
"cal remove(datatoken,0,search("^\"__DATA__$")-1)
"cal map(datatoken,"strpart(v:val,1)")
こんな感じで使う側はこんな感じ "source datatoken.vim
UseDataToken

silent! unlet d
let d = eval(join(datatoken))
echo d.author
echo d.version
echo d.date

"__DATA__
"{
"'author': 'mattn <mattn.jp@gmail.com>',
"'version': '0.001',
"'date': 'Mon, 17 Mar 2008'
"}
perlの様にファイルハンドルでないのが気持ち悪いか。
追記
タイトル変だったので直した
Posted at by




id:TAKESAKOさんのブックマークから
APIチュートリアル - Lingr Group on Hatena
API Tutorial in Lingr Developer Wiki
を見つけた。さっそくpythonでモジュール作った。(既にありそう...)
セッションの作成、入室、発言、退室をメソッドとして公開しています。
セッションの破棄はデストラクタでやってます。使い方は、__main__を参照。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Lingr API Module
"""
import httplib
import urllib
from xml.dom import minidom

__author__ = 'mattn <mattn.jp@gmail.com>'
__url__ = 'http://mattn.kaoriya.net/'
__version__ = "0.01"

"""
Lingr API Class
"""
class LingrAPI:
  """
  initialize class variables and create session.
  """
  def __init__(self, api_key, nickname):
    self.api_key = api_key
    self.nickname = nickname
    self.session = None
    self.conn = httplib.HTTPConnection("www.lingr.com")
    self.conn.request('POST', '/api/session/create/',
        body = "api_key=%s" % urllib.quote(api_key))
    response = self.conn.getresponse()
    data = response.read()
    doc = minidom.parseString(data)
    if doc.getElementsByTagName('status')[0].childNodes[0].data != 'ok':
      raise Exception({
          'code' : doc.getElementsByTagName('code')[0].childNodes[0].data,
          'message' : doc.getElementsByTagName('message')[0].childNodes[0].data})
    self.session = doc.getElementsByTagName('session')[0].childNodes[0].data

  """
  destroy session.
  """
  def __del__(self):
    if self.session:
      import urllib
      from xml.dom import minidom
      self.conn.request('POST', '/api/session/destroy',
          body = "session=%s" % urllib.quote(self.session))
      response = self.conn.getresponse()
      data = response.read()
      doc = minidom.parseString(data)
      if doc.getElementsByTagName('status')[0].childNodes[0].data != 'ok':
        raise Exception({
            'code' : doc.getElementsByTagName('code')[0].childNodes[0].data,
            'message' : doc.getElementsByTagName('message')[0].childNodes[0].data})

  """
  enter room and return room_id
  """
  def enter_room(self, room_id):
    self.conn.request('POST', '/api/room/enter',
        body = "session=%s&id=%s&nickname=%s"
            % (urllib.quote(self.session), urllib.quote(room_id), urllib.quote(self.nickname)))
    response = self.conn.getresponse()
    data = response.read()
    doc = minidom.parseString(data)
    if doc.getElementsByTagName('status')[0].childNodes[0].data != 'ok':
      raise Exception({
          'code' : doc.getElementsByTagName('code')[0].childNodes[0].data,
          'message' : doc.getElementsByTagName('message')[0].childNodes[0].data})
    return doc.getElementsByTagName('ticket')[0].childNodes[0].data

  """
  say message using ticket.
  """
  def say(self, ticket, message):
    self.conn.request('POST', '/api/room/say',
        body = "session=%s&ticket=%s&message=%s"
            % (urllib.quote(self.session), urllib.quote(ticket), urllib.quote(message)))
    response = self.conn.getresponse()
    data = response.read()
    doc = minidom.parseString(data)
    if doc.getElementsByTagName('status')[0].childNodes[0].data != 'ok':
      raise Exception({
          'code' : doc.getElementsByTagName('code')[0].childNodes[0].data,
          'message' : doc.getElementsByTagName('message')[0].childNodes[0].data})
    return doc.getElementsByTagName('occupant_id')[0].childNodes[0].data

  """
  exit room
  """
  def exit_room(self, ticket):
    self.conn.request('POST', '/api/room/exit',
        body = "session=%s&ticket=%s"
            % (urllib.quote(self.session), urllib.quote(ticket)))
    response = self.conn.getresponse()
    data = response.read()
    doc = minidom.parseString(data)
    if doc.getElementsByTagName('status')[0].childNodes[0].data != 'ok':
      raise Exception({
          'code' : doc.getElementsByTagName('code')[0].childNodes[0].data,
          'message' : doc.getElementsByTagName('message')[0].childNodes[0].data})
    return doc.getElementsByTagName('status')[0].childNodes[0].data

#  def find_room(title):
#    self.conn.request('GET', '/search/rooms',
#        body = "query=%s" % urllib.quote(title))
#    response = self.conn.getresponse()
#    data = response.read()

if __name__ == '__main__':
    import sys
    if len(sys.argv) < 2: sys.exit()
    api_key = sys.argv[1]
    nickname = sys.argv[2]
    room_id = sys.argv[3]
    message = sys.argv[4]

    api = LingrAPI(api_key, nickname)
    ticket = api.enter_room(room_id)
    api.say(ticket, message)
    api.exit_room(ticket)
room_idは部屋の検索から検索して、その部屋のURLの最後の部分がIDになります。
今のところbot的な用途でしか使えない程のメソッドしか出してませんが、暇があればメソッドを追加していくかも。

あと、codereposに置いておくので良かったら弄って下さい。
Posted at by