以前作ったJSONを整形するHTMLのツールをChrome Appとして公開しました。Chrome Web Storeに公開されています。
ただ受け取ったJSONを整形するだけのもの凄くシンプルなツールですが、よければ使ってください。
以前作ったJSONを整形するHTMLのツールをChrome Appとして公開しました。Chrome Web Storeに公開されています。
ただ受け取ったJSONを整形するだけのもの凄くシンプルなツールですが、よければ使ってください。
$ gem install prettyprint
prettyprint [json|xml] [filepath]
gemでインストールするとprettyprintコマンドが使えるようになります。prettyprintコマンドはxmlまたはjsonというサブコマンドを持ちます。ファイル名を指定するとそのファイルを入力とします。
$ prettyprint json input.json
ファイル名を省略すると、標準入力を受け付けます。
$ echo '<html><title>prettyprint</title><body>happy pretty printing</body></html>' | prettyprint xml <html> <title> prettyprint </title> <body> happy pretty printing </body> </html>
ちょくちょく必要になるのでHTML/JavaScriptでJSONをPritty Printするツールというかページを作りました。
内容は単純に入力に対してJSON.stringifyしているだけ。おまけとして、zClipというクリップボード用jQueryプラグインを使って、出力結果をクリップボードにコピーできるようにしてある。prettyprintの部分はこんな感じ。
var src = $('#src').val();
var obj = JSON.parse(src);
var formatted = JSON.stringify(obj, undefined, 2);
ちなみに前にも書いているけど、これを使わない場合はPythonのワンライナーでやっていいる。
$ echo '{"foo":"FOO", "bar": [1, 2, 3]}' | python -mjson.tool
{
"bar": [
1,
2,
3
],
"foo": "FOO"
}
表題の通り、以下の処理をするワンライナー。
$ cat target.txt | uniq | ruby -ne 'puts sprintf("%03d %s",$_.chomp.size,$_)' | sort -r | head -5
今まで知らなかったが、MySQLではSQLで直接MD5のハッシュ値を計算できる。
mysql> select md5('test');
+----------------------------------+
| md5('test') |
+----------------------------------+
| 098f6bcd4621d373cade4e832627b4f6 |
+----------------------------------+
ちなみにコマンドラインで計算する方法もいつも忘れるのでメモ。
# -sオプションの直後に変換する元の文字列を続ける
$ md5 -stest
MD5 ("test") = 098f6bcd4621d373cade4e832627b4f6
仕事でメール送信の機能を作るとき、ダミーのSMTPサーバーが必要になり、kosekiさんによるmocksmtpdというRuby製のものを見つけた。ただしBase64エンコードされたメールで日本語が表示できていなかったので、GithubでフォークしてBase64に対応した。あと、出力されるHTMLも若干変更しています。
詳細な使い方は作者のkosekiさんのブログも参考に。
開発用のメールサーバ mocksmtpd を gem にしてみた。
今はGithubがgemのホスティングをやめているので、specific_installというgemを利用する。これを使うとGithubのソースから直接gemをインストールできる。
$ gem install specific_install $ gem specific_install -l https://github.com/daixque/mocksmtpd.git
$ mocksmtpd init $ cd ./mocksmtpd $ sudo mocksmtpd
Spring MVCでアスペクト(インターセプター)を実装するのは結構簡単。アスペクトっていうのは、要するにメソッドに対して前後処理をするモジュールのこと。フィルターみたいなやつですね。Springの場合はSpring配下にある任意のクラスのメソッドに適応可能。アスペクトで実装する一番ありがちな処理はログでしょうね。私もそのために使いました。あとはエラー処理とか。
SpringではどうもAspect Jを使ってAOPをしていて、用語もそれに従っている。ここでは面倒なので細かい用語の説明はなし。気になる人はアドバイス、ポイントカット、ジョインポイントあたりについて調べるといいんじゃないでしょうか。もっと色々ありそうですけど。
アスペクトには以下の種類がある。
すごい簡単。アスペクトのクラスに@Aspect、インターセプターの処理のメソッドに、種類に応じて上記の名前のアノテーション(@Beforeとか)をつけるだけ。
例えば、Service層のクラスの中で、自作の@UpdateDatasourceというアノテーションのついているメソッドのみ特定のログを出力したいときの例。ここで、サービス層はorg.opentechnica.sample.serviceパッケージにあるとする。
アノテーションは普通に実装。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UpdateDatasource {
public String value();
}
アスペクトも、アノテーション以外は普通に実装。
@Aspect
@Component
public class LoggingAspect {
@Before("execution(public * org.opentechnica.sample.service..*(..))")
public void before(JoinPoint jp) {
try {
Class targetClass = jp.getTarget().getClass();
String methodName = jp.getSignature().getName();
MethodSignature signature = (MethodSignature) jp.getSignature();
Method method = signature.getMethod();
UpdateDatasource updateDatasourceAnnotation = method
.getAnnotation(UpdateDatasource.class);
if (updateDatasourceAnnotation != null) {
Logger logger = Logger.getLogger(targetClass);
logger.info("before");
}
} catch (SecurityException e) {
// do nothing
}
}
}
@Beforeアノテーションでメソッドの実行前にインジェクションする処理であることを表している。アノテーションの引数("execution(public * org.opentechnica.sample.service..*(..))")は、この処理を実行する対象をフィルタリングする条件。ポイントカットっていやつですね。ここでの指定は以下のような意味。
Javaは同一のメソッド名でも引数が違うと違うシグニチャになるので普通のリフレクションだと面倒だけど、beforeメソッドに渡されるJoinPointから、以下のようMethodSignatureにキャストすると直接取得できる。
MethodSignature signature = (MethodSignature) jp.getSignature(); Method method = signature.getMethod();で、methodがとれたらもうmethod.getAnnotation(UpdateDatasource.class)とすれば、自作の@UpdateDatasourceが付加されているかどうかわかる。
アスペクトを実装したら、applicationContext.xmlに以下の一行を追加するだけで動く。便利!
<aop:aspectj-autoproxy/>
タイトルで全て。
jQueryを使ってフォームをsubmitするとき、submit要素にname属性ががあるとうまく動作しないようなので、使わないようにする。
jQueryでラジオボタン/チェックボックスを操作するとき、attr("checked", "checked")だと2回目以降うまく動かないので、prop("checked", true)を使うのが正解。
// これはOK
$("input[type=radio]").prop("checked", true);
// こっちは2回目以降うごかない
$("input[type=raido]").attr("checked", "checked");
HTTPのスタブを作るためのフレームワークCameleonのv0.1.1をリリースしました。
Github : Cameleonv0.1.1ではポストされたJSONをバリデーションする機能を追加しました。Cameleonはgemでインストールできます。
$ gem install cameleon
使い方の詳細は前の記事を参照してください。
v0.1.1のJSONバリデーション機能では、POSTまたはGETのHTTPリクエストボディのJSONについて、データ構造の検証を行うことができます。バリデーションのエンジンにはjson-schema gemを利用し、JSON Schema Draft 3のスキーマ定義を利用します。このバリデーション処理をするには、まず設定ファイル(cameleon.yml)に以下の内容を記載します。
validation: type: json
その上で、レスポンスフォルダにrequest.schema.jsonというスキーマファイルをおいておくと、リクエストボディにそのスキーマに適合するJSONデータが含まれない場合にはステータス500のエラーが帰るようになります。
例えば次のようなJSONを期待するインターフェイスの場合
{"a": 1}
次のようなスキーマを定義します。
{
"type" : "object",
"properties" : {
"a" : {
"type" : "integer",
"required" : true
}
}
}
When you have Git repositories as below.
You can't merge on bare repository such as MAIN.git because bare repository has no working copy. There are no ways to resolve the conflict when it occurs. Therefore, you must checkout the target branch into your local repository, merge your commits, then push to bare repository(MAIN.git).
Use 'git fetch' when there are some changes on CENTER.git. But this command doesn't update HEAD position. So you should use 'git reset --soft'.
# on MAIN.git $ git fetch <CENTER.git> $ git reset --soft HEADcheck commit histories using 'git log'.
You can push local branch 'dev-local' into 'dev-remote' on origin.
$ git push origin dev-local:dev-remote
You can checkout 'dev-remote' branch on MAIN.git into 'dev-local' branch on local machine:
git clone <MAIN.git> git checkout -b dev-local remotes/origin/dev-remote
You can push local tags into remote repository.
$ git push --tags
This article is translated from Japanese.
You know there are development, test and production environments on Ruby on Rails. This article shows you how to create new environment for your system.
We are currently working with:
You can refer environment name through Rails.env.
p Rails.env #=> "development"
For example, you can add your new 'staging' environment by these steps. Follow these steps to add your new 'staging' environment.
Then, create database, do migration, and start your staging server.
$ rake db:create RAILS_ENV=staging $ rake db:migrate RAILS_ENV=staging $ rails server -e stagingYes! You now have new 'staging' environment for your project.
You can use different gems for your each environment. This situation, write your Gemfile as below.
group :development, :test do gem 'sqlite3-ruby' end group :staging, :production do gem 'mysql2', '0.2.7' endYou can reject unnecessary gems for specified environment.
$ bundle install --without test developmentsee: Bundler : Using Groups
This article is translated from Japanese.
なんだか流行っているようなので。
一般的な Web Programmer ならば、HTTP Status code はすべて暗記していると聞きました。しかし、僕は初心者なので、なかなか覚えきれていないので、HTTPのステータスコードをさがすのに便利なツールを用意しました。Rubyで書いてます。Githubに上げてあります。
$ httpstatus 40 400: Bad Request 401: Unauthorized 402: Payment Required 403: Forbidden 404: Not Found 405: Method Not Allowed 406: Not Acceptable 407: Proxy Authentication Required 408: Request Timeout 409: Conflict $ httpstatus bad 400: Bad Request 502: Bad Gatewayインストールはgemで。
$ gem install httpstatus元ネタなど。
CentOSにRedmineをインストールするために、ImageMagickとRubyバインディングのRMagickをインストールしたけど、やたら嵌ったのでメモ。なんか前からImageMagickのインストールはすんなり行ったことがないような。
まずはyumでインストールしようとしたけど、バージョンが古いのでNG。本家からRPMでインストールしてもエラーが出てNG。多分ヘッダーとかのパスの問題っぽいが、ImageMagick-develみたいなものをRPMでどう認識させて良いかわからず断念。(後から考えると、このタイミングでPKG_CONFIG_PATHを設定すればうまく行ったのかも)
最終的には本家からソースを持ってきてインストールして、PKG_CONFIG_PATHを設定した後にRMagickをインストールするとうまく行った。
$ tar xzvf ImageMagick.tar.gz $ cd ImageMagick-6.8.2-6/./configure $ make $ sudo make install $ sudo /sbin/ldconfig /usr/local/lib $ gem install rmagick -v '2.13.2'
Bundlerでライブラリが取得さえできれば、Redmineのインストールは特に問題なし。
Rubygemsにあるtwitterバージョン4以降は、rate_limit_statusを取得するAPIがなくなった。これは、このAPIの利用方法がTwitterのREST APIのエンドポイントURIに依存していて、Twitter側の仕様変更があったとき、このAPIをサポートしているとライブラリの更新だけで(アプリの修正なしに)この変更に追随することができなくなるためらしい。
まあ設計思想としては理解できるが、とはいえこのライブラリを使ってやりたいことはTwitterのREST APIを叩くことだから、Twitter側の仕様変更に影響を受けることはある程度は仕方ないと思うんだが、どうだろうか。もちろんそこが隠蔽されていて、Twitter側のバージョンが変わってもアプリのコードに変更がない、ということが可能であれば美しいけど。
で、無理やりrate_limit_statusを取得するには以下のコード。
Twitter.get('/1.1/application/rate_limit_status.json')[:body]
要するにgetというメソッドを使えば、直接使いたいAPIを叩ける。このコードで結果がHashで返ってくる。
参考)https://github.com/sferik/twitter/issues/318MongoDBのMapReduceをNode.jsから実行/テストするためのモジュール、mmrdをリリースしました。
$ npm install mmrd
例えばMongoDBのワードカウントなどで、以下のようなMapReduceを書いていたとします。
// map.js
function map() {
var words = this.text.split(' ');
words.forEach(function(word) {
emit(word, 1);
});
}
//reduce.js
function reduce(key, values) {
var result = 0;
values.forEach(function(v) {
result += v;
});
return result;
}
このとき、mmrdを使うと以下のような形でこのMapReduceをNode.jsから実行できます。
// runner.js
var mmrd = require('mmrd');
// map test
(function() {
console.log("Word count / Map test");
var doc = { text: "foo bar baz" };
mmrd.loadMap('map.js');
mmrd.map(doc, function(key, value) {
console.log(key, ":", value);
});
})();
// reduce test
(function() {
console.log("Word count / Reduce test");
mmrd.loadReduce('reduce.js');
var key = "foo";
var values = [1, 1];
var reduced = mmrd.reduce(key, values);
console.log(key, ":", reduced);
})();
// integration test
(function() {
console.log("Word count / Integration test");
var docs = [
{ text: "foo bar baz" },
{ text: "foo baz baz"}
];
mmrd.loadMap('map.js');
mmrd.loadReduce('reduce.js');
var result = mmrd.mapReduce(docs);
console.log(result);
})();
起動
$ node runner.js
もちろん、mochaやshouldを使ったテストも書けます。当たり前ですが。
お試しあれ。
短縮URLは普通リダイレクトで目的のコンテンツまで辿り着く。Rubyで短縮URLで指定されたコンテンツを扱いたいが、http_clientはリダイレクトには対応しているけど、デフォルトではhttpsの短縮URLに対してhttpのURLにリダイレクトされたときに例外を吐くのでbit.lyなんかではうまく使えない。
なので、以下のように常にリダイレクトするようにコールバックを設定すると、この制限を回避できる。
require 'httpclient'
def get_content_with_redirection(url)
client = HTTPClient.new
def client.allow_all_redirection_callback(uri, res)
urify(res.header['location'][0])
end
client.redirect_uri_callback = client.method(:allow_all_redirection_callback)
client.get_content url
end
html = get_content_with_redirection("http://bit.ly/RRKD7d")
puts html
fluentdはRubyで書かれたsyslogdのようなロギングミドルウェア。様々なログをネットワーク上で色々ルーティングして、たとえば最終的にMongoDBに登録したりすることができる。
fluentdをインストールして使ってみる。 インストールはgemで一発。
$ gem install fluentd
fluentdを起動するには、作業ディレクトリを作ってコマンドで設定ファイルを作成する。起動はfluentdを-cオプションでキックする。
$ fluentd --setup ./fluent $ cd fluent $ fluentd -c conf/fluent.conf
動作確認は別コンソールで次のように打ち込むと、先ほどのコンソールにログが出力される。
$ echo '{"json":"message"}' | fluent-cat debug.test
ここまでは公式サイトと同内容。 次に、テキストファイルをtailのようにウォッチして、fluentdに転送してみる。 conf/fluent.confを次のように記述する。
<source> type tail path /path/to/test.log tag debug.* format /^(?<log>.*)$/ </source> <match debug.**> type stdout </match>
ここで、sourceディレクティブのtagはどのmatchディレクティブにログをルーティングするかを決めるためのキーとなる。RabbitMQのルーティングキーと同じ感じ。formatディレクティブは、出力形式を正規表現で設定する。このとき、マッチした箇所に?<name>で名前を付ける。上記例だとlogという名前にしてる。
この状態でfluentdを起動して/path/to/test.logに追記すると、コンソールにログが出力される。
$ echo test >> /path/to/test.log
var json = <%= {:foo => "FOO"}.to_json.html_safe %>;
OSX 10.7にRをインストールする。今回はMacPortsを使う。
$ sudo port install RこれでRコマンド(対話型のインタープリター)がインストールされる。終了はq()関数。
$ R > q()
対話型のインタープリターではなく、ソースをファイルから実行するにはRscriptコマンドを使う。とりあえず引数を出力するサンプルを作ってみる。
# hello.r
arg <- commandArgs(TRUE)
cat("hello", arg, "\n")
実行
$ Rscript hello.r world hello world
PerlのCPANやRubyのRubygemsのようなパッケージ管理ツールが組み込まれていて、install.packages関数でパッケージをインストールできる(CRANというらしい)。試しに機械学習ライブラリのrandomForestをインストール。
> install.packages("randomForest")
MacPortsでインストールしていると、/opt/local/以下の書き込み権限がないという警告がでるので、今回はコンソールにいわれる通り、~/R/...にライブラリフォルダを作った。途中でTclのダイアログでダウンロード元を選ばされるので、普通に東京を選んだ。
インストールしたライブラリを使うのにはlibrary関数を使う。
> library("randomForest")
randomForest 4.6-6
Type rfNews() to see new features/changes/bug fixes.
その他、参考サイト。