2014年3月2日日曜日

Product Advertising APIのアカウント管理はイケてない

プログラムから本の情報検索したい!と思ったら Product Advertising API を使うのが手っ取り早い。先日作ったPribraryにISBNから書籍情報を自動取得する機能を追加したく、アカウント登録することにした。ただそのアカウント管理に関する情報がイケてない、と思ったのでまとめておく。Product Advertising APIを使うときに覚えておくポイントは
  • Product Advertising API へのリクエストにはルートアクセスキーしか使えない
  • アソシエイトタグは別に何でもいい。
っていうこと。間違っていたら誰か教えてね。

2つのアカウント情報が必要

APIのリクエストには↓のような感じで2つのアカウントIDが必要
http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Operation=ItemSearch&
AWSAccessKeyId=[アクセスキー ID]&AssociateTag=[ID]&SearchIndex=Apparel&
Keywords=Shirt

AWSAccessKeyId=[アクセスキー ID]

ここから登録できます。登録完了後に次のような画面が表示されるでしょう。
ふむふむ。Manage Your Accountに行けばいいのね?
アクセスキー取得っと。
こんなことが書いてあったら誰でも新しいページYour Security Credentialsに行くだろう。俺も行った。
へーIAMユーザーとか使ってセキュリティ高めるのね。ベストプラクティスでも読んどくか。

Lock away your AWS account access keys

Any request you make for an AWS resource requires credentials so that AWS can make sure you have permission to access the resource. You can use access keys (an access key ID and secret access key) to make programmatic requests to AWS. However, we recommend that you do not use your AWS account access keys. The access key ID and secret access key for your AWS account give you access to all your resources, including your billing information. (For more information about credentials for working with AWS, see Types of Security Credentials in the Amazon Web Services General Reference.)
何でもできるアクセスキーは使わずに、権限限定したユーザーを作ってそのアクセスキー使えってことね。はい分かりました。

早速Pribrary用にアカウントを作成した。さてProduct Advertising APIへの権限をば・・・


あるあ・・ねーよwww


そんな権限ありませんでした。もしかして単に名前が違って発見できないだけかと思いPribraryユーザーに全権限を与えてAdvertising APIへリクエストを送ってみましたが、だめでした・・・・orz

もういい、ルートのアクセスキー使うわ。


AssociateTag=[ID]

ここから登録可能。登録ではWEBサイトの内容とか紹介予定の商品とか記載。もちろんIDはtakkyuuplayerで申請。4時間後次のようなメールが届いた。
Amazonアソシエイト・プログラムにお申し込みいただき、ありがとうございます。

このたび当プログラムへの参加を申請いただいたWebサイトを拝見いたしましたが、誠に残念ながら、お申し込みを承認することができませんでした。当プログラムへの参加をご希望の場合は、下記の項目をご確認いただき、あらためてお申し込みくださいますよう、お願いいたします。

当プログラムでは、お申し込みいただいたWebサイトが下記の項目に当てはまる場合、残念ながらご参加を承認することができませんので、あらかじめご了承ください。
!!??怪しいのは次の文言。
1. Webサイトが未完成の場合
Webサイトの方向性がわかる程度を目安に、内容をアップロードしてからお申し込みください。

3. Webサイトに閲覧規制がなされており、内容を拝見できない場合 
Pribraryにテストデータ入って無いため未完成と思われた、もしくは閲覧規制されていると思われたのではないか。メール受信後、 amazonアソシエイトにログインできなくなったのでどうやらtakkyuuplayerは削除されてしまったらしい。

なんということだ。このままではAPIが使えない。仕方ないのでhttp://www.takkyuuplayer.com/に絞って再度ID: takkyuuplayerで申請。
Amazon アソシエイト・プログラムにお申し込みいただき、ありがとうございます。,takkyuuplay08-22!
takkyuuplay08-22って誰だよ!takkyuuplayerじゃないのかよ!どうやらtakkyuuplayerはロックされただけでアカウント自体は存在するらしい。果たしてどうやって復活させればいいのか?takkyuuplayerを使いたいのだが。

ひとまずアカウント自体の存在は分かったのでAssociateTag=takkyuuplayerでAPIを叩いてみたら・・・通った。存在しない(であろう)アカウントAssociateTag=takkyuuplayer0302でAPI叩いてみても・・・・通った。


AssociateTag何でもいいのかよ!

結論: Amazon Product Advertising APIのアカウント管理はイケてない

Amazon Product Advertising APIを使い始めるにあたって、ハマりそうなところをまとめました。AssociateTagはなんでも良いらしいのですが、せっかくなので発行したAssociateTagを使おうと思います。まだ審査結果来てませんが・・・。そしていったいtakkyuuplayer使うにはどうすればいいのか。

2013年12月10日火曜日

Windows8でMerry X'mas! #vgadvent2013

VOYAGE GROUP エンジニアブログ Advent Calendar 2013 10日目の記事です。

去年のAdvent Calenderから1年が経ちました、@takkyuuplayerです。10月末にパソコンを新調し、ついにWindows8機を手に入れました。せっかくなので前々から気になっていたWindows Storeアプリを作ってみようと思います。

前準備

