Amazon 互換 API を超簡単に作れる sinatra エクステンションを作った

一見釣りエントリっぽいタイトルのようでごく一部の人にしか刺さらない感が満載ですが、タイトル通りの sinatra エクステンションを作成して公開しました。

gem install sinatra-ace でインストールできます。(ace というのは Amazon Compatible Environments の略で、Transcend Computing | Amazon Compatible Environment で使われていたのをそのまま使っている感じです。)

下記のようなコードを書いて ruby app.rb するだけで、

require 'sinatra'
require 'sinatra/ace'

action 'DescribeDreams' do
  response_xml do |xml|
    xml.Dreams do
     %w(NiceDream Nightmare DayDream).each {|member| xml.member member }
    end
  end
end

dispatch!

下記のような AWS っぽいたいへんな感じの XML を返却できます。

$ curl "http://localhost:4567/?Action=DescribeDreams"
<?xml version="1.0" encoding="UTF-8"?>
<DescribeDreamsResponse>
  <DescribeDreamsResult>
    <Dreams>
      <member>NiceDream</member>
      <member>Nightmare</member>
      <member>DayDream</member>
    </Dreams>
  </DescribeDreamsResult>
  <ResponseMetadata>
    <RequestId>3f5a54f4-2781-4903-98e4-8977cdc184ef</RequestId>
  </ResponseMetadata>
</DescribeDreamsResponse>

Version パラメーターによる挙動の切り分けも簡単に行えます。

require 'sinatra'
require 'sinatra/ace'

version '2014-06-18' do
  action 'GetMessage' do
    response_xml do |xml|
      xml.Message 'old version'
    end
  end
end

version '2014-07-12' do
  action 'GetMessage' do
    response_xml do |xml|
      xml.Message 'new version'
    end
  end
end

dispatch!
$ curl "http://localhost:4567/?Action=GetMessage&Version=2014-06-18"
<?xml version="1.0" encoding="UTF-8"?>
<GetMessageResponse>
  <GetMessageResult>
    <Message>old version</Message>
  </GetMessageResult>
  <ResponseMetadata>
    <RequestId>d98216a5-19bc-476c-99ab-ea377c284a9b</RequestId>
  </ResponseMetadata>
</GetMessageResponse>
$ curl "http://localhost:4567/?Action=GetMessage&Version=2014-07-12"
<?xml version="1.0" encoding="UTF-8"?>
<GetMessageResponse>
  <GetMessageResult>
    <Message>new version</Message>
  </GetMessageResult>
  <ResponseMetadata>
    <RequestId>0c7085ba-f4d5-4d1f-928b-0971e85e57ee</RequestId>
  </ResponseMetadata>
</GetMessageResponse>

Amazon SQS のようにリクエストパスの概念があるシステムも記述することができるのですが、この機能については q3/lib/q3.rb#L60 あたりを見ると使い方が分かると思います。

自分で作りたいもので必要がでてきたら、認証機能とか最近の AmazonJSON っぽい API にも対応していきたいと思います。
たまには REST ではなく Amazon 互換っぽいインタフェースでオレオレ API を作ってみると、荘厳な感じになっておもしろいんじゃないかと思います。

14 日間の片想い

14 日間の片想い

ソース: tily/kataomoi-14days

1. 手紙をおくれます
2. 手紙をうけとれます
3. 14 日たつと消えます

メッセージキューは基本的にはプログラムがメッセージを送受信するためのものだけど、人が使ったらおもしろいんじゃないかと思ってメッセージキューで動くウェブアプリを作ってみた。裏側では q3-global が動いています。

「14 日間」は Amazon SQS で指定できるメッセージ保持期間の最大値です。「何を見ても何か思い出す」「ゴミ文庫」に続く 3 作目としてふさわしく、 自分が作ったウェブアプリの中でも最大級に意味不明な感じになった。

追記(2014/07/12)

先に送られた手紙ほど頻繁に受け取られてしまう問題があり、メッセージキュー的には正しい挙動のような気もするのですが、自分で手紙を読んでいてなかなか新しい手紙にたどり着けないのが不便だったので、手紙を受け取るときにランダムで受信されるように修正しました。

250 行ぐらいの Amazon SQS 互換 API を作ってエンドポイントを公開した

redis の勉強も兼ねて、redis + sinatra250 行ぐらいの Amazon SQS 互換 API を作ってみた。本当は 100 行ぐらいで作りたかったんだけど、色々機能を足していたら 250 行ぐらいになってしまった。

250 行なのでバリデーションをあまりしていなくて、異常系はあまり動かないけど、正常系はだいたい動くと思う。

Wiki みたいに誰でも手紙を送ったり受け取ったりできるメッセージキューシステムがあるとおもしろいだろうなと思っていてたので、認証が要らず誰でもキューを作成したり、キューに対してメッセージを送信・受信したりできるようにしてある。

heroku + redis to go に公開しているので、

http://q3-global.herokuapp.com/?Action=CreateQueue&QueueName=tily.hatenablog.com

