クックパッドで見つけた美味しいレシピ、和風編

今年(2016年)の1月から、クックパッドのプレミアム会員です!
今まで見つけた美味しいレシピを共有してもいいのでは?と思って〜
並び順はおすすめ順かな?適当な場合もあるかもしれませんが…

http://cookpad.com/recipe/2588173 簡単☆小麦粉で作るチーズお好み焼き
お好み焼きを作る時は、いつもこのレシピです。
ただし、これだと、少し分厚いかもしれません。
ほんだしは、もうちょっとだけ濃くしてもいいかもしれません。

http://cookpad.com/recipe/2407781 もっちり美味しい♡ニラの薄焼き
初めてのつくれぽを付けたレシピです!
美味しい&安いです!
飽きやすいかもしれませんが、難しくないので初めてでも成功する逸品です!

http://cookpad.com/recipe/2348826 エリンギの帆立風!にんにくバター醤油焼き
ちなみに、これを、豚醤油というもので作ったのですが、大変美味しかったです。
豚醤油は、http://ccib.or.jp/?page_id=308で購入できます。
高いです(´・ω・`)
他のブログなどを見てみたら、たまにお店でも買えることがあるらしいです!最初にメールで、どこか首都圏のお店では購入できませんか、と問い合わせてみましたが、現在できないということで、メールで注文して着払いで払いました。

http://cookpad.com/recipe/2921320 大根と合挽き肉の甘煮
美味しいです^^
「これが日本の味ですよ」と外国人に出すのに良い逸品だと思います!

http://cookpad.com/recipe/2839788 ♡レンコンと秋刀魚の黒酢あんかけ♡
きれいだし、美味しいです^^
ただし、秋刀魚ではなく、チキン竜田で作りました。

http://cookpad.com/recipe/1374729 手作り和風ドレッシング☆
簡単な和風ドレッシングです。美味しいです^^

Mixiのライフサイクルイベントの署名付きリクエスト / Mixi Lifecycle Event OAuth signatures

Mixiのライフサイクルイベント(アプリが追加された、アプリがマイアプリから削除されたといったイベント)の署名付きリクエストは他のよりまた少し違うみたいです。公開鍵を使うところは他にもありますが、ライフサイクルイベントの場合は、OAuth情報がHTTPのAuthorizationヘッダーに入っているため、お使いのOAuthライブラリーによってうまくいかない場合があるかもしれません。Rubyのoauthではほぼ動くのですが、

xoauth_signature_publickey=lc_20131107

が署名に含まれないため失敗します。

signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do

のようにOAuth::Signature.build()に渡すと署名に含まれ、署名の検証が通ります。

検証が通ったbase stringの例:

GET&http%3A%2F%2FXXXXXXXXXX%2FXXXXXXXXXX%2FXXXXXXXXXX%2Faddapp&eventtype%3Devent.addapp%26id%3Dmo3XXXXXXX7fr%26mixi_invite_from%3DmgwXXXXXXXnt8%26oauth_consumer_key%3Dmixi.jp%26oauth_nonce%3D719445958eb7ae359824%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1468335606%26oauth_version%3D1.0%26opensocial_app_id%3D41345%26xoauth_signature_publickey%3Dlc_20131107

ちなみに、xoauth_signature_publickeyが一生変わらないわけではありません。Mixiの公開鍵と同じタイミングで変わる予定です。現在使われている公開鍵の有効期限は確か2020年だったと思いますので、まだしばらく大丈夫かもしれないですね。

英訳の下のmixi_signed_request?関数の例もご参照ください。

Mixi’s Lifecycle events (add app and remove app) use an OAuth scheme that is slightly different from Mixi’s other OAuth implementations: the OAuth headers are included in the HTTP Authorization header. Depending on your OAuth library,  the non-standard xoauth_signature_publickey (passed in the HTTP header) may not be included when calculating the signature. However, Mixi includes this parameter. You’ll have to pass it manually to OAuth::Signature.build(), e.g., like this:

signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do

Here’s an example of a base string that could pass validation:

GET&http%3A%2F%2FXXXXXXXXXX%2FXXXXXXXXXX%2FXXXXXXXXXX%2Faddapp&eventtype%3Devent.addapp%26id%3Dmo3XXXXXXX7fr%26mixi_invite_from%3DmgwXXXXXXXnt8%26oauth_consumer_key%3Dmixi.jp%26oauth_nonce%3D719445958eb7ae359824%26oauth_signature_method%3DRSA-SHA1%26oauth_timestamp%3D1468335606%26oauth_version%3D1.0%26opensocial_app_id%3D41345%26xoauth_signature_publickey%3Dlc_20131107

Note that the certificate and the “lc_20131107” are linked. When there is a change, both will be updated. The current certificate is valid until 2020 or so.

The full verification code could look like this:

  def mixi_signed_request?
    mixi_certificate = <<END
-----BEGIN CERTIFICATE-----
MIIDNzCCAh+gAwIBAgIJAIQ3zDiILtpzMA0GCSqGSIb3DQEBBQUAMDIxCzAJBgNV
BAYTAkpQMREwDwYDVQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDAeFw0x
MzExMDcwODQwNTBaFw0yMzExMDUwODQwNTBaMDIxCzAJBgNVBAYTAkpQMREwDwYD
VQQKDAhtaXhpIEluYzEQMA4GA1UEAwwHbWl4aS5qcDCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAMxzCu9sUctGAzL/X0/sH2MSRmc/+X2Wx87ObZDpEd5P
19mIUQXW6hCXObB3SkE7kMuXiRhtrxwsnB9fjYIUEq/1vsTHkLJoJVUFIumqe6EH
c/WZaTmu34WpEUFXNDS4htidXyVqikoDQZF9wdczyH7bLPbekQfRAcyek3E6/7Qi
B00yWUqK8FcUOD4ILmtSHXsz4BNqekNgEzfUi5WkBYKtuD5zSunZalbWUPS7xa57
o1auVdclaHBfqe8dC5DTbxIe0szpHckQrJF9fJ/bIQSmvY6ADBRGfoLF7Fgoc5x+
R5my9weytzg4WdDUjYrxmhy5IpjxytipQqrFDqAUxl8CAwEAAaNQME4wHQYDVR0O
BBYEFKCQSlssCWLqd0tT7NVtoBUNzCasMB8GA1UdIwQYMBaAFKCQSlssCWLqd0tT
7NVtoBUNzCasMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBALoI7elk
ZCv+pUpi6aJepzLnQDYHB2eXpDkpWEUrF1WMvx8ovmWdVeviHqUdFtGL0XZ5tSoV
vGE/KQTavag+MfbafKaff4iHXNyNMygeFP7r/FaFQQRafyNfhaXF6sWfwKrOk/Bc
jIXFN9tYWN6LEwNgYT0C+OSOppQJzt2y1am15FExAHQcIEFYc+3T+MGGJ7e9H8tn
Qz84WmIgNZRUMYQC0PJTsMNVvr+/DTIzjabKz4W8qodXGA7AxXiRYdgC+3RUj/rA
lR09PXZ6nRaKiB0KBDIMUlPu/0u0Vw+GBt0ckH0htOKSxsn09jkITFhy3NX7Slbk
jlnY4pS9JO+avmM=
-----END CERTIFICATE-----
END

    require 'oauth'
    require 'oauth/signature/rsa/sha1'
    begin
      consumer = OAuth::Consumer.new(nil, mixi_certificate, {:signature_method => 'RSA-SHA1'})
      signature = OAuth::Signature.build(request, {:parameters => {'xoauth_signature_publickey' => 'lc_20131107'}}) do
        [nil, consumer.secret]
      end
      return signature.verify
    rescue => e
      logger.debug(e.inspect)
      return false
    end
  end

さくらクラウドの料金システムについて / Sakura’s Cloud Pricing System

さくらクラウドの料金システムには、月額、日額、時間額と、3つの価格があります。月額が日額などよりもお得であることは、プラン変更の際に頭に入れておいた方が良いかもしれません。
損をする例を見てみましょう:
プラン/2Core-2GB   30 + 0時間   3,240円 ← 高いスペックで通常の月額
プラン/2Core-2GB   17 + 14時間   2,916円 ← 高いスペックで17日間分
プラン/1Core-1GB   12 + 9時間   982円 ← 安いスペックで12日間分
12日間スペックが低かったのに、3898円と、高いスペックの通常の月額より658円高いです。
皆さん、気をつけてください。

Just here to document a peculiar feature of Sakura Cloud’s pricing system.
Let’s say you’ve been running on high-spec’d servers and want to reduce these specs a bit. For example, you would like to go from プラン/2Core-2GB down to プラン/1Core-1GB.
Depending on the day you do the change, you may end up paying more than necessary. Here’s an example:
プラン/2Core-2GB    30 + 0時間    3,240円 ← This is the normal monthly price for 2 core/2 GB plan
プラン/2Core-2GB    17 + 14時間    2,916円 ← Let’s say you reduced the specs on the 17th – you’ll pay almost a month’s worth of server fees for the 2 core/2 GB plan
プラン/1Core-1GB    12 + 9時間    982円 ← And the remaining days for the 1 core/1 GB plan
So that month you’ll pay 3898 JPY, even though you were running on lower specs.

Mixiの(モバイルでの)署名付きリクエスト

この度、ガラケー向けのMixiアプリを作ることになりました。こういうアプリのリクエストは、実機 → Mixiが運営しているサーバー → アプリ用サーバー、という流れで送られるようです。(もちろんサーバーから実機への回答は逆の流れです。)Mixiのサーバーは、各リクエストに、ユーザーのMixi IDみたいな文字列を付けてくれて、そして本当にMixiのサーバーから来たリクエストかどうかを検証できるように、署名も付けてくれます。

Mixiの公式ドキュメンテーションはhttp://developer.mixi.co.jp/appli/spec/mob/validate-oauth-signature/にありますが、残念ながら、現在のところ、多少足りない部分がありまして…

まずは、下記のGETリクエストを例として上げているのだが、

http://example.com/foo/?opensocial_app_id=123&opensocial_owner_id=xxxxxxxx

「Ky/6LlDHpHX1EZMRi5mfUl9vxqY=」という署名になるには、「opensocial_owner_id」を「xxxxxxxx」ではなく、「456」に設定しないといけません。
なんで知ってるの!?
archive.orgのおかげです: https://web.archive.org/web/20100912034001/http://developer.mixi.co.jp/appli/spec/mob/validate-oauth-signature

続いて、「特殊な文字(漢字など)を含んでいるパラメーターはどうすればいいですか?」という質問に対する明らかな答えもなく、困っていました。
いろいろ試したところ、二重エンコーディングで対応できました。
つまり、「example.com/foo?test=テスト」みたいなリクエストは、ユーザー側のブラウザーから「example.com/foo?test=%E3%83%86%E3%82%B9%E3%83%88」のように送られます。それを「%25E3%2583%2586%25E3%2582%25B9%25E3%2583%2588」にすると検証が通ります。

test[foo]=barみたいな、角括弧が入っているパラメーターも同じように二重エンコーディングします。

Ruby on Railsだと、下記のようなコードで検証できます。

def mixi_signed_request_mobile?
    require 'cgi'
    oauth_header = request.headers["HTTP_AUTHORIZATION"].split(/\s*,\s*/)
    oauth_header_hash = Hash[oauth_header.map { |keqv| keqv.gsub('"', '').split('=') }]

    base_string_array = [
      "oauth_consumer_key=" + @client_id,
      "oauth_nonce=" + oauth_header_hash["oauth_nonce"],
      "oauth_signature_method=" + "HMAC-SHA1",
      "oauth_timestamp=" + oauth_header_hash["oauth_timestamp"],
      "oauth_version=" + "1.0"
    ]
    if request.get?
      uri = URI.parse(request.url)
      query_array = URI.decode_www_form(uri.query)
      base_string_array += query_array.map{|param| "#{CGI.escape(param[0])}=#{CGI.escape(param[1])}"} # takes care of opensocial_app_id and opensocial_owner_id as well
    else
      # don't need the actual parameters for post requests (mixi-specific awkwardness)
      base_string_array += ["opensocial_app_id=#{params["opensocial_app_id"]}", "opensocial_owner_id=#{params["opensocial_owner_id"]}"]
    end
    base_string_array.sort!
    url = request.original_url.gsub(/\?.*/, '') # can't use request.base_url + request.path because the trailing slash is sometimes(?) cut off
    baseString = request.method + "&" + CGI.escape(url) + "&" + CGI.escape(base_string_array.join("&")) # [] and utf-8 are doubly percent-encoded!! e.g. "テスト" becomes "%25E3%2583%2586%25E3%2582%25B9%25E3%2583%2588"!!!!!

    sha1 = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA1.new, @client_secret + "&", baseString)
    base64 = Base64.strict_encode64(sha1)

    return CGI.escape(base64) == oauth_header_hash["oauth_signature"]
  end

(The above explanation and code show how to verify Mixi’s OAuth 1.0 signatures, as used with Japanese feature phone apps.)

Excel character counter / エクセル文字カウンター

At work, somebody sometimes needs to count the length of selected text in Excel cells. Doing it in one’s head is understandably unpleasant, so why not see if there’s software out there that can count the number of characters in selected text? Well, I got pretty close at http://www.donationcoder.com/Software/Skrommel/index.html#DragKing. Since this is written in AutoHotkey, I’d just have to modify it a bit to count while the mouse cursor is being dragged. (Watch the video below to see it in action.) Unfortunately, pressing Ctrl+V while selecting text doesn’t work, so we instead send the WM_COPY message, like this:

SendMessage 0x301,0,0,%Control%, %WinTitle%  ; WM_COPY

Also it’s not cool if the script gets rid of your clipboard contents, so we restore that too. Get the script here: moji_counter_v3.ahk
Note that it’s partially localized to Japanese.

会社に、エクセルセル内の文字を数えたり区切ったりする作業をしている人がいるのですが、頭の中で数えるのはあまり楽しくないので、この度、どうにかならないかという相談を受けました。早速ネットで調べてみると、http://www.donationcoder.com/Software/Skrommel/index.html#DragKingでほぼ同仕様のソフトがありました!しかもAutoHotkeyなので、すぐにうちの用途に合せられます。

DragKingではマウスボタンを外すとテキストをコピーして文字列の長さをカウントしているのですが、文字列を選択している間にカウントできたらもっと便利なんじゃないかなと思って…しかし、Ctrl+Vを押しても文字がコピーされないので、

SendMessage 0x301,0,0,%Control%, %WinTitle%  ; WM_COPY

変わりましてWM_COPYというメッセージを送ってコピーさせます。後、DragKingの仕様と違って、コピー・カウントの後、クリップボードの内容を復活させます。
AutoHotkeyスクリプトを下記のリンクでダウンロードできます。
moji_counter_v3.ahk

ブラック心理テスト

I recently started a job at a Japanese app development company that is mostly making fortune telling apps and the occasional personality test. I’m getting to work on some interesting stuff, including app development, web development, one-off utilities, and server administration. My first assignment was a personality test, and since it’s released now, I think I’m just going to link to it below.

最近転職し、占いアプリなどを取り扱っている日本の会社で活躍することになりました。「ブラック心理テスト」というアプリの開発を頼まれたのですが、ようやくリリースできましたのでリンクを貼らせていただきます〜

ブラック心理テスト@Play Store (Android)
ブラック心理テスト@App Store (iPhone)

まぁ、とても簡単なアプリですが、友だちが「楽しいかも!」と言ってくれました^^