まずは開発環境を整えましょう。Microsoft Visual Studio Express 2013 for Windowsを手順に従ってインストールしてください。特に詰まるところは無いと思います。Windowsをマシンを持っていなくても評価版を使えば開発環境を整えられるようです。

Hello world

このチュートリアルを参考にクリスマスにちなんでHello WorldならぬMerry X'masプロジェクトを作成してみました。https://github.com/takkyuuplayer/Merry-Xmas

ブランクプロジェクトを作成すると、ブランクのくせにいろいろファイルが追加されます。そのブランクプロジェクトを実行したのが↓
ブランクプロジェクト
何もありません。閉じるボタンもないので終了するにはAlt+F4を押して下さい。

最初にデフォルトビューを変更します。MainPage.xamlにその設定が記述されているようです。既存のものはいらないので削除して下さい。

Projects > Add New Item より、新しいMainPage.xamlを作成します。ビューの選択リストにはよく使う(?)テンプレートがまとまっていました。
右側にサンプルビュー
Basicテンプレートを追加(やはりBasicのくせにいろいろファイルを追加する)して、できたMainPage.xamlを編集するとアプリっぽくなります。ボタンにイベントを追加して終了 です。
Basicテンプレート

メリークリスマス!!

感想

Visual Studioは初めて触りましたが「クリック1回でいろいろやりすぎ!」というのが第一印象ですね。今後他のチュートリアルも触ってみつつVisual Studioが背後で何をやっているのか、把握していきたいと思います。

 明日の #vgadvent2013 は @_zoo さんです。

参考

2013年10月3日木曜日

perl の use について調べたのでメモ

perlのuseについて調べたのでメモ。 use Module LISTは perldoc.jp http://perldoc.jp/func/use によると

BEGIN { require Module; Module->import( LIST ); }

と等価らしいです。

#!/usr/bin/perl
use Data::Dumper (qw(Dumper));
warn Dumper 1; # $VAR1 = 1;
#!/usr/bin/perl
BEGIN {require Data::Dumper; Data::Dumper->import(qw(Dumper)); }
warn Dumper 1 ; # $VAR1 = 1;

確かに同じっぽい。なるほど。

パッケージの import メソッドを呼び出したくない場合(例えば、名前空間を 変更したくない場合など)は、明示的に空リストを指定してください:

    use Module ();
これは以下と完全に等価です:

    BEGIN { require Module }

そこは

BEGIN { require Module; Module->import(()); }

と等価ってことでもあるのかな?と思って実験。まず

use Data::Dumper ();
warn Dumper(1); # Undefined subroutine &main::Dumper called

は importされないわけだからエラー。

BEGIN {require Data::Dumper; Data::Dumper->import(()); }
warn Dumper(1); # $VAR1 = 1;

予想が外れた。どうやらimportは完全に呼ばれないらしい。

2013年6月28日金曜日

Chrome の console で jQuery を使いたい

Web開発者たるもの、Webブラウジング中にちょっとDOM要素を弄りたくなって「Chrome のconsoleでjQueryが使えたら楽なのに」と思うことがあります。もし見ているWebページが http://www.takkyuuplayer.com/ のようにjQueryをインポートしているのであればconsole上でもjQueryを使うことができますが、そうでない場合は使えません。

そのようなときは Include jQuery in the Javascript Console - Stack Overflow のようにしてjQueryを入れれば良いのですが・・・

この方法には致命的な欠点があります。それは

  • 常に同じバージョンのjQueryが使えるわけではない
  • そもそもインポート用のスクリプトを覚えられない
ことです。すでに閲覧中のサイトがjQueryをインポートしている場合「サイトのjQueryを使う」か「新しくjQueryをインポートしてサイト上のjQueryを上書きする」かの二択を迫られてしまいます。

どちらもやりたくはないので、既存のjQueryは置き換えずにいつも同じjQueryを使うためのChrome拡張を作りました。chebo.crxをインポートすればconsole上にて、次のようにしてjQueryにアクセスできます。 withCheboの引数として関数を渡してやれば、その中でjQueryが使えるようになります。便利ですね。

Underscore.jsBackbone.jsも使えるようになっているので、ちょいちょいウェブブラウジング中にDOM要素を弄りたくなる方は使ってみてください

2013年6月17日月曜日

local package manager のすすめ

vimをインストールしたいのにmercurialが無い、ncurseが無い。それらをインストールしようにもroot権限が無い。 

そんな風に思ったことはあるでしょう。慣れ親しんだ開発環境を使えないもどかしさ、分かります。大抵ホームディレクトリにmakeでインストールするのですが、環境が変わるたびに最新のソースを探しだし、makeが終わったと思ったらprefix間違えたorzなんて経験おありかと思います。(いや、そんな環境コロコロ変わらないが)

