Merbでリソースに:editのようなカスタムアクションを追加する場合、 以下のように:memberオプションを利用出来ます。

config/router.rb

   1  resources :materials, :member => {:download => :get}

これによって、GET /materials/:id/downloadが、Materials#downloadにmapされます。

posted by Png genki on Thu 26 Feb 2009 at 01:24

Merbでファイルアップロードのspecを書く場合には、 multipart_*系のAPIを利用出来ます。 以下は一例です。

   1  tmp = Tempfile.new('spec')
   2  path = tmp.path + ".txt"
   3  begin
   4    file = open(path, "w+")
   5    file.write "test"
   6    multipart_post(resource(:materials),
   7      :material => {:id => nil, :label => 'test', :file => file})
   8    tmp.close
   9  ensure
  10    file.close
  11    File.unlink path
  12  end

:content_typeはfilenameから推定されるので、拡張子をくっつけています。

posted by Png genki on Thu 26 Feb 2009 at 00:59

自分用メモ。
Mac標準のTextEditとプレビューを使ってリンクを含むPDFを作成します。

  1. TextEditでテンプレを参考にしつつ文を作成
  2. URLとメールアドレスの部分だけ、青色、下線の状態に
  3. ファイル - プリントを選び、プレビューボタンをクリック
  4. 先程、青色にしたテキストを選択状態にし、ツール - 注釈 - リンクを追加を選択
  5. アクションをURLにして、URL欄にURLまたはmailto:メールアドレスを入力
  6. すべてのリンクが追加できたら、ファイル - 保存を選択
  7. 終わり
posted by Png satoko on Wed 25 Feb 2009 at 17:00

2月25日付けでezPhotoMailのプレスリリースを出しましたので、ブログからもリンクさせて貰います。
先日の記事と随分被っておりますが、ご了承くださいませ。


ezPhotoMail

iTunes_ezPhotoMail.png

iPhoneで撮影した写真をじじばば(携帯メールアドレスしか持たない)に送りたいと思ったのですが、付属や市販のメールアプリでは画像サイズが大きかったり、日本語が文字化けしていたので、これを解消したいと思いこのアプリを制作しました。ezはeasyの意味ですが、zでじぃー(じじ)も兼ねています。

現在、日本のAppStoreの有料アプリケーション、写真部門で26位にランクされています。

ブログやiTunes Storeにも色々要望を頂いているので、検討して拡充していきたいと考えています。

ezPhotoMailとは

iPhoneで撮った写真をリサイズし、Gmailを使って簡単に写真添付メールを送信することができます。

iTunesストアURL
http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=305784712&mt=8

特徴

  • リサイズするサイズは任意に設定が可能:デフォルトは320x240。
  • 送信先として、手入力またはアドレス帳からインポートすることが可能です。
  • 件名はISO-2202-JPでエンコードされます。

(注)

  • 送信設定としてGmailアカウントが必要です
  • iPhone 2.0以降対応

ezPhotoMail_UI1.jpg

posted by Png satoko on Wed 25 Feb 2009 at 12:14

Merbのデフォルト構成にはRailsのような HTMLのsanitizeを行うようなヘルパーメソッドは無いのですが、 Gemで提供されている sanitize というライブラリを使うと、簡単にHTMLのsanitizeを行う事が出来ます。

   1  Sanitize.clean(html, Sanitize::Config::RELAXED)

タグ毎に有効・無効の細かい設定が出来て、使い勝手が良いです。

posted by Png genki on Tue 24 Feb 2009 at 15:28

Singleton Methodを削除する方法 についてですが、 Objectクラスに用意されているとありがたいですね。

object_ext.rb

   1  class Object
   2    def remove_singleton_method(*args)
   3      (class << self; self end).class_eval do
   4        args.each{|i| send :remove_method, i}
   5      end
   6    end
   7  end

こんな感じ。

posted by Png genki on Mon 23 Feb 2009 at 22:02

方法を探していたのですが、意外と苦戦したのでメモ。

   1  object = new Object
   2  def object.foo; end
   3  object.singleton_methods #=> [:foo]
   4  (class << object; self end).class_eval{send :remove_method, :foo}
   5  object.singleton_methods #=> []

