2009年10月アーカイブ

飲み屋に行ったら飲み屋のオヤジに雑誌の切り抜きを渡されて、これをワープロ書きにして見やすく大きく印字しろって言うんだ。どうやら、飲み屋の客にうんちく傾けたいらしい。

で、入力した。

見ると縁起が良い夢ベスト102
300pt富士三十五68pt二毛作六十九34ptひと間違え
200pt三十六67pt自分探し七十33ptひざまくら
100pt茄子三十七66ptうるち米七十一32pt三白眼
99pt三十八65ptえら呼吸七十二31pt深爪
98pt煙草三十九64ptなわばり争い七十三30pt痴話喧嘩
97pt座頭四十63pt天日干し七十四29ptぬか喜び
96pt四十一62pt思い出し笑い七十五28pt百日咳
95ptぬか四十二61pt金のしゃちほこ七十六27pt生返事
94pt化粧四十三60pt勇み足七十七26pt狐の嫁入り
93pt骨折四十四59pt手づかみ七十八25pt衝動買い
十一92pt茶だんす四十五58ptどんぶり勘定七十九24pt金縛り
十二91pt発熱四十六57pt鰹のたたき八十23pt煎餅布団
十三90pt仇討ち四十七56pt直談判八十一22ptききん
十四89pt腹痛四十八55pt平あやまり八十二21pt帳尻合わせ
十五88pt返品四十九54pt乳しぼり八十三20pt徹夜明け
十六87pt蒸し海老五十53pt迷い箸八十四19pt口べらし
十七86pt空耳五十一52ptあいこ八十五18pt寺子屋
十八85ptへらず口五十二51pt雨宿り八十六17ptおろし金
十九84pt御用聞き五十三50pt消し忘れ八十七16pt手さげ袋
二十83pt乾燥肌五十四49ptがら空きの芝居小屋八十八15pt打ちこわし
二十一82pt貧乏ゆすり五十五48ptわらべうた八十九14pt朝寝坊
二十二81pt雪おろし五十六47pt四つんばい九十13pt金魚売り
二十三80pt大あくび五十七46pt下駄九十一12pt道場やぶり
二十四79ptななめ読み五十八45pt孤独九十二11pt手前みそ
二十五78ptお説教五十九44ptお手つき九十三10pt越後屋
二十六77pt厚着六十43pt肝吸い九十四9pt上目遣い
二十七76pt六十一42pt口内炎九十五8pt参勤交代
二十八75pt踊り食い六十二41pt送り迎え九十六7pt塹壕
二十九74pt地引き網漁六十三40pt開けっぱなし九十七6pt鎖国
三十73ptふんどし六十四39pt涙目九十八5pt棚卸し
三十一72pt五徳六十五38pt昼あんどん九十九4pt奥二重
三十二71pt箸置き六十六37pt泥試合3pt目安箱
三十三70ptちょんまげ六十七36pt化けちょうちん百一2pt土砂崩れ
三十四69pt痩せ我慢六十八35pt一家団欒百二1pt金屏風

おおひなたごう「犬のジュース屋さんZ」75杯目より


んと、一富士から六座頭までは、江戸時代の国語辞典(俗語含む)「俚言集覧(りげんしゅうらん)」に載っていることは確認できた。7から先が出典不明。嘘(創作)だと言ってよ、バーニィ!

というわけでこれネタだろ!

これがどうやって使われているかは、

を読んでみてください。4巻あたりに収録されていそうだけど分からん。

もうひとつ、

見ると縁起が悪い夢ワースト6
-300pt禿
-200pt
-100ptふて寝
-99pt
-98pt面皰
-97pt土砂崩れ

おおひなたごう「犬のジュース屋さんZ」75杯目より


というのも載っていた。これも漫画の中でどう使われているかは読んでみてもらうことで。ptっていうのがポイント。

AcrobatでWebからページごとのデータを分割して取得できるよう、サーバがHTTP/1.1のRangeに対応していない場合代わりにUAからの要求範囲を受け取ってPerlでPDFの特定部位を切り出して返すリダイレクトCGIなんですね。

http://www.adobe.com/jp/products/acrobat4/library/scripts/bsunix.txt

(2013-05-25 10:26追記)

上記URLはリンク切れなので、Weyback Archiveのリンクと、転記をしておきます。それにしてもアドビの人は、後世に伝えることに関して無関心すぎる。

http://web.archive.org/web/20000615073408/http://www.adobe.com/support/techguides/acrobat/byteserve/bsunix.txt

#!/usr/bin/perl
#!/usr/local/bin/perl
# byteserver script
# byteserver.pl
# Last updated May 10, 1996
# This script implements the draft "Byte Range Retrieval Extension to HTTP" described at 
# "http://www.w3.org/Protocols/rfc2068/rfc2068". 
# place this script wherever you can run CGIs on your Web server.
# 1) Users should make sure that the script as placed in the cgi-bin
#directory is renamed to byteserver.pl, and has execute permission on 
#a UNIX machine. This is done  by typing: chmod 755 byteserver.pl
#2.) The first line of the byteserver.pl script contains a line of the form
#!<pathname>
#where <pathname> points to
#where perl is found on the system.
#Users should modify this line to suit their system-- on a UNIX machine
#you can find out where perl resides by typing: which perl
#if the above returns /usr/local/bin/perl
#then the first line of the byteserver.pl should read
#!/usr/local/bin/perl
#Note: if executing the command: which perl
#returns the message: perl command not found or something similar it
#means that perl is not installed on your system. You *need* perl to
#use byteserver.pl 
# query is of the form
# http://server/cgi-bin/byteserver.pl/path/name/here
#       with HTTP_RANGE specifying the ranges in the form
#       "bytes=m1-n1,m2-n2,...,mn-nn"
#       /path/name/here is relative to server root
#       m-n are ranges (0 based). If m is absent, means n bytes from EOF, if n
#       is absent, mean first m bytes of the file 
#       "bytes=..." syntax
#       STDOUT the ranges
#       The script issues HTTP1.0 206 Partial Content as a partial
#       content response.     
# Env. variables:
#       PATH_TRANSLATED is the file name
#       CONTENT_TYPE is what the server says is the mime type of file
#       REQUEST_METHOD is the request method i.e. GET, POST etc. (we only accept GET)
#       HTTP_RANGE the byte range request
# Return syntax:
# if no ;bytes= is specified, returns:
#       Accept-ranges: bytes
#       Content-type: <content-type>
#       Content-length: <file-length>
#       <the file itself>
# if ;bytes= specified, returns:
#       
#       HTTP/1.0 206 Partial Content
#       Accept-ranges: bytes
#       Content-type: multipart/x-byteranges; boundary=$boundary
#       < multipart-body >
   