そんな私を救ってくれたのが LPM: Local Package Manager でした。
Linux を使っていて、root は持っていないけど新規にソフトをインストールしたいと思ったことはありませんか? ちゃんとパッケージ化されていないソフトをインストールするのが面倒だと思ったことはありませんか? あなたの環境でコンパイラエラーを回避するために何度も同じパッチを当てなければならなかったことはありませんか? そんな貴方に LPM は手をさしのべます。
( LPM: Local Package Manager, http://www.kasahara.ws/lpm/index_ja.html, 2013/06/17. )
とあるように、便利でした。1ページのDocumentを読めば、すべての使い方が分かります。lpmスクリプトの書き方もわかります。

vimとかzshとかリポジトリになかったので、オレオレlpmスクリプト作成。
オレオレlpm https://github.com/takkyuuplayer/lpm/tree/master/lpm

そのうちサブミッションしてみようかな、と思います。

Wordpress on AWS やめたった

皆様、円安の昨今いかがお過ごしでしょうか?

私の方はというとAWSの1年間無料利用枠が4月で期限切れになりまして、先月よりきっちり従量課金されるようになりました。その額なんと

56.04 [USD] -> 5,720[JPY]

GW中に調子に乗ってWordpressのDBをlocalhostからRDSに変えなきゃよかった・・・。という反省はさておき、大したアクセスもないのに毎月6000円近く取られるのはキツいです。そこで
  • 開発機用EC2インスタンスを閉じ、開発にはVagrantを利用
  • BlogはBloggerに移動し、RDSは閉じる
  • そのついでに静的コンテンツもWordpressからSinatraへ移行
しました。その際困ったのがブログの更新をどうホームページ上で見せるか?というもの。

こんなの


まぁそういうのはフィードを使うと相場は決まっているわけでして、例に漏れずやってみました。

feedzirraを使った更新一覧表示

rubygemでRSSのパーサーを探していたらfeedzirraに出会いました。他にもいろいろ出会いましたがThe Ruby Toolbox - Atom & RSS Feed Parsingによると一番人気があるようだったので利用。コードは以下です。
できました!ですが、なんか重いです。それはそうです。毎回RSS取りに行ってパースするのだから。キャッシュが必要です。最初sinatraでやろうと調べていたのですが、途中でnginxに任せればいいじゃん、という事に気づきました。nginxでプロキシ&キャッシュサーバー « chibiegg日誌を参考に設定。 これでストレスなく?表示されるようになりました。

2012年12月19日水曜日

国会図書館のすすめ [#vgadvent2012]

※この記事はAdvent Calendar 2012 - Voyage Group Engineer blog - の一環として書かれています。

いやはや、Advent Calenderに向けて放置してたブログを書いたりデザインを一新したりする野望を抱えていたのですが、あえなく当日を迎えてしまいました@takkyuuplayerです。

土日は意外とやることが少ない


社会人になって土日の有難さが分かる、とは言いますが私が社会人になって感じたのは規則正しい生活の心地よさと「土日は意外とやることが少ない」ってことです。普段ずっと椅子に座りっぱなしだから運動でもするか!と意気込んでいてもいざ土日を迎えると体を動かす気力を失ってしまいます。そこでお勧めなのが国会図書館です。

自転車で国会図書館へ行こう


もし自宅から国会図書館への距離が10km程度なら、是非自転車で国会図書館へ乗り込みましょう。片道40分ほどでなまった体にはちょうど良い運動量です。




自転車置き場から眺めた国会図書館


なぜ国会図書館なのか?


図書館は近くにあるのに、なぜわざわざ遠い国会図書館まで足を運ぶのか?それは日本で出版された全ての本が読めるからです。国会図書館には納本制度というものがあります。
 「納本制度」とは、図書等の出版物をその国の責任ある公的機関に納入することを発行者等に義務づける制度のことです。わが国では、国立国会図書館法(昭和23年法律第5号)により、国内で発行されたすべての出版物を、国立国会図書館に納入することが義務づけられています。
納本制度|国立国会図書館―National Diet Library http://www.ndl.go.jp/jp/aboutus/deposit.html

国会図書館の本は館外へ持ち出すことはできません。そのため普通の図書館のように借りて家で読むということもできないのですが、代わりに朝一で行けばどんな人気の本でも読めるというメリットがあります。私の場合平日はエンジニアリングの本しか読みませんので、国会図書館では営業の人とかの日報で挙がった非エンジニアリング関係の本や、学生時代に打ち込んだ理数関係の本を読むことにしています。

また国会図書館では一切外に出ることなく丸一日遊べます。なんと館内には「食堂・コンビニ・カフェ」が存在します。食事をしに外へ出る必要は無く、値段も学食と同等の安さです。空調も完璧、電源もあります。さすがに無線LANはありませんが、むしろ気付いたらネットサーフィンにならなくて済むのでよいのではないでしょうか?

もちろん運動のきっかけを作れることも国会図書館へ行く理由の1つです。週に一度とはいえ、往復90分弱のサイクリングはデスクワークで衰えた体を引き締める効果があります。

国会図書館に弱点ってあるの?


一見完璧に見えますが、この世に完璧はありません。国会図書館にももちろん弱点があります。まず致命的なのは日曜日が休館日なことです。図書館は月曜日が休館日と相場が決まっていそうなものを、国会図書館は日曜日に休みます。日曜日もやっていれば土日の使い方は確定したのですが・・・。

もうひとつたまに傷になるのが立地条件です。隣に国会議事堂があるということは、当然そこでデモが開催される可能性があります。図書館という性質上基本は静かなのですが、デモが始まるとやや騒々しくなります。

雨が降ったらOASISへ


いかがでしたでしょうか?国会図書館の魅力は伝わりましたでしょうか?私はそんな国会図書館の魅力に惹かれ、雨の日も風の日も毎週欠かさず行っている、と言いたいところですがさすがに雨が降ると自転車では行けません。かといって電車で行く感じでもないのです。そんな時は会社の図書館OASISへ行きます(盛った)。OASISにはビジネス・テクノロジー・アイデア・マンガという4つのジャンルの本が取り揃えられています。同じIT業界に興味を持った同士、本の趣味も似ていて楽しいです。


社内用ライブラリ OASIS

次回予告

次回のAdvent Calender担当は@hagino3000さんです。

2012年7月4日水曜日

Slimを読む(1)

今週からは Home - Slim Framework for PHP 5 を読み始める。symfony2はどうなったのか?重い。やっぱり軽いOSSから読んでいかないと。

はじめに


環境: Amazon EC2, Amazon Linux AMI x86_64 EBS
ソースコード:Symfony2.0.15

まずはコードを動かしてみる


なにはともあれ、動かしてみるところから。

ソースコードの配置


[bash]
~$ cd /var/www/
/var/www$ wget https://github.com/codeguy/Slim/zipball/master
/var/www$ mv codeguy-Slim-29d662d/ slim
[/bash]

バーチャルホストの設定


/etc/httpd/conf.d/slim.conf
[text]

ServerName slim.wordpress.takkyuuplayer.vagrant
DocumentRoot /var/www/html/slim/
ErrorLog logs/slim-error_log
CustomLog logs/slim-access_log combined env=!no_log

[/text]

[bash]
/var/www$ sudo service httpd restart
[/bash]

http://slim.wordpress.takkyuuplayer.vagrant/にアクセスすればSlimのトップ画面が表示されるはずだ。

2012年6月21日木曜日

symfony2を読む(3)

さて、前回に引き続きsymfony2を読み解く。今日は以下の箇所について調べる。

./web/app_dev.php


[php]
Request::createFromGlobals()
[/php]

vendor/symfony/src/Symfony/Component/HttpFoundation/Request.php


[php]
static public function createFromGlobals()
{
$request = new static($_GET, $_POST, array(), $_COOKIE, $_FILES, $_SERVER);

if (0 === strpos($request->server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
&& in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE'))
) {
parse_str($request->getContent(), $data);
$request->request = new ParameterBag($data);
}

return $request;
}
[/php]
1行目, new static ってなんだ!? new self と new static の違い - Sarabande.jp によると、記述元のクラスでメソッド呼び出された風になるのが、new self, 呼び出し元のクラスでメソッド呼び出し風になるのが new static とのことだが、今回は記述元も呼び出し元も同じである。例えばJavaでstatic int といえばすべてのインスタンスで共有したいintを指すが、今回は他のクラスからRequestインスタンスを呼び出すときに同一のものを扱いたい、ということなのだろうか?そういうことにしておこう。何はともあれ、コンストラクタの呼び出しがあり、そこで初期化のための関数が呼ばれる。
[php]
public function __construct(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
$this->initialize($query, $request, $attributes, $cookies, $files, $server, $content);
}
public function initialize(array $query = array(), array $request = array(), array $attributes = array(), array $cookies = array(), array $files = array(), array $server = array(), $content = null)
{
$this->request = new ParameterBag($request);
$this->query = new ParameterBag($query);
$this->attributes = new ParameterBag($attributes);
$this->cookies = new ParameterBag($cookies);
$this->files = new FileBag($files);
$this->server = new ServerBag($server);
$this->headers = new HeaderBag($this->server->getHeaders());

$this->content = $content;
$this->languages = null;
$this->charsets = null;
$this->acceptableContentTypes = null;
$this->pathInfo = null;
$this->requestUri = null;
$this->baseUrl = null;
$this->basePath = null;
$this->method = null;
$this->format = null;
}
[/php]
ここではキーと値を格納するクラスParameterBagのインスタンスが内部変数に格納される。createFromGlobalsに戻ろう。
[php]
if (0 === strpos($request->server->get('CONTENT_TYPE'), 'application/x-www-form-urlencoded')
&& in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), array('PUT', 'DELETE'))
) {
parse_str($request->getContent(), $data);
$request->request = new ParameterBag($data);
}
[/php]
if文の中には

  1. ファイルアップロードで使われるようなCONTENT_TYPEではない。

  2. PUT OR DELETE メソッド


の2つを満たす時にだけ入る。このとき、リクエストの内容はrequestBodyに書き換えられる。

最後に Requestクラスのstaticインスタンスを返して終了だ。

2012年6月18日月曜日

symfony2を読む(2)

昨日に引き続き、symfony2を読む。カレントディレクトリをsymfony2のインストールディレクトリとする。

web/app_dev.php


[php]
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';

use Symfony\Component\HttpFoundation\Request;

$kernel = new AppKernel('dev', true);
$kernel->loadClassCache();
$kernel->handle(Request::createFromGlobals())->send();
[/php]

useにより、$SYMFONY2_DIR/vendor/symfony/src/Symfony/Component/HttpFoundation/Request.php を読み出している。
この $SYMFONY2_DIR/vendor/symfony/src の位置はどうやって伝えられたのだろうか?それは bootstrap.php.cache 内で読み込まれた autoload.php に秘密があった。

app/autoload.php


[php]
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
'Symfony' => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
[/php]

loadClassCache(), handle()はともにAppKernelの親クラスであるKernelクラスの下記メソッドが呼ばれている。

vendor/symfony/src/Symfony/Component/HttpKernel/Kernel.php


[php]
public function loadClassCache($name = 'classes', $extension = '.php')
{
if (!$this->booted && file_exists($this->getCacheDir().'/classes.map')) {
ClassCollectionLoader::load(include($this->getCacheDir().'/classes.map'), $this->getCacheDir(), $name, $this->debug, false, $extension);
}
}
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
if (false === $this->booted) {
$this->boot();
}

return $this->getHttpKernel()->handle($request, $type, $catch);
}
[/php]
今日は loadClassCache()の挙動をよく調べてみよう。まず
[php]
$this->booted # false
$this->getCacheDir().'/classes.map' # app/cache/dev/classes.map
[/php]
となっている。bootedの値ついては__constructメソッドを読めば分かる。
[php]
ClassCollectionLoader::load
[/php]
では、下記クラスのloadメソッドが呼ばれている。