とかやるとキューを作れるし、

http://q3-global.herokuapp.com/*/tily.hatenablog.com?Action=SendMessage&MessageBody=hello

とかやるとキューに対してメッセージを送信できるし、

http://q3-global.herokuapp.com/*/tily.hatenablog.com?Action=ReceiveMessage

とかやるとメッセージを受信できる。

基本機能の統合テストを書いたので、割とちゃんと動くと思う。メッセージを遅延させるやつ (DelaySeconds) とか、VisibilityTimeout も普通に使える。

Amazon SQS と互換しているので、Amazon SQS 互換のクライアントからなら自由にメッセージを送受信できるはず。

q3-global は何の役に立つかよく分からないので、これから使い方を考える。ローカルに redis さえ立ち上がっていれば、gem install q3 して q3 コマンドを打つだけで気軽に API を立ち上げることができるので、よかったら使ってみてください。

AWS Simple Icons のセキュリティグループの赤黒の囲みを CSS で再現してみた

非常に地味な話なんですが、AWS Simple Icons ではセキュリティグループを赤と黒のボーダーによる枠線で囲むことになっており、シンプルでかっこいいので HTML+CSS で実現できないかなーと思って色々試していたらそれっぽいものができたので書いておきます。こんな感じのやつ。

security group

ソースは上記リンクのページに載っています。CSS に詳しくないので他のスタイルシートと組み合わせるとうまく描画されないとか色々あるかも。昔から CSS 苦手なので勉強したいと思った。

ニフティクラウドの情報取得系 API を RESTful なインタフェースで利用できるようにする Sinatra アプリ

ニフティクラウドの APIAWS 互換なのですが、レスポンスの形式が独特で少々扱いづらいので、REST っぽいインタフェースから情報取得できるようにしてみました。

/computing/instances でサーバー一覧がとれたりするので、Backbone.js の Collection から使ったりすると便利なんじゃないかと思います。

ひまなときにニフクラ RDB/MQ/ESS/DNS/Automation にも対応したい。

追記 (2014/06/27)

現在のバージョンで v0.0.3 で RDB/MQ/DNS に対応しています。

(きこえる) CIDR アドレス計算ツール

(きこえる) CIDR アドレス計算ツール by tily

ソース: tily/cidrcalc

仕事で必要になったとき、(今さら)CIDRアドレス計算ツール by yamagata21 にお世話になっていたんだけど、IPをそのままコピペできない点とかがやや不便だったので、勉強がてらに自分がほしい感じの CIDR アドレス計算ツールを作った。下記が工夫した点です。

  • オクテット毎の入力ではなく IP アドレスをそのままペーストできる
  • クライアントサイドだけで完結しているのでサーバーサイドに IP アドレスを送らなくていい
  • ボタンをおさなくても正しい IP アドレスを入力すれば結果が反映される
  • パーマリンクをはれる
  • 8 進数・16 進数・整数の表示は必要になることが少ないので思い切って削った

あと、どうせなら何か機能を追加しようと思い、2 進数にした IP アドレスを 32 分音符に見立てて、音として聴ける機能を追加してみた。Web Audio API を使っているのでそれなりにちゃんと聴こえるのではないかと思います。10. ではじまる IP アドレス、192.168. ではじまる IP アドレス、172. ではじまるIP アドレスぐらいは聴き分けられそうでおもしろい。

YouTube の動画を組み合わせて新しい音楽を作れる YouSample というウェブアプリを作った

YouSample
http://f.st-hatena.com/images/fotolife/t/tily/20140615/20140615120718.png

最近サンプリングベースの HIPHOP が好きで、YouTube の動画を並べるだけで新しい音楽を作れたら面白いんじゃないかなと思い作ってみた。

作例なので適当でセンスない感じだけど、こういう感じの (http://bit.ly/1orEbbL http://bit.ly/1iyH9mG) とかを簡単に作れます。最大 4 つの YouTube 動画を埋め込むので結構重いかも。あと、Mac+Google Chrome でしか動作確認していません。

ハッシュに JSON を埋め込むのは前に hitode909 さんがやっていたのを真似しました。タイミング制御に mohayonao/MutekiTimer を使おうとしたのだけどうまくできなかったのでそのうち再チャレンジしたい。

追記(2014/06/15)

Mac+Google Chrome でしか動作確認していなかったら、ほんとにそれ以外の環境ではまともに動かないことが分かりました。無念。どうも音が細切れに再生されてしまうような気がするんだけど、何が悪いのかよく分からないので分かったら直したいです。

あと、ブックマークコメントで renu さんから「ミュートボタンで音をオンオフとか面白いなあ」というのを頂戴したのですが、似たようなものを作ろうとしている人のために書いておくと、YouTube Player API Reference for iframe Embeds では、一度プレイヤーをstopVideo() すると seekTo() してもすぐに指定した位置に戻って再生してくれないので、常にプレイヤーの状態を playing にしたまま unMute() して指定した時間が経ったら mute() するような実装になっています。