sub badjob {
     
local($mesg) = @_;
     
print "Status: 403 \"BOGUS\"\r\n\r\n";
     
print "<HEAD><TITLE>403 BOGUS</TITLE></HEAD>"; print "<BODY BGCOLOR="#FFFFFF" LINK="#0033CC" VLINK="#800080" ALINK="#FF0000"><H1>403 BOGUS</H1>";
print "<pre>$mesg</pre>\r\n";
print "Bad Request\r\n\r\n";
exit 1;
}
     
     
$path = $ENV{'PATH_TRANSLATED'};
$ranges = $ENV{'HTTP_RANGE'};
     
($file, $query) = split(/;/,$path);
     
$contenttype = $ENV{'CONTENT_TYPE'};
if ($contenttype eq "") 
{ 
        $contenttype = "application/pdf";
}
     
if ((! -r $file) || (length $file <= 3)) 
{ 
        &badjob("file $file not found");
}
     
if ($ENV{'REQUEST_METHOD'} ne 'GET') 
{ # not URL-based query 
        &badjob("METHOD not GET");
}
     
$size = -s $file;
     
if (($query eq "") && ($ranges eq "")) 
{
        # respond that we can do ranges
        print "Accept-ranges: bytes\r\n";
        print "Content-type: $contenttype\r\n"; 
        printf "Content-Length: %d\r\n\r\n", $size; 
        open(FILE, "< $file");
        while(read(FILE, $buffer, 4096)) {
        print STDOUT $buffer;
}
exit 0;
     
} else {
    if ($ranges ne "")
    { 
        $query = $ranges;
        $query =~ s/bytes=//;
    }
    else
    {           
        $query =~ s/\s+//g; # squeeze all whitespace out 
        $query =~ s/bytes=//; 
    }
     
    #check that the ranges are properly formatted 
    @byterangeCheck = split(/[-,=]/,$query); 
    while (defined($fbyte = shift(@byterangeCheck))) {
        $lbyte = shift(byterangeCheck);
        if (($fbyte > 0) && ($lbyte < 0)) {
                &badjob("query range malformed");
        }
        if (($fbyte < 0) && ($lbyte > 0)) {
                &badjob("query range malformed"); 
        }
        if ($fbyte > $lbyte) {
                &badjob("query range malformed");
        }
     
    }
    @byterange = split(/[,]/,$query);
}
     
# print 206 only if called with official syntax   
if ( $ranges ne "" )
{
        print "Status: 206 Partial Content\r\n";
}
# print other header info
$boundary="multipart-boundary";
print "Accept-ranges: bytes\r\n";
print "Content-type: multipart/x-byteranges; boundary=$boundary\r\n\r\n";
     
# Serve up the bytes:
     
open(FILE, "< $file");
while (defined ($range = shift(@byterange))) {
     
    ($fbyte, $lbyte) = split('-', $range); 
    $i = index($range,"-");
    if ($i == 0) { $fbyte = -1; }
    if ($fbyte < 0) {
        $fbyte = $size - $lbyte;
        $lbyte = $size;
    }
    $nbytes = $lbyte - $fbyte + 1;
     
    print "\r\n--$boundary\r\n";
    print "Content-type: $contenttype\r\n";
    printf "Content-Range: bytes %d-%d/%d\r\n\r\n", $fbyte, $lbyte, $size;
     
    seek(FILE, $fbyte, 0);
    read(FILE, $buffer, $nbytes);
    print STDOUT $buffer;
}
     
print "\r\n--$boundary--\r\n";
     
exit 0;

アドビのCS4対応プリントショップのリストのページから、Google Mapsに表示させるやつの4回目。

前回は、アドビのサーバからHTTPステータスコードが200ばっかり返ってくるので、ステータスコードは使えないから、HTTPレスポンスヘッダを見てみよう、ということで、FirefoxのLive HTTP Headersという機能拡張を入れて調べたところ、ヘッダからはコンテンツの更新がわからないということがわかりました。ということは実際に取得してみなくてはわからないと言うことになりますが、どうしよう? ていうところまでやりました。

さて、アドビのサーバは、「取得したデータは取得した側で6時間キャッシュしてね。内容変更はヘッダでは教えてあげないよ。」と言っているわけなので、まず、6時間ごとアドビのサーバから取得すればいい、という方針が立ちます。従って、取得する部分は6時間ごと実行するようにcronに設定すればいいかなあということになります。

また、6時間ごと取得しても、内容に変化がないことがあるのも予想されますので、「内容に変化がない」ことを検出する仕組みを作らなくてはなりません。どうしよう。

そこで、今回は「取得したHTMLの長さを比較する」方法でいきたいと思います。なお、この方法は、AdobeさんがPDFの改変チェックで採用している由緒正しい古式ゆかり方式です。PDFのチェックサムの再計算とか知らなかったとき、ゲームのセーブデータをいじるがごとく手法でPDFをいじっていたのを思い出します。

今回のコードはこんな感じです。

#!/usr/bin/perl
 
# Filename: test3.pl
 
use strict;
use warnings;
use URI::Fetch;
use Cwd;
 
# GETしてきたコンテンツの長さを記録するファイル
my $cwd = getcwd; # カレントディレクトリ
my $length_file = "$cwd/length.txt";
# GETするコンテンツのURL(STATUSが常に200なので
# 内容変更調べるにはコンテンツの大きさを使う)
my $url= 'http://www.adobe.com/jp/print/printshop/';
 
# main
 
my $html = get_html($url);
print "modified:\n" if $html;
 
exit;
 
sub get_html {
  my $url = shift;
  # length.txtから前回取得時のコンテンツの大きさを
  # 取得するよ
  my $length = 0;
  if ( -e $length_file ) {
    open my $fh, '<', $length_file or die $!;
    $length = <$fh>;
    close $fh;
  }
  # Webからコンテンツを取得するよ
  my $ua = new LWP::UserAgent;
  $ua->timeout(10);
  $ua->agent('DTPWiki.jp AdobeJpPrintShopMap/0.1 '
           . '(+http://labo.dtpwiki.jp/printmap/)'
  );
  my $res = URI::Fetch->fetch(
    $url, UserAgent => $ua,
  ) or die URI::Fetch->errstr;
  my $html = $res->content;
  # 今回取得したWebコンテンツの大きさを記録するよ
  my $length_new = length($html);
  {
    open my $fh, '>', $length_file or die $!;
    print $fh $length_new;
    close $fh;
  }
  # 前回と大きさが変わらない場合はundef、
  # 変わっている場合はコンテンツを返すよ
  return ( $length == $length_new
             ? undef
             : $html
         );
}
 
__END__

実行結果:

$ perl test3.pl
modified:
$ perl test3.pl
$ cat length.txt
188685$ cat > length.txt 
120000
$ perl test3.pl
modified:
$ cat length.txt
188685$

1回目は更新と検出、2回目は変更なしと検出、length.txtファイルにはコンテンツのサイズが入っています。意図的にlength.txtファイルを書き換えてやると、その次に取得した場合は変更ありと検出されていることが確認できました。