vendor/symfony/src/Symfony/Component/ClassLoader/ClassCollectionLoader.php


[php]
static public function load($classes, $cacheDir, $name, $autoReload, $adaptive = false, $extension = '.php')
{
// each $name can only be loaded once per PHP process
if (isset(self::$loaded[$name])) {
return;
}

self::$loaded[$name] = true;
[/php]
$nameという名前で、$classesに渡されたクラス群を読み込むらしい。$nameと$classesは一対一対応となっている。
[php]
if ($adaptive) {
// don't include already declared classes
$classes = array_diff($classes, get_declared_classes(), get_declared_interfaces());

// the cache is different depending on which classes are already declared
$name = $name.'-'.substr(md5(implode('|', $classes)), 0, 5);
}
[/php]
ここでは $adaptive = false なのでif文の中には入らない。

[php]
// auto-reload
$reload = false;
if ($autoReload) {
$metadata = $cacheDir.'/'.$name.$extension.'.meta';
if (!file_exists($metadata) || !file_exists($cache)) {
$reload = true;
} else {
$time = filemtime($cache);
$meta = unserialize(file_get_contents($metadata));

if ($meta[1] != $classes) {
$reload = true;
} else {
foreach ($meta[0] as $resource) {
if (!file_exists($resource) || filemtime($resource) > $time) {
$reload = true;

break;
}
}
}
}
}

if (!$reload && file_exists($cache)) {
require_once $cache;

return;
}
[/php]
$autoReload変数には今回true(AppKernel->debug)が渡されているのでif文の中に入る。ここでは$classesを再度読み込み直すか?それともキャッシュされたクラスをそのまま使うのかが指定されている。再読み込みする条件は3つ。

  1. そもそもキャッシュが存在しない

  2. キャッシュされているクラス群と読み込もうとしているクラス群が異なる

  3. キャッシュ元のクラスが更新されている


[php]

$files = array();
$content = '';
foreach ($classes as $class) {
if (!class_exists($class) && !interface_exists($class) && (!function_exists('trait_exists') || !trait_exists($class))) {
throw new \InvalidArgumentException(sprintf('Unable to load class "%s"', $class));
}

$r = new \ReflectionClass($class);
$files[] = $r->getFileName();

$c = preg_replace(array('/^\s*<\?php/', '/\?>\s*$/'), '', file_get_contents($r->getFileName()));

// add namespace declaration for global code
if (!$r->inNamespace()) {
$c = "\nnamespace\n{\n".self::stripComments($c)."\n}\n";
} else {
$c = self::fixNamespaceDeclarations(' $c = preg_replace('/^\s*<\?php/', '', $c);
}

$content .= $c;
}

// cache the core classes
if (!is_dir(dirname($cache))) {
mkdir(dirname($cache), 0777, true);
}
self::writeCacheFile($cache, '[/php]
$classesを1つずつ読み込み、最終的にすべてのクラスを1つのファイル($cacheDir.'/'.$name.$extension)にまとめている。ここで$nameと$classesを一対一対応にしたことが効いてくる。

[php]
if ($autoReload) {
// save the resources
self::writeCacheFile($metadata, serialize(array($files, $classes)));
}
[/php]
オブジェクトを直列化してファイルを保存する。

dev環境、prod環境でのautoReloadの違い


prod環境では$autoReload=falseとなり、キャッシュを消すまで古いクラスが使われ続ける。これは安定した速い運用が求められるprod環境に適している。対してdev環境では$autoReload=trueとなり、常に最新のソースコードでSymfonyを動かすことになる。多少ブラウザ表示が遅くなるとはいえ、開発効率を上げるための工夫である。

2012年6月17日日曜日

symfony2を読む(1)

はじめに


環境: Amazon EC2, Amazon Linux AMI x86_64 EBS
ソースコード:Symfony2.0.15

まずはコードを動かしてみる


参考:The Big Picture (current) - Symfony

ソースコードの配置


[bash]
~$wget http://symfony.com/get/Symfony_Standard_Vendors_2.0.15.tgz
~$tar xvf Symfony_Standard_Vendors_2.0.15.tgz
~$mv Symfony /var/www/html/symfony2
[/bash]

バーチャルホストの設定


参考:バーチャルホスト設定 - CentOSで自宅サーバー構築
DocumentRoot /var/www/html/symfony2/web
に対してバーチャルホストを設定。

config.phpを表示


アクセス情報【使用中のIPアドレス確認】にて自分の現在のIPアドレスを確認。
/var/www/html/symfony2/web/ を開いて
[php]
if (!in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
'Your.Current.Ip.Address',
))) {
header('HTTP/1.0 403 Forbidden');
exit('This script is only accessible from localhost.');
}
[/php]
のように編集。その後 http://symfony2.yourdomain.com/config.php アクセス。表示に従い必要なライブラリのインストールや、フォルダの作成などを行う。

app_dev.phpを表示


config.phpと同様に
[php]
if (isset($_SERVER['HTTP_CLIENT_IP'])
|| isset($_SERVER['HTTP_X_FORWARDED_FOR'])
|| !in_array(@$_SERVER['REMOTE_ADDR'], array(
'127.0.0.1',
'::1',
'Your.Current.Ip.Address',
))
) {
header('HTTP/1.0 403 Forbidden');
exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
}
[/php]
と編集。その後 http://symfony2.yourdomain.com/app_dev.php にアクセスすると以下のような画面が表示される。
app_dev

2012年5月1日火曜日

Amazon EC2入門

Amazon EC2の登録からssh接続までの作業ログ。

環境:Ubuntu12.04 x32

EC2の仮想サーバー起動まで

Amazon Web Services (日本語)にて、「今すぐ申し込む」からAWSを利用するための登録を行う。
登録が完了したらログインして「アカウント/コンソール」からAWS Management Consoleを開く 
 EC2タブへ移動し、Launch Instanceをクリック

①ssh公開鍵を作成しダウンロード
②サーバーを選んで
③Continue

 Launch
 
 ①NavigationタブからInstancesを表示 ②Status Check欄が準備完了となるのを待つ 

sshでログイン

ssh公開鍵の移動
[bash]
~$ mkdir .ssh
~$ mv
~/ダウンロード/takkyuuplayer.pem .ssh
[/bash]
公開鍵のパーミション変更
[bash]
~$ chmod 400 .ssh/takkyuuplayer.pem
[/bash]
Public DNSの確認

ssh接続
[bash]
~$ ssh -i ~/.ssh/takkyuuplayer.pem ec2-user@PublicDNS
[/bash]
これでssh接続は完了する。

らくらくssh接続

PublicDNSをいちいち覚えていられないので、簡単にAWSに接続できるようにconfigファイルを作る。
[bash]
~$ vi ~/.ssh/config
[/bash]

[text]
Host ec2
User ec2-user
HostName PublicDNS
Port 22
IdentityFile ~/.ssh/takkyuuplayer.pem
[/text]

すると以下の簡略コマンドで接続可能になる

[bash]
~$ ssh ec2
[/bash]

2011年11月28日月曜日

GoogleのOCR tesseract-ocr

GoogleのオープンソースOCR、tesseract-ocrのインストールと実行テスト。

環境:Ubuntu11.10x32
バージョン:Tesseract3.01

tesseract-ocrとは


the 1995 UNLV Accuracy testでトップ3に入ったOCRエンジン。1995-2006までほそぼそと開発が進められたが、その後Googleがホストとなりオープンソース化した。tesseractTrainer.pyは GPL, それ以外は Apache2.0 ライセンスのもと公開されている。

インストール


依存ライブラリのインストール
[bash]
~$ sudo apt-get install autoconf automake libtool
~$ sudo apt-get install libpng12-dev
~$ sudo apt-get install libjpeg62-dev
~$ sudo apt-get install libtiff4-dev
~$ sudo apt-get install zlib1g-dev
~$ sudo apt-get install libleptonica-dev
~$ sudo Idconfig
[/bash]
subversionのインストール
[bash]
~$ sudo apt-get install subversion subversion-tools
[/bash]
tesseractのチェックアウト
[bash]
~$ svn checkout http://tesseract-ocr.googlecode.com/svn/trunk/ tesseract-ocr-read-only
[/bash]
tesseractのインストール
[bash]
~$ cd tesseract-ocr-read-only
~/tesseract-ocr-read-only$ ./autogen.sh
~/tesseract-ocr-read-only$ ./configure
~/tesseract-ocr-read-only$ make
~/tesseract-ocr-read-only$ sudo make install
[/bash]
言語データのインストール
[bash]
~/tesseract-ocr-read-only$ cd
~$ wget http://tesseract-ocr.googlecode.com/files/eng.traineddata.gz
~$ gzip -d eng.traineddata.gz
~$ sudo mv eng.traineddata /usr/local/share/tessdata/
[/bash]

実行


[bash]
~$ tesseract hogehpge.jpg
[/bash]

TeXのインストール

UbuntuでTeXを使いたくなったのでインストールした。参考にしたのは
Ubuntu 11.10 TexLive 2011 - cloverroseUbuntu で TeX Live 2011 を利用する | Amrta

環境
Ubuntu 11.10x32

日本語用のTexをダウンロードし、リポジトリに追加


[bash]
~$ wget -q https://www.ubuntulinux.jp/ubuntu-ja-archive-keyring.gpg -O- | sudo apt-key add -
~$ wget -q https://www.ubuntulinux.jp/ubuntu-jp-ppa-keyring.gpg -O- | sudo apt-key add -
~$ sudo wget https://www.ubuntulinux.jp/sources.list.d/oneiric.list -O /etc/apt/sources.list.d/ubuntu-ja.list
~$ sudo apt-get update
[/bash]

TexLiveインストール


[bash]
~$ sudo apt-get update
~$ sudo apt-get install texlive-full
[/bash]

日本語環境インストール


インストール時のオプションはUbuntu で TeX Live 2011 を利用する | Amrtaを参考に。
[bash]
~$ wget http://mirror.ctan.org/systems/texlive/tlnet/install-tl-unx.tar.gz
~$ tar xvf install-tl-unx.tar.gz
~$ cd install-tl-20111028/
~$ sudo ./install-tl
[/bash]

2011年11月27日日曜日

Bitbucket 入門

先日githubにプログラムを上げた。無料アカウントではgithubに非公開プログラムを置けないので、非公開のプログラムはFree source code hosting — Bitbucketにホスティングすることにした。ついでにMercurialにも入門。

環境
Ubuntu 11.10 x32

bitbhcketのアカウント取得


Symfoware bitbucket アカウントとリポジトリの作成を参考に,Sign upから行う.

リポジトリ作成


右上のメニューから
[text]
Repositories > create repository
[/text]
レポジトリの作成ができる。

Mercurial インストール


[bash]
~$ sudo apt-get install mercurial
[/bash]

cloneの作成


ローカル・リポジトリの作成は
[bash]
~$ hg clone https://takkyuuplayer@bitbucket.org/takkyuuplayer/test
[/bash]
で可能。

EclipseでMercurial


Eclipseのプラグインアップデートサイトは
[text]
http://cbes.javaforge.com/update
[/text]
にある。詳しい操作方法はSymfoware EclipseにMercurialプラグインをインストールし、bitbucketにプッシュするを参考にすればできる。

2011年10月31日月曜日

Github 入門

今日「pdfファイルに対して1頁毎に空白のページを挿入する」というソフトウェアを書いた。git入門がてらそのプログラムをgithubにあげた。takkyuuplayer/zeminar - GitHub


環境
Ubuntu 11.10 x32

gitインストール


[bash]
$ sudo apt-get install -y git-all
[/bash]
めんどくさかったのでallでインストール。これでいいのかな?

githubアカウント作成


github 超入門 - glasses factory を参考にすればできた。

githubにプロジェクトをあげる


github もうちょい入門 - glasses factory を参考にすればできたが一箇所だけ追記。github へ公開鍵の設定 においてLinux環境ではgithubへのSSH接続テスト
[bash]
./ssh$ ssh -T git@github.com
[/bash]
に失敗する。上記接続テストをする前にで生成したsshキーを有効にしておかなければならない。
[bash]
./ssh$ ssh-add ~/.ssh/id_rsa
./ssh$ ssh -T git@github.com
[/bash]
あとは書いてある通りにやればいい。

2011年10月29日土曜日

デフォルトのブートOSを変更

Windows Server 2008 R2 とUbuntu11.10のデュアルブートをしているわけだけど、デフォルトのブートOSをUbuntuからWindowsに変更する方法。Ubuntu-9.10をインストール。 いろいろ変わってて困ってしまう。 - Okumatsu_Hiroshiの覚書を参考に。

[bash]
$ sudo vi /etc/default/grub
[/bash]
でブート設定ファイルを開き、デフォルトでは
[text]
GRUB_DEFAULT=0
[/text]
となっているところを、ブートしたいOSの番号に書き換えればよい。番号はPC起動時にでるブートメニューを上から順に0,1,2,...と数えた時の番号だ。最後に
[bash]
$ sudo update-grub
[/bash]
とやって終わり。

2011年10月28日金曜日

Ubuntu に Eclipseをインストールして日本語化

Javaのインストール


【Ubuntu】JAVA 7 (JDK 1.7.0) インストール (ただ、色々問題が・・・):を参考にインストール

Java SE Downloadsよりjdkをダウンロード

解凍→フォルダ移動
[bash]
$ cd ダウンロード
~/ダウンロード $ tar xf jdk-7u1-linux-i586.tar.gz
~/ダウンロード $ sudo cp -R jdk1.7.0 /usr/lib/jvm/
[/bash]

JAVA 有効化ツールインストール→実行
[bash]
$ sudo add-apt-repository ppa:nilarimogard/webupd8
$ sudo apt-get update
$ sudo apt-get install update-java
$ sudo update-java
[/bash]

確認

[bash]
$ java -version
[/bash]

Eclipseのインストール


【Ubuntu 11.04】 Eclipse 3.7M6(Indigo) + CDT 8.0 + Pleiades 1.3.3(日本語化):なんでもかんでもコンピュータ:So-netブログを参考にインストール

Eclipse Project DownloadsからEclipseをダウンロード。日本語化に利用するPleiades - Eclipse プラグイン日本語化プラグインが3.x系にしか対応していないので3.7.1をダウンロードした。

解凍→インストール
[bash]
$ cd /usr/local/lib
/usr/local/lib$ sudo tar xf ~/ダウンロード/eclipse-SDK-3.7.1-linux-gtk.tar.gz
[/bash]

起動コマンドの作成
[bash]
$ cd /usr/bin
/usr/bin$ sudo vi eclipse
[/bash]
以下のようなファイル作成
[bash]
#!/bin/sh

export GDK_NATIVE_WINDOWS=true
ECLIPSE=/usr/local/lib/eclipse/eclipse
exec $ECLIPSE "$@"
[/bash]
実行権限付与
[bash]
/usr/bin$ sudo chmod +x eclipse
[/bash]

起動メニュー作成
[bash]
$ cd /usr/share/applications/
$ sudo vi eclipse.desktop
[/bash]
下記を記入
[text]
[Desktop Entry]
Encoding=UTF-8
Name=Eclipse
Comment=Eclipse IDE
Exec=eclipse
Icon=/usr/local/lib/eclipse/icon.xpm
Terminal=false
Type=Application
Categories=GNOME;Application;Development;
StartupNotify=true
[/text]

日本語化


Pleiades - Eclipse プラグイン日本語化プラグイン からPleiades本体をダウンロード
[bash]
$ cd /usr/local/lib/eclipse/
/usr/local/lib/eclipse$ sudo unzip ~/ダウンロード/pleiades.zip
/usr/local/lib/eclipse$ sudo vi eclipse.ini
[/bash]
最終行に以下を追加
[text]
-javaagent:/usr/local/lib/eclipse/plugins/jp.sourceforge.mergedoc.pleiades/pleiades.jar
[/text]
スプラッシュ変更のため、2行コメントアウト
[text]
#-showsplash
#org.eclipse.platform
[/text]

初起動


一度ログアウトか再起動してから
[bash]
$ eclipse -clean
[/bash]
で起動。以降は -clean は不要

Ubuntuにrpmパッケージインストール

rpmパッケージをインストールするにはalienというrpmをdebに変換するコマンドが便利らしい。参考UbuntuでRPMをインストールする件 - システムエンジニア奮闘記 ~ダメダメSEの備忘録~


alienをインストール


[bash]
sudo apt-get install -y alien
[/bash]

rpmのインストール


alienを使ってrpm -> deb 変換
[bash]
sudo alien Package.rpm
[/bash]
直接インストール
[bash]
sudo apt-get install -y Package.rpm
[/bash]

2011年9月9日金曜日

Wordpress移転

http://wordpress.takkyuuplayer.vagrant/ 上のWordpressをローカルの Ubuntu11.04 にバックアップ。その手順のまとめ。これはWordpress移転にも使える。

DBのエクスポート


phpmyadminを用いて、Wordpress関連の全テーブルをエクスポート。その際、
[text]
DROP TABLE / VIEW / PROCEDURE / FUNCTION / EVENT
[/text]
にチェックを入れるのを忘れずに。仮にnetau.sqlというファイル名で保存されたものとする。

Wordpressファイルのダウンロード


FileZilla のインストール
[bash]
~$ sudo apt-get install filezilla
[/bash]
/var/www/の権限変更
[bash]
~$sudo chown -R takkyuuplayer:www-data /var/www/
~$sudo chmod 750 /var/www/
~$sudo usermod -g www-data takkyuuplayer
[/bash]
Filezillaを起動しhttp://wordpress.takkyuuplayer.vagrant/のpublic_htmlディレクトリの中身を/var/www/netauに突っ込んだ。

local環境の準備


mod_rewriteをONにする。
[bash]
~$sudo a2enmod rewrite
[/bash]
Overrideを許可する。
[bash]
~$ sudo vi /etc/apache2/sites-available/default
[/bash]
[text]

Options Indexes FollowSymLinks MultiViews
AllowOverride None -> Allに変更
Order allow,deny
allow from all

[/text]
apache再起動
[bash]
~$ sudo /etc/init.d/apache2 restart
[/bash]
.htaccessのpermissionを777に。
[bash]
~$ chmod 777 /var/www/netau/.htaccess
[/bash]

データベースの作成


/var/www/netau/wp-config.phpを開く
[bash]
~$ vi /var/www/netau/wp-config.php
[/bash]
ホスト名はlocalhostに変える。その他も変えたければ変更する。
[php]
/** MySQL のホスト名 */
define('DB_HOST', 'localhost');
[/php]
wp-config.phpファイルを参考に、ローカルのMySQLサーバー上にDBを作成。文字コードの照合順序(utf8_general_ciにする)に注意。
エディタでnetau.sqlを開き、wordpress.takkyuuplayer.vagrant→wordpress.takkyuuplayer.vagrantに全置換
phpmyadminにnetau.sqlをインポートし実行。

バックアップできているか確認


http://wordpress.takkyuuplayer.vagrant/にアクセスし、正常に表示されるか見てみる。
文字化けしたら

データベースの照合順序やnetau.sqlの文字コードを確認しよう。
404になったら

mod_rewriteの設定が怪しい。パーマリンク設定をデフォルトに変えて記事が表示されるようなら、mod_rewrite関連や.htaccessの設定を見直す必要がある。それでも表示されないならデータベースの作成をもう一度やり直そう。

以上で完了だ。