アクセスログのパースはたまにしかやらないけど、忘れるので書いとこう
<?php $fp = fopen('access_log','r'); while ($d = fgets($fp, 8192)){ var_dump(parse_log($d)); } function parse_log($line){ if (preg_match('@^([\d\.]+) \- \- \[(.*)\] "(GET|POST|HEAD) ([^ ]+) HTTP/([^ ]+)" (.*) (.*) "(.*)" "(.*)"$@', rtrim($line), $matches)) { // 4xx エラーコードは処理しない $ip = $matches[1]; $status = $matches[6]; if (preg_match('@^4\d{2}$@',$status)) return; $parts = preg_split("@[: /]@", $matches[2]); $epoch = strtotime(sprintf("%d %s %d %d:%d:%d", $parts[0], $parts[1], $parts[2], $parts[3], $parts[4], $parts[5])); $t = strftime("%Y-%m-%d %H:%M:%S", $epoch); $req = $matches[4]; $ref = $matches[8]; $ua = $matches[9]; return compact("ip","status","req","ref","ua","t"); } }
yesodを試す
ubuntu server 64bit 11.10 環境でyesodを始める
haskell-platformによると、ubutnu 11.10はhaskell-platform-2011.2.0.2がはいる。cabalは0.10.2が入った。
% sudo aptitude install haskell-platform % sudo aptitude install libedit-dev libbsd-dev libgmp3-dev zlib1g-dev freeglut3-dev % cabal update // ここでコーヒータイム % cabal install yesod // pathを通す % echo 'PATH=$HOME/.cabal/bin:$PATH' >> ~/.zshrc % source ~/.zshrc // init実行で対話モード % yesod init Welcome to the Yesod scaffolder. I'm going to be creating a skeleton Yesod project for you. What is your name? We're going to put this in the cabal and LICENSE files. Your name: otmb Welcome otmb. What do you want to call your project? We'll use this for the cabal name. Project name: yesodtest Great, we'll be creating yesodtest today, and placing it in yesodtest. What's going to be the name of your foundation datatype? This name must start with a capital letter. Foundation: Yesodtest Yesod uses Persistent for its (you guessed it) persistence layer. This tool will build in either SQLite or PostgreSQL or MongoDB support for you. We recommend starting with SQLite: it has no dependencies. We have another option: a tiny project with minimal dependencies. Mostly this means no database and no authentication. So, what'll it be? s for sqlite, p for postgresql, m for mongodb, or t for tiny: m
次にプロジェクト作成
% cd yesodtest % cabal configure -fproduction Resolving dependencies... Configuring yesodtest-0.0.0... cabal: At least the following dependencies are missing: hjsmin >=0.0.14 && <0.1, persistent-mongoDB ==0.6.*, yesod-default ==0.4.*, yesod-static >=0.3.1 && <0.4 // 色々無いと怒られた % cabal install hjsmin persistent-mongoDB yesod-default yesod-static // 気を取り直してconfigure % cabal configure -fproduction % cabal build
Herokuに登録
前回からの続き
Getting Started with Herokuを参考にherokuをinstall
// rvm インストールしてパスを通す % sudo aptitude install curl git make % bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer) % echo 'PATH=$HOME/.rvm/bin:$PATH' >> ~/.zshrc % source ~/.zshrc % rvm install 1.9.2 && rvm use 1.9.2 --default // heroku インストール % gem install heroku % echo 'PATH=$HOME/.rvm/gems/ruby-1.9.2-p290/gems/heroku-2.14.0/bin:$PATH' >> ~/.zshrc % source ~/.zshrc % heroku version // ここで apt-get install libopenssl-ruby とか出るがパッケージ探しても無いので下記で対応 % rvm pkg install openssl % rvm install 1.9.2 -C --with-openssl-dir=$HOME/.rvm/usr
ちなみにパスを$HOME/.rvm/gems/ruby-1.9.2-p290/gems/binにすると以下のエラーが出た。
/home/xxxx/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/site_ruby/1.9.1/rubygems/dependency.rb:247:in `to_specs': Could not find heroku (>= 0) amongst [minitest-1.6.0, rake-0.8.7, rdoc-2.5.8] (Gem::LoadError)
あとは、「Haskell on Heroku」を参考で完了。
IRCの部屋に在席してる人を取得してくる
PEARのライブラリの使い方がいまひとつ解らなかったので自分で書いてみた。
<?php $host = '192.168.100.10'; $port = 6667; $irc = new irc(); $irc->connect($host,$port); $irc->login('test_bot'); $irc->read(); $irc->send('names #testroom'); $buffer = $irc->read(); $row = split("\n",$buffer); $members = preg_replace("@^:(.*):(.*)$@",'$2',$row[0]); echo "<html><body><h1>IRC Login User</h1><pre>"; foreach(split(" ",$members) as $name){ echo $name ."\n"; } echo "</pre></body></html>"; class irc { function connect($host,$port,$timeout=30){ $this->sock = fsockopen($host,$port,$errno,$errstr,$timeout); if (!$this->sock) echo "{$errstr} ({$errno})"; } function send($cmd){ $cmd .= "\n"; fwrite($this->sock, $cmd); } function login($nickname, $username='user', $password = "", $realname='bot', $hostname='hoge', $servername='hoge'){ $this->send(sprintf("USER %s %s %s %s",$username, $hostname, $servername, $realname)); $this->send("NICK " . $nickname); } function read(){ return fread($this->sock,4096); } }
Redmineの $git pullが遅いので。。
script/runner "Repository.fetch_changesets" -e production だと全てのプロジェクトのリポジトリを更新して遅いので、指定のプロジェクトだけを更新するようにした。
こんな感じにシェルを作成して、コードの指定がある場合は指定プロジェクトのみを更新するようにした。
- hooks/post-update
#!/bin/sh /usr/local/bin/post-commit.sh [プロジェクトコード]
- post-commit.sh
#!/bin/sh APIKEY="APIのKEY" ID=$1 if [ $# = 0 ]; then /usr/local/bin/ruby /var/lib/redmine/script/runner "Repository.fetch_changesets" -e production else /usr/bin/wget -q -O /dev/null "https://[RedmineのURL]/sys/fetch_changesets?key=${APIKEY}&id=${ID}" fi
Gitを使ってコンフリクトを試す
※Git version 1.7.4.1 で試しました。
資料はPro Gitを参考にまとめました。
master ブランチのみでコンフリクトしてみる
- 同じファイルに変更がかかっているとpullは出来ない
% git pull remote: Counting objects: 4, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From gkan:gittest c90d273..c3a0c18 master -> origin/master Updating c90d273..c3a0c18 error: The following untracked working tree files would be overwritten by merge: config.yml Please move or remove them before you can merge. Aborting
- ローカルのリポジトリにコミットするとpullできる。pullすると勝手にmergeされる
% git commit -am 'change config.yml' [master 0d9553e] change config.yml 1 files changed, 2 insertions(+), 0 deletions(-) create mode 100644 config.yml % git pull Auto-merging config.yml CONFLICT (add/add): Merge conflict in config.yml Automatic merge failed; fix conflicts and then commit the result. // 中身 % cat config.yml <<<<<<< HEAD hage hage ======= hoge hoge hoge >>>>>>> c3a0c186114523678443d95a62c97c1b8763a503 // 修正する % git mergetool % git commit -am 'conflict config.yml fix' % git push
○考察
これがsubversionの場合 $ svn update でコンフリクトするとファイルが消滅する可能性があるがcommitしているので消える心配はない。
以下はその確認。
% git show c3a0c186114523678443d95a62c97c1b8763a503:config.yml hoge hoge hoge % git show 5fde2874f852ba978e96a51c302395e842aee0c0:config.yml hage hage
ローカルブランチを用意してコンフリクトしてみる
- ブランチdevを作成して、masterで変更内容を取得
% git checkout -b dev Switched to a new branch 'dev' // 変更してcommit % vi config.yml % git commit -am 'change config.yml' [dev 1d9b4d1] change config.yml 1 files changed, 2 insertions(+), 0 deletions(-) // masterに切替て変更内容取得 % git checkout master Switched to branch 'master' % git pull remote: Counting objects: 5, done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From gkan:gittest 5fde287..ce03373 master -> origin/master Updating 5fde287..ce03373 Fast-forward config.yml | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
- masterのブランチにdevの内容を反映するとコンフリクトになる
% git merge dev Auto-merging config.yml CONFLICT (content): Merge conflict in config.yml Automatic merge failed; fix conflicts and then commit the result. // conflictを修正してリモートのリポジトリに反映 % git mergetool % git commit -am 'conflict config.yml fix' [master 5d09e4e] conflict config.yml fix % git push Counting objects: 10, done. // dev に切替 % git checkout dev Switched to branch 'dev' // mergeするとmasterを真として適用された % git merge master Updating 1d9b4d1..5d09e4e Fast-forward config.yml | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
○考察
本番サイトはreleaseタグを切って運用となるが、リリースブランチを開発者以外が直接触ることから、ローカルブランチを分けて変更内容をmasterに反映とする
リリースブランチの作成と切替
- ローカル
// リリースブランチ作成して、新しいブランチに切替 % git checkout -b iss1 % git commit -am 'release iss1' % git push origin iss1
- 本番環境
// リモートリポジトリ取得 % git fetch // リモートリポジトリ確認 % git branch -r origin/HEAD -> origin/master origin/iss1 origin/master % git checkout --track origin/iss1 % git branch * iss1 master
- 不要になったリモートブランチを削除(※利用には注意)
% git push origin :iss1
PhoneGapについてまとめてないまとめ
下記はプレゼンネタ用にまとまっていないことをとりとめなく書いた内容ですのであしからず。
PhoneGapとはなにか?
クロスプラットフォーム・モバイルアプリケーションの開発フレームワーク
HTML5+CSS+JavaScriptで開発できる
PhoneGapとTitanium Mobileと比較してみた
PhoneGap | Titanium Mobile | |
メモリ管理 | 出来ない | 出来ない |
デプロイ | 速い | 遅い |
パッケージ容量 | 10M | 120〜150M |
ライセンス | MIT or BSD | Apache v2 |
v1.0 | 2011.7.28 | 2010.05 |
開発言語 | HTML5+CSS+JavaScript | Javascript |
アプリ容量 | - | 大きい |
デプロイの速度に差があるのはPhoneGapはWebViewベースなのと、Titanium Mobileはネイティブなコードに変換しているからとのこと。PhoneGapはネイティブなコードとコンパイル速度変わらない感じ。
もちろんデプロイには正確な数字や環境が異なったのもあるけど、XcodeでのiPhoneアプリコンパイルにPhoneGap1秒(Core i5 1.6GHz)、Titanium Mobile 30秒(Core2 Duo 2GHz)
Titanium Mobileのアプリの容量が大きくなるのは元から含まれるライブラリ群が多い為。
最小サイズ(Hello World)で3Mくらいになったかと。
ちなみに少し前に作ったアプリ CheerDogsは600KB程度でした。
これもうろ覚えだけど、Titanium MobileはiPhone由来のボタンとか使用できたはず。
PhoneGapは自分で用意する必要がある。
PhoneGapで出来ること
http://www.phonegap.com/about/features
対応OSの種類が多い。WIndows Phone7は対応してないみたい。
JavaScriptから位置情報、カメラ、ストレージにアクセス出来るのがよいかなと。
まとめになっているか解らないまとめ
web系の開発者、デザイナーでもアプリを作れそう。リリースできそう。
環境構築も簡単。ただし、Androidのデプロイが普通に遅い環境の人は開発手法は考えた方がよさそう。
WEBサービスもアプリストアにないと利用してもらえない状況も出てるので実績作るにはよいかなと。
アプリなのにアプリに縛られてない感じ。アプリをよく知らない人がアプリ作ると、利用者は操作に戸惑いそう。
アプリのOSが増えてきてるのでクロスプラットフォーム対応で、今までの言語使えるのはとても重要かなと。
Titanium Mobileの画面遷移はOS毎に操作を変える必要がある。PhoneGapはWebViewベースなので何処まで制限が緩いのか作らないと不明。