ちなみに、length.txtに記録されるのは、HTTPレスポンスヘッダのContent-Lengthの値ではなくて、実際データとして利用できるコンテンツのサイズです。アドビのサーバからは、GZipエンコーディングで圧縮された状態で送られてくるのですが、URI::Fetchが自動的に伸張するのですね。

泥臭いですが何とかアドビさんからHTMLをGETするところができました。

次回は、いったんWebやHTTPから離れて、HTMLを解析するところをやりたいと思います。


(2009-10-30 14:00修正)

<del>由緒正しい</del><ins><a href="http://www3.airnet.ne.jp/gomimemo/tmron/yukari.htm" target="_blank">古式ゆかり</a>な</ins>

ブックマークのコメントで、「ダメな手法を真似したらダメ。ギャグのつもりならネタだと分かるようにかいてほしい」とOtsuneさんから指摘があったので、ギャグにしました。念のため、古式ゆかりは本命キャラ攻略失敗時に出てくるキャラです。

アドビの擁護をするならば、PDFはバイトサービングなどの細切れで転送される用途もあったため、ファイル全体のハッシュ値でファイルの健全性を確認する手法は使えなかったのかもなあと思っています。

2009年11月7日に、CSS Nite in NIIGATA Vol.1があるということで、「あー外に着ていく服ないなー」とおもって服を買ってきてこれで万全と思ってさあ申し込もうかと思ってその前に会社の出勤ローテーション見たらどう見ても出勤で、他の人は何やら代休となっていて僕が休みにするといろいろ迷惑かかりそーな感じになっていたので(OSC 2009 Niigataもほかの人と休みを動かしてもらって出席した)、出席できなくなりました。

服買うお金でぼろぼろの背広を新調すればよかった気がしてきました。

それはともかく、ローマ字書きの時ってNIIGATAって長音でIを重ねるのが普通なのな。僕出身が県外なんで、けっこう気になりますね。

アドビのCS4対応プリントショップのリストのページから、Google Mapsに表示させるやつの3回目。

前回は、無駄なジオコーディング問い合わせを発生させないためにも、アドビのWebサーバにあるHTMLコンテンツが更新されたかどうかを確認する必要があり、そのために、HTTPのステータスコードを使おうかと思ったんだけど、アドビのサーバから返ってくるステータスコードは200ばっかり、いい加減にしろ! というところまでやりました。

ステータスコードは、単純にURLで示された先のコンテンツの状態がわかるものでしたが、もうちょっと詳しい情報を得たい場合は、HTTPレスポンスヘッダを見ます。

HTTPレスポンスヘッダなんですが、CGIを作ったり、よそのWebサーバからコンテンツをGETしたりHEADしたりする業務をやっている人はおなじみなんですけれども、このレスポンスヘッダを調べるには、Firefoxの機能拡張、Live HTTP Headersが便利です。名前も特徴があって、Googleで検索するとすぐ出てくるのがよい。

Live HTTP Headers :: Add-ons for Firefox [addons.mozilla.org]

これをFirefoxに入れますと、メニューの「ツール」あたりに「Live HTTP Headers」ていう選択肢が出てきます。こいつを選ぶと、別ウィンドウに、レスポンスヘッダ表示がされるという仕組みです。

早速、自分んちと、アドビでためしてみたよ。

まず、自分んち。アドビのコンテンツをそのままwgetしてきてWebにおいたやつ。

Adobeprintshopheader01s

つぎ、アドビのサイトから。

Adobeprintshopheader02s

アドビのサイトからHTMLを取得した場合、“Last-Modified”ヘッダが発行されないみたい。CGIで動的コンテンツを作ったときのようなヘッダです。あと、コンテンツが変更されているかどうかの手がかりになる“Etag”ヘッダもない。

同様なレスポンスヘッダを返す例として、動的生成しているRSSなどがありまして、印刷・DTP関連でいえば、「DTP駆け込み寺BBS」のRSSはこのタイプのコンテンツです。

~~~

そんで、アドビのサーバから送り返されたレスポンスヘッダの意味は、「このコンテンツは今から21600秒有効です。おまえの方でキャッシュ管理してね。ヘッダだけだと、21600秒内でコンテンツの内容変更があったかどうかは教えてあげないよ。」

ていう意味なんで、最新の情報が欲しければ、実際にコンテンツを読み込め、というご指示だと判断します。

というわけで、次回は、ステータスコードが信用ならない、レスポンスヘッダも信用にならない場合、どうやってコンテンツが更新されたかを知るか、という方法を考えます。先なげーなー

アドビのCS4対応プリントショップのリストのページから、Google Mapsに表示させるやつの2回目。

前回は、アドビのページから、HTMLを取得するところをやりました。

HTMLを取得するときに、キャッシュをして、コンテンツに変更がない場合は、キャッシュから使うような仕組みにしました。

さて、データを取得したかどうか、というのは、この後控えているジオコーディング(住所から経度緯度を取得する)をするかしないか、という判断に使うことになるので、重要です。

それを判断するためには、HTTPのステータスコードを使います。

ステータスコードというのは、404 Not foundとかいうところの404とかの数字で、サーバにURLを伝えてコンテンツの要求をしたとき、サーバからそのURLで示されるコンテンツがどうなっているかを知らせるために使うものです。

ステータスコード/意味

  • 200 Found
  • 404 Not Found
  • 304 Not Modified

今回関係ありそうなのはこの程度。

それで、ステータスコードを表示するように改良したソースを以下に示します。

Filename: test2.pl

#!/usr/bin/perl
 
# Filename: test2.pl
 
use strict;
use warnings;
use Cache::File;
use URI::Fetch;
use Cwd;
my $cwd = getcwd;
my $cache = Cache::File->new(
              cache_root =>  "$cwd/cache",
            );
 
my $ua = new LWP::UserAgent;
$ua->timeout(10);
$ua->agent('DTPWiki.jp AdobeJpPrintShopMap/0.1 '
         . '(+http://labo.dtpwiki.jp/printmap/)'
     );
 
my $res = URI::Fetch->fetch(
  'http://www.adobe.com/jp/print/printshop/',
  Cache     => $cache,
  UserAgent => $ua,
) or die URI::Fetch->errstr;
 
my $html = $res->content;
print $res->http_status."\n";
 
__END__


さてこれを実行してみて、ステータスコードを観察しましょう。

$ perl test2.pl
200
$ perl test2.pl
200
$

……ええと、想定では、2回目の実行は304が返ってくるはずなのですが。

調べてみたところ、アドビのプリントショップリストのページがあるURLに関しては、毎回必ず200を返すようになっていました。なんだって!

手持ちのWebサーバの静的コンテンツのURLを指定した場合は、ちゃんと1回目が200、2回目が304になるんです。