これで行けるようです。instance_eval{undef foo}でも削除はできますが、その場合親クラスのメソッドにもアクセス出来なくなってしまうので、 singleton methodだけを削除する場合には、 メタクラスのインスタンスメソッドをremove_methodするのが良いようです。

posted by Png genki on Mon 23 Feb 2009 at 21:53

カメラ系やメモ系のアプリなんかはユニーク/一意な名前を考えるのに苦労します。で、*.appファイル名と、iPhone上で表示される表示名を変えたいと思ったのでメモメモ。

Store上で表示される名前と*.appファイル名と、iPhone上の表示名が違っても申請が通るかどうか、またどれくらい違ったらokなのか気になるところです。ちなみにStore上とiPhone上の表示名は違うことはよくあるみたいで、Store上ではより長い仕様分かりやすい名前にするのをよく見かけます。

結論:CFBundleDisplayNameを編集すればok

例えばShopping Pink.appというappファイル名で、表示はShoppingとすることが可能です。

Info.plistで:

   1  	<key>CFBundleDisplayName</key>
   2  	<string>Shopping</string>
   3  	<key>CFBundleExecutable</key>
   4  	<string>${EXECUTABLE_NAME}</string>

CFBundleDisplayNameとCFBundleNameの違い

ぐぐったところ、CFBundleNameはQuickLookでindexされる名前??、CFBundleDisplayNameは言語毎にローカライズしたい時に使うプロパティだということがわかりました。

/ Localized versions of Info.plist keys /

NSHumanReadableCopyright = "© __MyCompanyName__, 2008";
CFBundleName = "English MenuBar"; //...and Finder's QuickLook
CFBundleDisplayName = "EnglishApp";
http://forums.macrumors.com/showthread.php?t=537977

Refs

http://eien.seesaa.net/article/27964381.html
http://forums.macrumors.com/showthread.php?t=537977
http://developer.apple.com/documentation/MacOSX/Conceptual/BPInternational/Articles/LocalizingPathnames.html#//apple_ref/doc/uid/20002141-97582-BCIDCGHG

posted by Png satoko on Mon 23 Feb 2009 at 17:13

An Idea for Open Avatar Exchange

I am using GRAVATAR at github.com. It is very interesting service that provides globally recognized avatar image from a hash of email address. What is clever is a service using GRAVATAR can present its user's avatar without not exposing his/her email address.

But the GRAVATAR is not the only provider of such avatars. For example, twitter.com has huge database of mapping from email address to avatar image. There are a lot of services which have such the database.

Imagine twitter.com, facebook, linkedin and so on provide their avatar images by the same manner. We can provide avatar image for every user of which we know his/her email address everywhere and quite easily. This is the principal advantage of this idea.

But what is advantage for provider? That's the obvious question. Answer is inter-service completion of avatar images. In each service, not all users have his/her avatar image. For such users, the service provides disappointing default avatar image. But if there is the open avatar exchange, the service can try to find it in other services instead.

The way to make the exchange is really simple. Provide REST API to map MD5 hash of email address to avatar image. Block accesses from domains you don't want to exchange.

In addition, avatar providers can harvest stats of the sites that are using your avatar image.

posted by Png takiuchi on Mon 23 Feb 2009 at 08:21

MerbのCacheはなかなか優れた設計なので面白いのですが、 開発中にログにCache Miss/Hitの具合が分かるように出力してほしかったので、 development環境用のLoggingMemcachedStoreというのを書いてみました。

   1  class LoggingMemcachedStore < Merb::Cache::MemcachedStore
   2    include Extlib::Hook
   3   
   4    before :read do |key, params|
   5      if exists?(key, params)
   6        Merb.logger.debug "Cache Hit: #{key}"
   7      else
   8        Merb.logger.debug "Cache Miss: #{key}"
   9      end
  10    end
  11   
  12    before :write do |key, data, params, conds|
  13      Merb.logger.debug "Cache Write: #{key}"
  14    end
  15  end

こんな感じでログに出ます。

   1  merb : worker (port 4000) ~ Cache Hit: Plugins#show
   2  merb : worker (port 4000) ~ Cache Write: Plugins#show

posted by Png genki on Sat 21 Feb 2009 at 01:27