平成22年2月9日(火) 05時16分29秒
区分
javascript
報告者:
komagata
火曜日担当のkomagataです。
Metasploitは一回お休みさせていただいてJavascriptのお話しです。
仕事は主にwebプログラミングなので身も蓋も無い言い方をすると「DBに入れたり出したり」しかしてません。
「もう文字列処理はうんざりなんだよ!」
というのは嘘ですが、たまには動きのある見栄えのするグラフィックとかアニメーションとかプログラムしてみたいと思い、HTML5で使えるようになるらしい、グラフィック機能のcanvasと双方向同期通信のWebSocketsを使ってキャラクターがウロウロするだけのプログラムを作ってみました。
WebSocketsを実装しているのは現状Google Chrome 4以降だけなので、動作してる雰囲気を伝えるために動画にしてみました。
【ニコニコ動画】CanvasとWebSocketsのデモ
最近のChromeには実装されているので下記のように簡単にサーバーに接続することができます。
ws = new WebSocket("ws://localhost:8080/")
ws.onopen = function() { console.log('open') }
ws.onclose = function() { console.log('close') }
ws.onmessage = function(evt) { ws.send('Hello!') }
CometなどよりとてもシンプルでたちまちWebSocketsが好きになりました!
Ajaxのように非同期に小さなメッセージをちょこちょこ飛ばすのではなく、1ユーザーに対して1本ガッシリしたラインを繋ぎ、双方向にドカドカ通信するイメージでしょうか。
真っ先にネットゲーム的なものでの利用方法が思い付きますが、これが標準的なブラウザで使えるようになれば、他の新しい使い方で出てきて斬新なUIが生まれれば良いなと思います。
とりあえず現状を下記のURLで動かしています。chromeやsafariのnightlyでは動くみたいです。(windows, mac, linuxどれでも動くことは確認しました。)
http://verdana.komagata.org/prowler/
ソースは下記です。
komagata's prowler at master - GitHub
>View Comments
このページの上へ戻る
平成22年2月5日(金) 10時49分53秒
区分
Ruby on Rails
報告者:
tahara
こんにちは!! tahara です。
今回は Lisp on Rails はお休みで、Ruby on Rails の Paperclip の話題です。
IE で RGB の画像は表示できますが、CMYK の画像は表示できません。
CMYK から RGB に変換する手もありますが、変換時に結構色が変ってしまいます。
ということでアップロードする画像が CMYK の場合は、
バリデーションではじくようにします。
まず CMYK の判定ですが、ImageMagic の identify コマンドで可能です。
~% identify -format '%[colorspace]' ~/archive/normal.jpg
CMYK
~% identify -format '%[colorspace]' ~/archive/normal-rgb.jpg
RGB
ただし古い ImageMagic では -format '%[colorspace]'
オプションが認識されないので -verbose オプションを使います。
~% identify -verbose ~/archive/normal.jpg
Image: /home/ancient/archive/normal.jpg
Format: JPEG (Joint Photographic Experts Group JFIF format)
Class: DirectClass
Geometry: 290x200+0+0
Resolution: 72x72
Print size: 4.02778x2.77778
Units: PixelsPerInch
Type: ColorSeparation
Endianess: Undefined
Colorspace: CMYK <=== これ!!
Depth: 8-bit
...
この identify を呼び出して CMYK をチェックするバリデーションを
config/initializers/paperclip.rb に組み込みます。
module Paperclip
module ClassMethods
...
# CMYK は IE で表示できないため、検証でエラーとする。
def validates_attachment_not_cmyk name, options = {}
message = options[:message ] || "CMYK フォーマットの画像はブラウザによって表示できないため使用できません。お手数ですが RGB フォーマットに変換してください。"
attachment_definitions[name][:validations ][:not_cmyk ] = lambda do |attachment, instance|
original_file = attachment.instance_variable_get(:@queued_for_write )[:original ]
colorspace =
begin
attachment.file? && original_file &&
Paperclip .run("identify" , "-verbose #{original_file.path} " )
rescue
nil
end
if colorspace && colorspace =~ /^\s*Colorspace: CMYK$/
message
end
end
end
....
これでモデルから validates_attachment_not_cmyk
というひどい名前のバリデーションが使えるようになります。
validates_attachment_not_cmyk :picture_1
まとめるとこうなります。
(incf ImageMagic)
(decf IE most-positive-fixnum)
>View Comments
このページの上へ戻る
平成22年2月5日(金) 00時43分42秒
区分
エコロジー
報告者:
chiba
こんにちは、千葉です!
完全なるネタ切れです。
以前のエントリーにも書きましたが、私は返り値をできるだけ使いたくなってしまう派です。
値を返すところは積極的に拾ってゆきたい。
そういう質なので、
if pred
method(100)
else
method(200)
end
のようなものを見ると
method(if pred
100
else
200
end)
と書きたくなってしまいます。ifは分岐が2つですが、Rubyのcase等の複数への分岐も同じくそうです。
LISPだと
(method (if pred 100 200))
という感じですが、このifの纏め方は、LISPではすんなり流れるものの、Rubyだとif〜endが重たくみえるので、なんとなく書いてはいけないようにさえ感じます。
条件演算子なら
method(pred ? 100 : 200)
という風にすっきりなのですが、なんとなく読みづらいですね。
>View Comments
このページの上へ戻る
平成22年2月4日(木) 00時13分51秒
区分
Objective-C
報告者:
masuda
こんにちは。
masudaです。
今日は節分でしたね。
あの豆を食べるのが好きです。
早くもネタが尽きてきました。
自分がObjective-Cのポテンシャルがわかっていないので(別にObjective-Cである必要は全然ないのですが)、続き物を書くことができません。
今回はToll-free bridgeについて書いてみようと思います。
またもやどこにもあるようなネタです。
Toll-free bridgeについてはHMDTさんなどで詳しく紹介がされています。
ダイナミックObjective-C (38) Toll-free bridge(1) – 変換コスト0のブリッジ | エンタープライズ | マイコミジャーナル
CocoaのオブジェクトとCoreFoundationのオブジェクトを相互にキャストするだけで変換することができます。
たとえばCocoaのNSStringというクラスは、CoreFoundationではCFStringというものに対応します。
具体例を示しましょう。
変換の話の前に、CoreFoundationでは初期化はどうするか?
NSStringであれば
NSString *hoge = [[NSString alloc] initWithCString:"piyo"];
のように書くところですが、CoreFoundationでは
CFStringRef hoge = CFStringCreateWithCString(kCFAllocatorDefault, "piyo", kCFStringEncodingUTF8);
となります。
さて、本題のToll-free bridgeによる変換です。
どのようなときに使うのか?
具体例を挙げると、NSStringの遅いメソッドであるcharacterAtIndexを呼び出す代わりに、CoreFoundationにあるCFStringGetCharacterFromInlineBuffer関数を使用して高速に処理するなんて使い方をするとか。
別にすべてCoreFoundationで書いてもかまいませんが、Cocoaを使うよりも幾分面倒なのでこういう適用が多いのではないかと思います。
NSString *hoge;
CFIndex length, current;
CFStringInlineBuffer buffer;
UniChar ch;
*hoge = [[NSString alloc] initWithCString:"piyo"];
length = CFStringGetLength((CFStringRef)hoge);
CFStringInitInlineBuffer((CFStringRef)hoge, &buffer, CFRangeMake(0, length));
current = 0;
while (current < length)
{
ch = CFStringGetCharacterFromInlineBuffer(&buffer, current);
NSLog(@"%c", ch);
++current;
}
こんな風にキャストするだけで渡すことができます。
昔、NSDictionaryの生成をCFDictionaryの生成に変えたところ劇的に速度が向上したことがあったような気がします。
>View Comments
このページの上へ戻る
平成22年2月2日(火) 02時49分59秒
区分
セキュリティ
報告者:
komagata
火曜日担当のkomagataです。
Gumblerウィルスが猛威を振るっているので流行に乗ってセキュリティネタです。
脆弱性検証(というか実際に脆弱性を突くので悪用厳禁)ツールのMetasploit3 をMacで使ってみました。
Macportsのはrb-railsやrb-rackが普通のgemとぶつかって入りません。(port editで依存性を外せば入りましたが気持ち悪いです。)
なので、svnのtrunkを持ってきました。
% svn co https://www.metasploit.com/svn/framework3/trunk metasploit
今回checkoutしたのはrevision8340でした。
% cd metasploit
% ./msfconsole
/Users/komagata/code/metasploit/lib/msf/core/exploit/mixins.rb:46:in `require': /Users/komagata/code/metasploit/lib/msf/core/exploit/capture.rb:358: syntax error, unexpected ')', expecting kEND (SyntaxError)
/Users/komagata/code/metasploit/lib/msf/core/exploit/capture.rb:375: syntax error, unexpected $end, expecting kEND
from /Users/komagata/code/metasploit/lib/msf/core/exploit/mixins.rb:46
from /Users/komagata/code/metasploit/lib/msf/core/exploit.rb:216:in `require'
from /Users/komagata/code/metasploit/lib/msf/core/exploit.rb:216
from /Users/komagata/code/metasploit/lib/msf/core.rb:52:in `require'
from /Users/komagata/code/metasploit/lib/msf/core.rb:52
from /Users/komagata/code/metasploit/lib/msf/ui/console/driver.rb:1:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui/console/driver.rb:1
from /Users/komagata/code/metasploit/lib/msf/ui/console.rb:10:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui/console.rb:10
from /Users/komagata/code/metasploit/lib/msf/ui.rb:10:in `require'
from /Users/komagata/code/metasploit/lib/msf/ui.rb:10
from ./msfconsole:16:in `require'
from ./msfconsole:16
ところがcoreで読み込んでるファイルがsyntax error。ほぼ全てのコマンドが動きません。
「これは良いコミットエンドラン ・・・(ゴクリ)」
% svn diff
Index: lib/msf/core/exploit/capture.rb
===================================================================
--- lib/msf/core/exploit/capture.rb (revision 8340)
+++ lib/msf/core/exploit/capture.rb (working copy)
@@ -355,7 +355,7 @@
rescue RuntimeError => e
@pcaprub_error = e
print_status("Cannot stat device: #{@pcaprub_error}")
- raise RuntimeError, "Pcaprub error: #{@pcaprub_error}")
+ raise RuntimeError, "Pcaprub error: #{@pcaprub_error}"
end
return my_net
end
取り敢えずこれで動きますのでお急ぎの方は是非。
% ./msfconsole
| | _) |
__ `__ \ _ \ __| _` | __| __ \ | _ \ | __|
| | | __/ | ( |\__ \ | | | ( | | |
_| _| _|\___|\__|\__,_|____/ .__/ _|\___/ _|\__|
_|
=[ metasploit v3.3.4-dev [core:3.3 api:1.0]
+ -- --=[ 176 exploits - 30 auxiliary
+ -- --=[ 104 payloads - 17 encoders - 5 nops
=[ svn r8340 updated today (2010.02.01)
msf >
metasploitはversion3からperlからrubyになったらしく、僕にとっては読みやすくて嬉しいです。でもWebインターフェースがRailsなのは少しアグレッシヴですね。
次回は実際に脆弱性を突いてみようと思います。
>View Comments
このページの上へ戻る
平成22年1月29日(金) 10時16分25秒
区分
Lisp on Rails
報告者:
tahara
こんにちは!! tahara です。
Lisp on Rails 第2回です!
ActiveRecord::Base ではクラスメソッドとして find や all の検索メソッドが定義されています。
Common Lisp でそれらを実装するにあたり、メタクラスのメソッドとして実装してみます。
Common Lisp では自分でメタクラスを定義することができます。
次のようにメタクラスを定義します。
なんとなく、テーブル名とカラム情報を持たせています。
(defclass active-record-class (standard-class)
((%table-name :initarg :%table-name :accessor %table-name-of)
(%columns :initarg :%columns :accessor %columns-of)))
各テーブル毎のクラスはこの active-record-class のインスタンスになり、
インスタンス変数としてテーブル名とカラム情報を持つイメージです。
メタクラスに全レコードを取得する all メソッドを実装します。
(defmethod all ((class active-record-class))
(multiple-value-bind (rows columns)
(clsql-sys:query (format nil "select * from ~a" (%table-name-of class)))
(loop for i in rows
collect (make-instance-from-row class i columns))))
(def-record post) は次のように展開されて
:METACLASS ACTIVE-RECORD::ACTIVE-RECORD-CLASS を指定します。
(PROGN
(DEFPARAMETER POST
(DEFCLASS POST (BASE)
((ID :INITARG :ID :INITFORM NIL :ACCESSOR ID-OF)
(NAME :INITARG :NAME :INITFORM NIL :ACCESSOR NAME-OF)
(TITLE :INITARG :TITLE :INITFORM NIL :ACCESSOR TITLE-OF)
(CONTENT :INITARG :CONTENT :INITFORM NIL :ACCESSOR CONTENT-OF)
(CREATED-AT :INITARG :CREATED-AT :INITFORM NIL :ACCESSOR
CREATED-AT-OF)
(UPDATED-AT :INITARG :UPDATED-AT :INITFORM NIL :ACCESSOR
UPDATED-AT-OF))
(:METACLASS ACTIVE-RECORD::ACTIVE-RECORD-CLASS)))
...
Ruby のクラス定義と違って Common Lisp のクラス定義ではクラス名に何も束縛しないため、
わざわざ
defparameter しています。
そんな感じでメタクラスによる
(all post)
ができました。
ソースはこちらから http://github.com/quek/lisp-on-rails
第3回につづきます
>View Comments
このページの上へ戻る
平成22年1月28日(木) 22時44分00秒
区分
Common LISP愛
報告者:
chiba
こんにちは!、chibaです。
早くも書くネタが無いのですが、どうしたら良いんでしょうか。
今年の私のテーマは「挑戦」。
先日、そんな私にぴったりな、盗んだバイクで走り出したくなる挑戦をみつけました。
PerlとC++にしかできないような気がするアノ機能(挑戦者募集中)
#!/usr/bin/perl
# PerlとC++は世界一。
srand(time);
my $a = 0;
my $b = 0;
for(my $i = 0; $i < 1000; $i++) {
(rand(2)<1 ? $a : $b) += 1;
}
print "$a, $b\n"
これをPerlや、C++以外の言語で書けるのか、と。
私は、LISP野郎なのでLISPで回答するとして考えましたが「実行時に変数の名前によって任意の変数にアクセスし、その変数に値を代入できるか」という風にお題を解釈しました。
PerlやC++の場合は、?:にそういう機能があるのでしょう。
Common Lispだとどうなるかというと、「実行時に変数の名前によって任意の変数にアクセス」というのは、シンボル名による変数へのアクセスで可能なので、上をCommon Lispに訳すと
(let ((a 0) (b 0))
(declare (special a b))
(dotimes (i 1000)
(incf (symbol-value
(if (< (random 2) 1) 'a 'b))))
(format t "~A, ~A~%" a b))
;⇒ NIL
----------
499, 501
こんな感じに書くことになるのかなあと思いました。
…というようなことをtaharaさんと昼食時に話していたのですが、taharaさん曰くifにsetfが付いてれば可能なんじゃないかとのこと。
なるほど、確かにそうです。
setfというのは代入する構文のマクロなのですが、ユーザーが色々カスタマイズできます。
実行時に変数名でアクセス→代入というのではなく、そういう構文をマクロで定義するわけですね。
ユーザーがifにsetfを書けば良いのですが、これが標準で付いている処理系をどっかでみたなーと思ったので調べてみるとCLISPがそうでした。
CLISPだと標準で
(let ((a 0) (b 0))
(dotimes (i 1000)
(incf (if (< (random 2) 1) a b)))
(format t "~A, ~A~%" a b))
;⇒ NIL
----------
513, 487
と書けます。自分はPerlは書けないのですが、+=をカスタマイズすることによって
for(my $i = 0; $i < 1000; $i++) {
if (rand(2) < 1) {
$a
} else {
$b
} += 1;
}
のようにも書けるようにユーザーが勝手に定義できる、という感じでしょうか。
こんなことをしているとすぐカオスになりそうですが、LISPに構文は無いようなものなので特に混乱もなかったりします。LISPは単純で良いですね■
>View Comments
このページの上へ戻る
平成22年1月27日(水) 21時12分55秒
区分
objective-c
報告者:
masuda
こんにちは。
先日komagataさんにgit svnの使い方を教えていただいたおかげで、少しは使えるようになってきたmasudaです。
今回も前回のGeohashに引き続き、位置情報に関する内容です。
ググれば出てくる内容なので、新しいことはなんにもないのが申し訳ないところです。
位置情報に関するライブラリは
などがあります。
GPSで現在位置を取得するにはCoreLocationを使用し、地図を表示したり現在地の大まかな住所を取得するためにはMapKitを使用します。
CoreLocationではCLLocationManagerDelegateを実装し
CLLocationManager *locationManager = [[CLLocationManager alloc] init];
if ([locationManager locationServicesEnabled])
{
[locationManager setDelegate:self];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locationManager setDistanceFilter:kCLDistanceFilterNone];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(@"%@", newLocation);
}
このようにすればLogに現在地の情報が取得できます。
地図を表示するには
CGRect screen = [[UIScreen mainScreen] bounds];
MKMapView *mapView = [[MKMapView alloc] initWithFrame:screen];
[[self view] addSubview:mapView];
[mapView release];
MKCoordinateRegion region;
region.center = [location coordinate];
region.span.latitudeDelta = 0.005;
region.span.longitudeDelta = 0.005;
[mapView setRegion:region animated:YES];
とすれば、locationで指定した座標に移動します。
現在地を取得するにはMKReverseGeocoderDelegateを実装し
MKReverseGeocoder *reverseGeocoder = [[MKReverseGeocoder alloc] initWithCoordinate:[location coordinate]];
[reverseGeocoder setDelegate:self];
[reverseGeocoder start];
- (void)reverseGeocoder:(MKReverseGeocoder *)geocoder didFindPlacemark:(MKPlacemark *)placemark
{
NSLog(@"%@", [placemark title]);
}
とすることで取得することができます。
すべてのAPIが非常にシンプルに作られているので、使用するのは非常に簡単です。
>View Comments
このページの上へ戻る
平成22年1月27日(水) 11時11分38秒
区分
lisp
報告者:
komagata
興味のある言語にLispと書いておいたら面接で爆笑された
面接官「Lisp・・・ふははっ!Lisp!」
面接官「Lispやってるんですか?wwwww」
俺「(唖然)は、はい・・まだS式を理解したぐらいですが。。」
面接官「Lisp・・・ニヤニヤ」
Hunchentootで動いてるこのブログを見て弊社に面接に来た方がCommon Lispに興味なかったらメンバー全員がっかりしますね・・・。
>View Comments
このページの上へ戻る
平成22年1月26日(火) 16時51分29秒
区分
git
報告者:
komagata
火曜日担当のkomagataです。
gitよく分からないのでどういう風に使ってるのかデモってくれと言われたので実際に仕事のコードにコミットしてみました。
実録!git!
アクトインディでは「子供とのお出かけ先を探すサイト」いこーよ (http://iko-yo.net )というサイトを運営しています。
リポジトリはデザイナーさんがDreamweaver やCoda のsvnクライアントを使うのでSubversionです。
svnの最新リビジョンだけを持ってくる。(全部持ってくると死ぬほど時間がかかる。)
% git svn clone -r HEAD https://svn.actindi.net/svn/oyaiku/trunk/outing outing --username=komagata
Redmineのチケットを見る。
予め仕込んでおいた簡単そうなチケットを発見。(redmineではイシューというみたいです)
チケットに対応したブランチを作る。
% git branch issue3487
作業ブランチを切り替える。
% git checkout issue3487
(git branch foo; git checkout fooはgit checkout -b fooと同じ)
ブランチ確認。
% git branch
master
* issue3487
shouldaスタイルのマクロが使いたいのでremarkableを入れる。
# config/environment.rb
Rails::Initializer.run do |config|
config.gem 'remarkable_rails', :lib => false
end
# spec/spec_helper.rb
require 'spec/rails' # ここの下に書く
require 'remarkable_rails'
% sudo rake gems:install
% rake gems:unpack
% rake gems:refresh_spec
一旦、コミット。
% git add vendor vendor/gems/remarkable_rails-3.1.12
% git commit -a -m'added remarkable'
app/model/city.rbのテストを作る。
# app/model/city.rb
class City < ActiveRecord::Base
belongs_to :prefecture
validates_presence_of :name, :reading, :roman
validates_length_of :name, :within => 1..40
validates_length_of :reading, :within => 1..40
validates_length_of :roman, :within => 1..40
validates_uniqueness_of :roman
end
# spec/models/city_spec.rb
require 'spec_helper'
describe City do
fixtures :cities
should_belong_to :prefecture
should_validate_presence_of :name
should_validate_presence_of :reading
should_validate_presence_of :roman
should_validate_length_of :name, :within => 1..40
should_validate_length_of :reading, :within => 1..40
should_validate_length_of :roman, :within => 1..40
should_validate_uniqueness_of :roman
end
テスト実行(ホントは全部のテストを実行する)
% ./script/spec spec/models/city_spec.rb
City
- should belong to prefecture
- should require name to be set
- should require reading to be set
- should require roman to be set
- should ensure length of name is within 1..40 characters
- should ensure length of reading is within 1..40 characters
- should ensure length of roman is within 1..40 characters
- should require unique values for roman
Finished in 0.770165 seconds
8 examples, 0 failures
コミット
% git add spec/models/city_spec.rb
% git ci -a -m'added city_spec. fixed #3487'
masterに移る。
% git checkout master
最新版を持ってくる
% git svn rebase
issue3487をマージする
% git merge issue3487
svnにコミット。
% git svn dcommit
完了。
その他の便利機能 3>
いっこ前のコミットなかったことにする
% git reset HEAD^
昔のコミットを修正したい
% git log --oneline
c5524b2 * removed foo * removed remarkable
460bfa1 [デザイン] TOPページ「外へおでかけ」の変更 (refs #3490) * 谷さん修正分
9b819fd * add city_spec * add remarkable * add foo
695b1eb [システム] [mobile] /facilities/:id のレイアウト変更。 (refs #2899) * いらないhrを削除。
% git rebase -i 695b1eb
エディタが立ち上がるので修正したいリビジョンのpickをeditに変更して終了する。
pick 9b819fd * add city_spec * add remarkable * add foo
pick 460bfa1 [デザイン] TOPページ「外へおでかけ」の変更 (refs #3490) * 谷さん修正分
edit c5524b2 * removed foo * removed remarkable
指定したリビジョンの状態に戻るので好きにaddしたり編集したりする。
% git commit --amend
% git rebase --continue
修正完了
複数の適当なコミットを一つにまとめたい
% git log --oneline
68fb234 add text2 in foo
5cd81d6 add text in foo
43fdcb7 add foo
fb91711 removed old paperclip
aa21e65 fixed
% git rebase -i fb91711
pick 43fdcb7 add foo
pick 5cd81d6 add text in foo
pick 68fb234 add text2 in foo
次のリビジョンとまとめたいリビジョンの先頭をpickからsquashに変える。
pick 43fdcb7 add foo
squash 5cd81d6 add text in foo
squash 68fb234 add text2 in foo
コミットメッセージをいれて終了。
みなさんおっしゃってますが、やはり、svnからgitにして嬉しいのはbranchの作成やcommitが気軽できるところですね。一つの作業をやってる途中に別の優先タスクが入った場合も、現在のbranchをほっぽってすぐにそちらのタスクに移れるのは精神的にもとても楽です。
適当にfixed, fixedなどとコミットしていっても後で綺麗にまとめられるところもいいですね。
gitは他にもいろいろ出来るみたいですが、今のところリアルにこんな感じで使っています。便利な使い方があれば教えて頂けると嬉しいです。
>View Comments
このページの上へ戻る