というわけで、このプログラムだと、コンテンツの更新があったかどうかを検出することができないということになりました。

ちょっと考えなくてはいけないようですね。(続く

CreativeSuite4出力店募集中!! - いわもとぶろぐ [blogs.adobe.com]

全国の会社様を案内しているのですが、意外に私の地元
千葉からも応募がなかったり...

地図で出せっつーの!(CV:丹下桜)

というわけで、

http://www.adobe.com/jp/print/printshop/

のCS4対応ショップをGoogle Mapsで表示させる奴、今回は、時間をかけてやりたいと思います。

まず、今回は、アドビのサイトから印刷屋さん一覧のHTMLをギるところからです。ギるの語源はギルティーだってネタはどっからやってきたんだろうな。さっきまで誤用してたじゃないか。くそーLe.Chocolatめ!

環境はLinuxのPerl 5.8.6です。

Filename: test1.pl

#!/usr/bin/perl
 
# Filename: test1.pl
 
use strict;
use warnings;
use Cache::File;
use URI::Fetch;
use Cwd;
my $cwd = getcwd;
my $cache = Cache::File->new(
              cache_root =>  "$cwd/cache",
            );
 
my $ua = new LWP::UserAgent;
$ua->timeout(10);
$ua->agent('DTPWiki.jp AdobeJpPrintShopMap/0.1 '
         . '(+http://labo.dtpwiki.jp/printmap/)'
     );
 
my $res = URI::Fetch->fetch(
  'http://www.adobe.com/jp/print/printshop/',
  Cache     => $cache,
  UserAgent => $ua,
) or die URI::Fetch->errstr;
 
my $html = $res->content;
print $html;
 
__END__

ちゃんとUser-Agentを名乗ってhttp://www.adobe.com/jp/print/printshop/からHTMLを取得します。また、実行ディレクトリの下にcacheフォルダを作ってキャッシュすることにして、コンテンツが変更ない場合はWebから取得しなくするなどしました。

上の例では、アドビさんのURLを指定しているのですけれども、キャッシュがきいていなかったりとか、User-Agentの変更がきいていなかったりするので、最初は自分が取り扱えるWebサーバを指定して、ログを見て判断するようにしましょう。

さっき、URI::Fetch 0.72とか入っていて、最新版LWPとバージョンが合わず、User-Agent変更がきいてなかったりしました。

次回は、取得したHTMLコンテンツを解析して、プログラムで扱えるようなリストにするところまでやろうかなあと思います。でも、取得したコンテンツがキャッシュにヒットしたやつなのか、Webから取得したやつなのか判断するのが必要かも。


(2009-10-25 14:13追記)

次のエントリ書くために調べていたんですけれども、Adobeのリストが載っているページは、常にHTTPのステータスコード200を返すということがわかりました……どうしよう……

合い言葉は「B!」びーびっくり!Twitterからのつぶやきでお手軽にブックマークできる連携機能が登場 - はてな広報ブログ [d.hatena.ne.jp]


タイトルが出オチすぎる

こんなのもあるよ

C4exe
▲p1.exeではない

問題(各10点)

  • どこら辺がおっさんホイホイなのか
  • C!って何ぞ
  • Zドライブでない件について考察せよ

IMEがMS-IME2007でこうだまりこが変換できなかった…別れたい。

     ∧_∧
     ( ゚ω゚ ) 合言葉は?
BeeBeeC□l丶l丶
     /  (   ) やめて!
     (ノ ̄と、 i
        しーJ

GoogleケータイHT-03AのOSがアップグレードして16MBのアップデータを3G回線で自動で落としてアップデートが実施されるそうな。僕の端末ではまだ落ちてこないけど。

んで、16MBのパケット代をパケット定額制に入っていないとかなり高い、ていうので困ったねーていう話で、3G回線をこまめにOffにして使っている人(APNdroidとか使うと3G回線の発呼止められる)とか困るねーとは思います。

でもだ、僕もそうやって使ってみても簡単にパケホーダイBizダブルの天井まで簡単に行ってしまうんですよね。

Googleサービスを利用する場合専用の書類って確かにありましたね。ここで活きるのか。

(2009-10-24 10:10追記)

HT-03AのOSアップデート、定額制加入を強く推奨 - ケータイ Watch [k-tai.impress.co.jp]

 なお、更新ファイルは無線LANに接続された状態でもダウンロードできるが、ダウンロードのタイミングは指定できないため、意図的に無線LANでのみダウンロードさせることは難しくなっている。

とか書いている。手動更新メニューつければ一発解決な気がするなあ。

印刷業界の仲間に、印刷ネタでWebコンテンツを作ってみることを促すシリーズ。

住所リストがあって、緯度経度を知りたい、というときに、Google Maps APIのジオコーディングが使えます。

今回は、日本印刷産業連合会のウェブサイトで、環境に配慮した印刷会社、グリーンプリンティング認定工場のリストがあったのでこれの第13回認定工場一覧を使います。

http://www.jfpi.or.jp/greenprinting/introduction/index.html

Googleapigeocoding01
▲まじこれ見て発注してくださいよーたのんまっすよー

まず、Googleで「Google Maps API Geocoding」で検索すると出てくる

http://code.google.com/intl/ja/apis/maps/documentation/services.html

から、ジオコーディングの「例を表示 (geocoding-simple.html)」

http://code.google.com/intl/ja-JP/apis/maps/documentation/examples/geocoding-simple.html

にサンプルが有ります。ここのサンプルの動作を一通り楽しんだ後、Operaで「ページのソースを表示」を選択します。

次に、おもむろにソースをこのように改変します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <script src="http://maps.google.co.jp/maps?hl=ja&amp;file=api&amp;v=2.x&amp;key=(略)" type="text/javascript"></script>
    <script type="text/javascript">
    var list = [
['オフセット','A10007','宝印刷株式会社','印刷部浮間工場','東京都北区浮間4-24-23','H21.9.30','H24.9.29'],
['オフセット','B10099','六三印刷株式会社','水沢工場','岩手県奥州市水沢区佐倉河字仙人6-1','H21.9.30','H24.9.29'],
['オフセット','B10100','株式会社アカマ印刷','本社工場','山口県下関市長府扇町9-10','H21.9.30','H24.9.29'],
['オフセット','B10101','株式会社橋本清文堂','','石川県金沢市示野町南51','H21.9.30','H24.9.29'],
['オフセット','B10102','株式会社金羊社','本社','東京都大田区鵜の木2-8-4','H21.9.30','H24.9.29'],
['オフセット','B10103','株式会社山口県農協印刷','','山口県山口市嘉川668-1','H21.9.30','H24.9.29'],
['オフセット','B10104','株式会社ソーエイ','','兵庫県明石市樽屋町6-6','H21.9.30','H24.9.29'],
['オフセット','B10105','冨士オフセット印刷株式会社','','茨城県水戸市根本3-1534-2','H21.9.30','H24.9.29'],
['オフセット','B10106','株式会社横山印刷','','茨城県土浦市卸町2-6-6','H21.9.30','H24.9.29'],
['オフセット','D10004','あさひ高速印刷株式会社','本社・本社工場','大阪府大阪市西区江戸堀2-1-13','H21.9.30','H24.9.29'],
['オフセット','F10017','小澤製本株式会社','本社工場','東京都荒川区西尾久8-27-3','H21.9.30','H24.9.29'],
['オフセット','J10003','株式会社大和紙工業','本社工場','埼玉県和光市新倉7-12-13','H21.9.30','H24.9.29'],
['オフセット','J10004','興亜産業株式会社','本社工場','東京都板橋区高島平1-55-16','H21.9.30','H24.9.29'],
['シール','G20010','株式会社ヒロミ産業','','北海道札幌市西区発寒14条2-2-21','H21.9.30','H24.9.29'],
['グラビア','H30020','北海紙工業株式会社','','北海道小樽市銭函3-524-15','H21.9.30','H24.9.29'],
['グラビア','H30021','株式会社東和プロセス','川口工場','埼玉県川口市領家5-8-18','H21.9.30','H24.9.29']
    ];
    var last = list.length;
    var timer;
    var count = 0;
    var geocoder = null;
    function initialize() {
      if (GBrowserIsCompatible()) {
        geocoder = new GClientGeocoder();
      }
    }
    function showAddress() {
      address = list[count][4];
      if (geocoder) {
        geocoder.getLatLng(
          address,
          function(point) {
            if (!point) {
              document.getElementById('list').innerHTML
                += address + ",not found,\n";
            } else {
              document.getElementById('list').innerHTML
                += address + "," + point.toUrlValue() + "\n";
            }
            count ++;
            if ( count != last ) timer = setTimeout( showAddress, 3000 );
          }
        );
      }
    }
    </script>
  </head>
 
  <body onload="initialize();showAddress();" onunload="GUnload()">
    <textarea id="list" style="width: 100%; height: 300px;"></textarea>
  </body>
</html>

そして、Operaのページソースタブの「更新を適用」ボタンを押すと、Google Maps APIのジオコーディング問い合わせに3秒ごとに問い合わせてtextareaに書き出すことができます。

Googleapigeocoding02

textareaの部分をコピペして、緯度経度をlistに反映。手作業ですw

反映した後地図に表示させるコードはこんな感じ。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=(自分が取得したkeyに置き換えてね)"
      type="text/javascript"></script>
    <script type="text/javascript">
    var list = [
['オフセット','A10007','宝印刷株式会社','印刷部浮間工場','東京都北区浮間4-24-23','H21.9.30','H24.9.29',35.78669,139.690808],
['オフセット','B10099','六三印刷株式会社','水沢工場','岩手県奥州市水沢区佐倉河字仙人6-1','H21.9.30','H24.9.29',39.160941,141.152834],
['オフセット','B10100','株式会社アカマ印刷','本社工場','山口県下関市長府扇町9-10','H21.9.30','H24.9.29',34.020314,131.017882],
['オフセット','B10101','株式会社橋本清文堂','','石川県金沢市示野町南51','H21.9.30','H24.9.29',36.576984,136.608892],
['オフセット','B10102','株式会社金羊社','本社','東京都大田区鵜の木2-8-4','H21.9.30','H24.9.29',35.573727,139.682746],
['オフセット','B10103','株式会社山口県農協印刷','','山口県山口市嘉川668-1','H21.9.30','H24.9.29',34.075746,131.394741],
['オフセット','B10104','株式会社ソーエイ','','兵庫県明石市樽屋町6-6','H21.9.30','H24.9.29',34.646664,134.986707],
['オフセット','B10105','冨士オフセット印刷株式会社','','茨城県水戸市根本3-1534-2','H21.9.30','H24.9.29',36.387537,140.465555],
['オフセット','B10106','株式会社横山印刷','','茨城県土浦市卸町2-6-6','H21.9.30','H24.9.29',36.047697,140.145749],
['オフセット','D10004','あさひ高速印刷株式会社','本社・本社工場','大阪府大阪市西区江戸堀2-1-13','H21.9.30','H24.9.29',34.687638,135.490952],
['オフセット','F10017','小澤製本株式会社','本社工場','東京都荒川区西尾久8-27-3','H21.9.30','H24.9.29',35.75246,139.754298],
['オフセット','J10003','株式会社大和紙工業','本社工場','埼玉県和光市新倉7-12-13','H21.9.30','H24.9.29',35.802047,139.621708],
['オフセット','J10004','興亜産業株式会社','本社工場','東京都板橋区高島平1-55-16','H21.9.30','H24.9.29',35.784187,139.673496],
['シール','G20010','株式会社ヒロミ産業','','北海道札幌市西区発寒14条2-2-21','H21.9.30','H24.9.29',43.098772,141.296774],
['グラビア','H30020','北海紙工業株式会社','','北海道小樽市銭函3-524-15','H21.9.30','H24.9.29',43.137071,141.179022],
['グラビア','H30021','株式会社東和プロセス','川口工場','埼玉県川口市領家5-8-18','H21.9.30','H24.9.29',35.788408,139.742903]
    ];
    var last = list.length;
    var count = 0;
    function initialize() {
      if ( GBrowserIsCompatible() ) {
        var map   = new GMap2( document.getElementById("map_canvas") );
        map.addControl(new GLargeMapControl() );
        map.addControl(new GMapTypeControl () );
        var point = new GLatLng(36.03, 139.15);
        map.setCenter(point, 8);
        
        var markers = [];
        var gb;
        var first = 1;
        var manager = new GMarkerManager(map);
        for ( count = 0; count < last; count++ ) {
          var point = new GLatLng( list[count][7], list[count][8] );
          var marker = new GMarker(point);
          markers.push( marker );
          if( first ){
            gb = new GLatLngBounds( marker.getPoint(), marker.getPoint() );
            first = 0;
          }
          else {
            var point = marker.getPoint();
            gb.extend( point );
          }
        }
        manager.addMarkers( markers, 0 );
        map.setCenter( gb.getCenter(), map.getBoundsZoomLevel( gb ) );
        manager.refresh();
      }
    }
    </script>
  </head>
 
  <body onload="initialize();" onunload="GUnload()">
    <div id="map_canvas" style="width: 900px; height: 600px;"></div>
  </body>
</html>

クリックすると社名が表示されるなどは実装していないけれども(賞味30分仕事だし)、配列に持っているからすぐできると思います。

地図に表示させるのは結構簡単なので、手持ちの住所リストでやってみるとおもしろいと思います。

本来は3回ぐらいに分けてやればいいネタだけど1回で終わってしまった……。

んと24inch iMacを使っていて感想なんですが、

  1. 向き合っていると顔がほてってくる
  2. チルトスタンドで支えられている本体を上に向けてもすぐうつむく

など、お互いに恋しているんじゃね?的な反応で困るのですけれども、1.は輻射熱じゃあねえかってことでなんだか顔面になんかの作用引き起こしそうだし、2.はチルトスタンドの構造上の問題で重量支え切れていないってことだと思うんで、27inchとなったらどうなることやら。

そもそもVDP作業用として机の上に置くと画面上部あたりを見るとき視線が水平よりも上になると思うのでどっかが人間に厳しいデザインとか言って取り上げてもいいと思う。

docomoのGoogleケータイ、HT-03Aを使っていまして、このケータイは電池パックが2つついてくるのですけれども、僕の使い方であれば、電池パックを1つ使い切ることもないのです。

通勤に自家用車を利用しているという点、15分ぐらいで会社に到着してしまうという点が大きい。あと、休日は外でないので何のためのスマートフォンだ、ということでもあります。

予備の電池パック、これは使わずにとっておいて1個目の電池パックがバカになったあたりで使い始めても性能を発揮するものなのか。

たしか、この端末の超ウルトラバッテリーがすごい形状なんですよね。

Amazon.co.jp: HT-03A用ウルトラ大容量バッテリー HLI-G2XL: 家電・カメラ [www.amazon.co.jp]

DTP系デザイン制作を行っている方に質問します。 現在制作業務で使っているIllstratorのバージョンとOSを教えてください。 ※異なるプラットフォーム環境をお持ちの場合は.. - 人力検索はてな [q.hatena.ne.jp]

正直言ってですね、さまざまなバージョンのデータを処理することになるいわゆる印刷通販的な業務に携わっている最近ですが、実際Illustrator CS3の入稿数抜群に多くなってきた感じがしています。CS4は今の時点でもかなり少ない。

作業している側としては、Mac OS 9のマシンで作業する必要がなくなるんでありがたいです。リンクされるファイルをファイルサーバに配置するなどのファイル操作はなるべくMac OS Xで作業しておいて、編集作業だけMac OS 9のマシンまでいって作業して、RIPのホットフォルダに投げるところは、やっぱり巨大ファイルのハンドリングはMac OS Xの方がいいので元の席に戻って作業するなど、めんどくさいんです。

Illustrator CS3がいいらしい、ていうの皆がどうやって知ったのかが気になります。

DTP Booster 008(Osaka/091030)(2009年10月30日、デジタルハリウッド大阪校 セミナールームで開催)

カラマネのセミナーって、その事業者の作業工程を変更できるだけの責任がある人が受けないとあんま生きない、知識だけに終わってしまう、ていう印象。個人事業者のカラマネが先に行っているというのもそういう理由。自分でフロー構築できるから。

いまのホットトピックは

Japan Color認証制度 [japancolor.jp]

でしょうか。今までがんばって測色機とか使いつつも「本当にこれでいいの?」とか思って疑心暗鬼でやってたところも、外部のお墨付きがあるとなればやりやすくなると思われ。

ExcelでPS書き出しをしようとすると、シンプルすぎるダイアログボックスが表示され、ファイル名欄にフルパスを入力しなくちゃならず、大変不便です。ちなみに、ここでフルパス入れないと、カレントディレクトリに書き出されますが、Excelの起動の仕方によってカレントディレクトリがあちこち変わりますので(!)、フルパスで入力することをお薦めします。

Excelps01
▲どうしろと?

そんなシチュエーションに備えて、一度「ファイル名を指定して実行」(Win+R)で自分のアカウントでのデスクトップを指定しておきましょう。

一度、「ファイル名を指定して実行」で実行したものは、履歴に残ります。それを利用して、いざという時に、コピーアンドペースト用に呼び出してくることができます。

Excelps02
▲Win+Rで表示すると、デスクトップのパスが入力されている。表示されていない場合↓を押して探す

表示されたパスをCtrl+Cでコピーして、ExcelのPS書き出しダイアログボックスに切り替えてCtrl+Vをすると、デスクトップのパスが貼り付けできます。あとは、書き出したいPSファイルのファイル名を入力しましょう。

Excelps03
▲PS書き出しなのにepsとしておくとCoreSeparation時に便利だったりするよ

うーん、PS書き出しって奥が深いですね!

このPS書き出しダイアログボックス、Excelの場合と、MS-Word・PowerPointの場合とで表示されるダイアログボックスが違うというのも奥が深すぎますよね。MS-Word・PowerPointの場合、コモンダイアログボックスが表示されてデスクトップがすぐ選べるようになっているのだけれども、拡張子が強制で.prnになるという問題が。これも回避方法あるがそれについてはまた別の機会で。

不毛なPS書き出し(こうい)と 君は笑うだろか それなら君は 幸せなんだろね

Re^4: カラープリンター購入について - DTP駆け込み寺 新掲示板 [www.dtptemple.org]

Adobeの方が「もうPSプリンターである必要はありません。我が社ではすでに使用していません」とコメントされていました。
これを聞いてPSプリンターである必要はないのかと思っていました。

僕は、半年前、アドビにはFAXがないというのを聞きました。本当かどうかは知らん。本当だとしても、その部署に、という意味だと思いますけどね!

こんな職種もあるのか。

Nikkeiinsatsu
▲livedoor Readerででたよ

それ専門でやるっていう観点なかったよ。すげえなあ。

職場の労働安全衛生的な観点で、あと、危機管理的な観点で、去年やっとお願いして会社でインフルエンザワクチンの集団予防接種ができるようになりまして、よかったよかった、て思っていましたが、今年は、新型インフルエンザワクチンと季節性インフルエンザワクチンの両方が数が足りず、会社での集団予防接種ができなくなり、予防接種したい人は、個人でかかりつけ医に相談してね、ということになりましたが、よその県から来ていてこれといった病気もしていない僕は、かかりつけ医などあるわけもなく、今年に関しては予防接種なしで挑むことになりそうです。

ゼロックスのカウンタ報告の仕事を引き継ぐことになり、いよいよ以前作ってたDocuPrintなどが内蔵しているHTTPサーバにWWW::Mechanizeでアクセスしてカウンタの値を取得するスクリプトを使い、自動でレポートさせようと思ったのですけれども、残念ながら、cron設定できる自由度があるサーバがないので、企画倒れ。

よくわからないですけれどもSNMPでもカウンタ数とれるとか聞いたけど、さすがにそこら辺までできんわ(80番以外はなあ)。

カウンタ報告って本来は完全自動化できるが人間が確認しているという工程が必要なんだろうかなあと思いました。

(ブリンクとは言っても青くはないので注意)

GoogleMapAPIでものすごい多くMarkerがあった場合、GMarkerManagerとかMarkerManagerとか使って、拡大率によって表示されたりされなかったりを制御できるっていうのはいいんですが、むしろ全部表示してもいいから、特定のMarkerを目立たせろっていうミッション。

これを、この3日間ラブプラスやっていた僕はラブプラスの左側のステータス表示でいちいちハートがでっかくなったり小さくなったりしている効果に気付きまして、それをまねてやってみました。

Googlemapblink
▲効果てきめん

単純に、Markerとして指定する画像ファイルを、アニメーションPNGにしただけです。アニメーションGIFじゃないのは、フリンジが出ちゃうからです。

そんで、アニメーションPNGはまだ普及していないので、もしかしたら見られないブラウザもある。ここにアニメーションPNGのMarker画像貼るので見られるかどうか見てください。

Markeranimation

これを作るには、FirefoxのAPNG Editorという機能拡張を使う。あらかじめそれぞれのフレームのPNGを書き出しておいて、APNG Editorで合成するよ。

Markeranimation02
▲簡単です

うちでテストしたところ、APNGは、Opera10とFirefox3で機能しました。後方互換として、対応していないブラウザだと1フレーム目が表示されるとのことなので、影響が少ない程度にアニメーションさせたアイコンを置いてみるのもいいかと思います。

問題は、GoogleMapsの上に置くMarkerの画像って、なかなかしっくりくるものがないってことなんだと思います。

ラブプラスで久しぶりに丹下桜の声を聞いたこともあって、丹下つながりで、今使っているAndroidケータイHT-03Aに、アンドロイド・アナMAICO2010の曲を着メロにしよう。

ちゃんと持っている。

ゆきえちゃんパニックの歌詞はアニメ鉄人28号(モノクロ版!)のパロディだ。作詞のクレジットないけどおそらく黒田洋介。そんで歌っているのは岡崎律子。岡崎律子といえばメロキュア。メロキュアといえばもう一人は日向めぐみ。日向めぐみといえばグミ。グミといえばカードキャプターさくらOP歌っている(たまに広瀬香美と勘違いしている人がいるが広瀬香美はED歌ってる)。カードキャプターさくらといえば声優は丹下桜。なんという丹下桜無間地獄。

もっとも、普段電話はFOMAの端末のほうで取るので、この端末に設定した着信音はなることはないのでした……

これは言い逃れできん。今日のだめっぷりはTwitterでわかるかもね!

それと、今から後輩を飲みにつれださなくてはならん。しかしこの後輩、下手すると上司と親戚のおじさんに遭遇するのでそうなるととてもかわいそうな気がする。僕もかわいそう。

明日名古屋でDTPの勉強部屋という勉強会があるという話で、同僚君が一緒に行かないかと誘ってくれたが断って、この3連休はギョーカイの人のためのサイトのリニューアルをトッカントッカン作らなくてはならないような気がするので名古屋に行く人は頑張ってください。

その作っているサイトというのは会社業務でやっとるのでここのブログでは載せられないのだ。一応そういう約束になっとるのであしからず。

「Adobe Creative Suite 4」の入稿に対応した国内印刷拠点が100カ所を突破 | クリエイティブ | マイコミジャーナル [journal.mycom.co.jp]

アドビ システムズは、日本国内における「Adobe Creative Suite 4」の入稿に対応する印刷会社、対応店が100カ所を突破したと発表した。対応会社には印刷大手の共同印刷、凸版印刷などが含まれているとのこと。

アドビさんCS4あたりから全国行脚をしとるのかな。知らんけど。

でも、この表

Adobe Creative Suite 出力対応店一覧

を見て発注を決めたというひとは今まで見たことないのだ。発注のプロセスってそんな自由じゃないからだろうなあ。

Mac OS 9のMac IE 5.1対応ページをそろそろぶっちゃって、モダンブラウザ対応に作り変えようという案件。jQuery使って省力化を図ってやっているわけですけれども、Cookieでちょっとはまりました。

Mac IE 5.1の時代、そのブラウザには、encodeURI(), decodeURI() が実装されていなかったのです。decodeURI()は

M.C.P.C.: MacIE5でdecodeURIを実装

で実装できたものの、encodeURI() は根性がなくてできなかった。しかれば、JavaScript 1.0からある、escape() を使えばよくね? と思うのは自然の摂理。Cookieにescape()でパーセントエンコーディングした文字列を格納し、必要なときにCookieから読み込んだパーセントエンコーディング文字列をenescape() すれば元に戻っていた。それで今まで問題なかったんですよね。

ここで、escape()、unescape() はブラウザごとに挙動違うから encodeURI()、decodeURI() のほうがいいんじゃないの?ていう人がいると思うんですが、

  • Cookie焼くときも食べるときも同じブラウザ使うだろ

という1点で論破。

そんで、今回jquery.cookie.jsプラグインの$.cookie() を使ってみたらば、こいつ、読み込み時は内部でdecodeURI() でデコードしているので、URIError: malformed URI sequence JavaScriptなんてエラーが出るわけです。口に合わないCookieを食べてしまったので、$.cookie() が食あたりを起こしている状態。

しょうがないので、try...catchを使って、$.cookie() がエラーを起こした場合は、生Cookieを読み込んで自前でunescape() する小ルーチンを作ることになりました。

Cookieに日本語文字列を生で入れるな、というのはまあわかります。

Xenを使って仮想的に2台のCentOS 5を動かしているサーバの、Domain-Uの方を再起動した後、Domain-0で取得しているmuninの表示が途切れてしまっていました。

いろいろ調べたところ、再起動前は、手動でiptablesでport 4949を穴を開けていたんですね。それが再起動したらふさがってしまったと。

今時のCentOSは、ファイヤーウォール有効でインストールされますので、必要なポートは明示的にあけておく要があるってことなんですけれども突貫で設置したので忘れていました。今度から気をつけたいところです。

どうやらうちのWeb制作は、TypePadあたりのSSIで何でもやる作法に慣れてしまったせいか、Dreamweaverを使うというシチュエーションがなく、そもそもCS3にDreamweaverが同梱されるまでインストールすらされていなかったりしたものだから、だれもDreamweaver使えない。

やっぱ印刷会社のWeb作る部門は皆Dreamweaver使っているのかな。印刷会社同士交流ないからわからないや。

僕がDTPエキスパート認証を取ったのは10年ぐらい前で、その時は、課題提出はPageMakerだったかLaTeXだったかで作ったやつを郵送で送った。

そんで、今から認証を取る人は、課題はオンラインダウンロード・オンライン入稿なんだって。

ネット利用の推進者としての技量に期待 - JAGAT [www.jagat.jp]

■Webでの課題ダウンロード・アップロード

経緯から説明すると第31期試験からCD-ROMによる課題制作の材料配布からWebによるダウンロード形式に変更した。

正直な話、最悪のことも考えて100枚のCD-ROMは用意しておいたのだが、指定校から1枚のオファーがあっただけで、特に混乱もなく終了した。なぜこんなことをと疑問に思われるかもしれないが、デジタル化のメリットでもあるネット利用の推進者として、DTPエキスパート取得者は働いていただかないと困るので、その技量を持っていることも必須と考えているのだ。もっとも日本のブロードバンドの普及率も重要で、昨今の状況をかんがみて課題提出もWeb経由という決断に至った経緯があるのは言うまでもない。作業指示書はPDF、でき上がった課題はPDF/X-1aの入稿データの形で指定サイトにアップしてもらうのだが、締め切り間際のトラフィックの混雑も考慮してのスケジューリングなども、必然的に採点対象に含まれてくるわけである

しらんがな。

うち、お客様に迷惑かけないよう、入稿サーバ混雑しないようにといろんな工夫をしてきたのがあほらしくなる発言である。

上から目線なのはまあいいとして、思いつきで書いたふうなのはやめてほしいと、個人的に思うぞ。

思うんだけど、これってLaTeXやWordで課題制作したい場合はAdobe Acrobatないとできないんじゃないか。JAGATは貸し出し用Acrobatとかも用意していたのかなあ。

以前作ったはてな投げ銭スクリプトが、動かなくなっていたので、直してみました。太字部分が直したところかな。

#!/usr/bin/perl
 
# throw.cgi ブックマークしたら投げ銭します。
# 2009-06-07 ver 0.0.1 ファーストポスト
# 2009-10-xx 最新のMechでも動くように
 
use strict;
use warnings;
use CGI;
use Config::Pit;
use Encode;
use HTML::AccountAutoDiscovery;
use utf8;
use WWW::Mechanize;
 
# 初期設定
my $url_sendpoint = 'https://www.hatena.ne.jp/sendpoint';
my $send_point = 10; # 送信するポイント(はてな手数料別)
my $login;
my $config = pit_get('hatena.ne.jp');
die "not preset account data in Pit." if !%$config;
my $my_id    = $config->{id      } or die 'id not found.';
my $password = $config->{password} or die 'password not found.';
my $auth_key = $config->{auth_key} or die 'auth_key not found.';
 
my $q = CGI->new;
my $mech = WWW::Mechanize->new;
$mech->agent_alias('Windows IE 6');
 
{ # メインルーチン
  # 認証
  if ( $q->param('key') ne $auth_key ) {
      die "Authentication failed";
  }
  # メソッド確認
  if ( $q->param('status') eq 'add' ) {
    # エントリーの情報
    my $req = $q->Vars();
    nagesen( $req );
  }
  # はてなブックマークWeb Hook用リザルト
  print $q->header('text/plain');
  print 'ok';
}
exit;
 
sub nagesen {
  my $req = shift;
  my $url = $req->{url};
  my @account = HTML::AccountAutoDiscovery->find( $url );
  
  foreach my $item ( @account ) {
    my $send_id = $item->{account}; # account name
    send_hatenapoint( $req, $send_id );
    last; # HTMLに複数のIDを埋め込んでいた場合最初の人の分
          # だけ対応(同じ人がID埋め込みまくるとポイント
          # 送信しまくるのを防ぐ)
  }
  return;
}
 
sub login_hatenapoint {
# はてなにログインします
  $mech->get( $url_sendpoint );
  # ログインを促す画面に遷移済
  $mech->follow_link( text => mech_encode('ログイン') );
  # ログイン画面に遷移済
  $mech->set_visible( $my_id, $password );
  $mech->submit();
  # ログイン済み画面に遷移済
  $mech->follow_link( text => mech_encode('こちら') );
  # 投げ銭画面に遷移済
  $login = 1;
  return;
}
 
sub send_hatenapoint {
# はてなポイント送信をします
  my $req     = shift;
  my $send_id = shift;
  unless ( $login ) {
    login_hatenapoint();
  }
  # ログイン済みの状態
  $mech->get( $url_sendpoint );
  # はてなポイント送信のページに遷移済
  # ポイント送信メッセージ組み立て
  my $send_message = decode('utf8', $req->{title})
    ."($req->{url}) をブックマークしました。投げ銭いたします。"
    .'投げ銭スクリプト:http://svn.coderepos.org/share/lang/'
    .'perl/misc/hatenabookmark_webhook_nagesen/';
  # ポイント送信用パラメータ入力
  $mech->set_visible(
    $password, $send_id, $send_point,
    undef, # 匿名にしたい場合は1
    mech_encode( $send_message )
  );
  $mech->submit();
  # confirm画面に遷移済
  return unless $mech->title() eq mech_encode(
    'はてな ポイント付きメッセージ送信確認'); # 送信確認ページ?
  $mech->click_button( value => mech_encode('送信する') );
  #open my $fh, '>', 'log.html';
  #print $fh $mech->content();
  #close $fh;
  return;
}
 
sub mech_encode {
# WWW::Mechanizeをバージョンアップしたら変わった挙動に対応
  my $str = shift;
  if ( ( $WWW::Mechanize::VERSION ) < 1.60 ) {
    $str = encode( 'utf8', $str );
  }
  return $str;
}
 
__END__

そんで、最後のサブルーチンで、WWW::Mechanizeがバージョンアップしたら動作が変更になった部分を吸収しようとしているわけなんですけれども、動作が変わった境目がどこなのかわからないので、このままcommitするのがためらわれるよね。もしかしたらWWW::MechanizeじゃなくてHTTP::ResponseとかHTTP::Messageのバージョンを見ろとか、バージョン番号の取得はこれだと不適切とか(正式にはなんかモジュール使うんだったよね)あるかもしれん。ともかく、うちのWWW::Mechanizeの1.60だとこれで動くようになりました。

WinBookのVGA出力に、15inchの1024x768表示の液晶モニタをつなぎ、狭い画面での表示確認用として活用している気でいましたが、隣には、MacBookもあって、そもそもモニタつながずにWinBookで編集しMacBookでリロードして確認すればいいじゃないかということに気づきました。

カセットテープのウォークマンをクルマで聞くためにカーコネクティングキットで車載カセットデッキにつないだこともありますが、そういう遠回りってよくしてしまうのです。あほたれですね……

どうも田舎はdocomoユーザーが多いせいか、おサイフケータイにiDを設定している人が多くて(ドコモショップの抱き合わせ商法のせいだよね)、そのせいで、ぼんやりサークルKにいって、ぼんやりレジに商品持ってって、支払は、と聞かれた時、ぼんやりとえでぃとか言うと、シャリーンじゃなくてチャランポンみたいな音がしてiDで支払いされているというのを経験するわけです。

いなかもんにDの発音させるなってこってす。サークルKの店長はそれぞれ「えでー」「あいでー」といっておるでー

一方全国出店済みのローソンは、レジで客にどっちを使うか選ばせた。さすがだなあ。

月別 アーカイブ

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 5.2.13

このアーカイブについて

このページには、2009年10月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2009年9月です。

次のアーカイブは2009年11月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。