Exifファイルの原画像データ生成日時を取得するライブラリ

ディレクトリに保存されているExifファイルから、原画像データを生成した日時(DateTimeOriginal)を取得するCライブラリを作ってみました。

サンプルの実行例

sample.cをコンパイル、実行すると以下のような結果が表示されます。

$ ./sample ~/Pictures/
/Users/nkmrshn/Pictures/DSCN0001.JPG, 2011:02:23 14:00:03
/Users/nkmrshn/Pictures/TS3R0001.JPG, 2010:01:01 17:24:02
/Users/nkmrshn/Pictures/SH340001.JPG, 2008:02:04 06:25:38

余談

今年2月に大病を患い、5月のGW中、リハビリの為につくった代物です。何の役に立つのだろうか。

例えば、画像ファイルビューワで撮影日時毎に一覧を表示させる際、その一覧表示ウィンドウを生成する過程において使えるんじゃないかなぁ...と。

コマンドラインでツイートするRubyスクリプト(その2)

昨年、『コマンドラインでツイートするRubyスクリプト』(2011年2月6日)および『コマンドラインでツイートするRubyスクリプト(つづき)』(2011年2月11日)を書きました。

この度、コードを見直し、TwitterREST API v1.1に対応させ、GitHubにpushいたしました。

設定や使い方に関しては、基本的には以前と変わっておりません。URLが文中にある場合、その前後に半角空白があると短縮化される仕様を追加いたしました。詳しくは、READMEをご覧ください。

余談

POST status/update_with_mediaを使って、コマンドラインから画像ファイルも投稿できたらいいなぁ。

あ...

The Twitter Ruby Gemなんてあったんですね。もっと簡単に作れたのか...


[追記:10/13 1:17]
とりあえず、最後の引数として画像ファイルを指定すると、画像も投稿するようにしてみました。ただし、GET help/configurationで投稿できる画像サイズなどをきちんとチェックはしていないのでご注意ください。


[追記:10/30 19:35]
これまで一つのファイルだったものを分割したり、Unitテストなどを追加しました。ただし、postメソッドのテストは未実装ですが、中途半場でも無いよりはいいだろうと、コミットしてあります。

ログイン時に開く

現在、いわゆる「ログイン時に開く」を実装したアプリをApp Storeに申請中です。承認されるか、却下されるかわからないのですが、備忘録を残しておきたいと思います。

私がXcode 4.5で試した方法なので、それ以外ではOrganizerのValidateで却下されたり、うまくOrganaizerでSubmitできても、iTunes ConnectでInvalid Binaryと表示されるかもしれません。

SMLoginItemsSetEnabled関数を使う

  • App Storeに申請するにはSandbox化が必要です。
  • その為、AppleがdepreciatedしているLSSharedFileListInsertItemURL関数は使えない。
  • そこで、SMLoginItemsSetEnabled関数を使う。
  • ただし、この関数は次の条件でしか使えない。
    1. Contents/Library/LoginItemsにメインアプリを起動するヘルパーアプリが保存されていること。
    2. ヘルパーアプリは、LSUIElementもしくはLSBackgroundOnlyキーをInfo.plistファイルに設定していること。

StartAtLoginControlerを使う

Alex Zielenski氏の「StartAtLoginController」を使わせていただきました。

https://github.com/alexzielenski/StartAtLoginController:Title=https://github.com/alexzielenski/StartAtLoginController

ログイン項目に表示されない

SMLoginItemsSetEnabled関数を呼んでも、システム環境設定の「ユーザとグループ」にある、各ユーザのログイン項目に追加されませんでした。最初、関数の呼び出しに失敗したのかと思ったのですが、きちんとログイン時にアプリが開くため、バグではないと思うのですが。

他にやったこと

  • ヘルパーアプリ
    1. MainMenu.xibからメインウィンドウを削除。
    2. Info.plistのApplication is background onlyをYES。
    3. ヘルパーアプリのBuild SettingsにあるSkip InstallをYES。
  • メインアプリ
    1. アプリの環境設定で、「ログイン時に開く」を有効にした時、確認アラートを表示させ、可否を問う。
    2. ヘルパーアプリをContent/Library/LoginItemsにコピーする為、メインアプリのBuild PhaseにCopy FIleを追加。DestinationはWrapperで。
    3. ヘルパーアプリのembedded.provisionprofileを削除しないとOrganaizerのValidateが失敗するため、Build PhaseにRun Scriptを追加。
rm "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Library/LoginItems/${PRODUCT_NAME}Helper.app/Contents/embedded.provisionprofile"
  • 両アプリ
    1. Provisioning Profilesで作成し、インストール。
    2. ヘルパーもEnable App Sandboxingを有効にする。

余談

他に書き忘れていることはないかなぁ...

Lokka用のプラグインを更新

これまで、いくつかLokka用のプラグインを作成してまいりましたが、ほとんどが動かなくなっていました。
主な原因は、Lokkaが使っていたi18nに変更があったらからです。今回、プラグインi18nディレクトリにあるen.ymlとja.ymlを修正するなどしました。
また、LokkaのHTMLエディタが変更になったこともあり、画像アップロード系のプラグインなどは修正箇所が多いことなどから、誠に勝手ながら公開を終了させていただきました。

謝辞

今回、プラグインを修正した後、間違ってLokka本体のGitHubにコミットしてしまいました。関係者各位には、ご迷惑をおかけし申し訳ありませんでした。

Play! frameworkで作ったアプリをHerokuで動かしてみた

HerokuJavaに対応*1しました。そこで、Play! frameworkTutorialで作るブログエンジン、「Yabe」をHerokuで動かしてみました。

Herokuにアプリを作成*2

Herokuにアプリを作成しますが、この時に「--stack」オプションを追加して「cedar」スタックを指定してください。アプリの名前を「yabe-nkmrshn」に変更していますが、これは必須ではありません。

$ heroku create --stack cedar
$ heroku apps:rename yabe-nkmrshn

次にデータベースを追加。とりあえず無料の共有データベースを指定しました。

$ heroku heroku addons:add shared-database

そして、conf/application.confで設定するPostgreSQLのURLを取得します。

$ heroku config
SHARED_DATABASE_URL => postgres://<URL>

Yet Another Blog Engine(Yabe)の準備

HerokuのデータベースはPostgreSQLなので「User」というテーブルが作れません。そこで、Userをすべて「Account」に書き換えました。また、Tutorialの第10章「Completing the application tests」を終えた後、私はフレームワークIDを「prod」に設定してあります。

conf/application.confのデータベースの設定にPostgreSQLを追加します。

%prod.db=postgres://<URL>

また、DDLはあえて「update」を指定しました。これは、app/Bootstrap.javaでテーブルの作成と初期値*3の挿入をおこなわせる為です。本当はnoneにして、migrationモジュールを使って管理するのがいいんだと思いますが、Herokuのコマンドで「heroku run play db:migrate」などと実行できるのかなぁ...

%prod.jpa.ddl=update

最後に「Procfile」という名前のテキストファイルをアプリケーションルートに作成します。最後の「--http.port=$PORT」は必須です。

web: play run --%prod --http.port=$PORT

Herokuにデプロイ

gitコマンドでHerokuにpushしてデプロイします。

$ git push heroku master
Counting objects: 7, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 337 bytes, done.
Total 4 (delta 3), reused 0 (delta 0)

-----> Heroku receiving push
-----> Play! app detected
-----> Building Play! application...
       ~        _            _ 
       ~  _ __ | | __ _ _  _| |
       ~ | '_ \| |/ _' | || |_|
       ~ |  __/|_|\____|\__ (_)
       ~ |_|            |__/   
       ~
       ~ play! 1.2.3, http://www.playframework.org
       ~
       1.2.3
       Play! application root found at ./
       Resolving dependencies: .play/play dependencies ./ --forceCopy --sync --silent -Duser.home=/tmp/build_35cm0iosbsdu2 2>&1
       ~ Resolving dependencies using /tmp/build_35cm0iosbsdu2/conf/dependencies.yml,
       ~
       ~
       ~ Installing resolved dependencies,
       ~
       ~        modules/crud -> /tmp/build_35cm0iosbsdu2/.play/modules/crud
       ~        modules/secure -> /tmp/build_35cm0iosbsdu2/.play/modules/secure
       ~
       ~ Done!
       ~
       Precompiling: .play/play precompile ./ --silent 2>&1
       Listening for transport dt_socket at address: 8000
       12:27:59,957 INFO  ~ Starting /tmp/build_35cm0iosbsdu2
       12:27:59,962 INFO  ~ Module secure is available (/tmp/build_35cm0iosbsdu2/modules/secure)
       12:27:59,962 INFO  ~ Module crud is available (/tmp/build_35cm0iosbsdu2/modules/crud)
       12:28:00,725 INFO  ~ Precompiling ...
       12:28:08,140 INFO  ~ Done.
       
-----> Discovering process types
       Procfile declares types -> web
-----> Compiled slug size is 26.6MB
-----> Launching... done, v17
       http://yabe-nkmrshn.herokuapp.com deployed to Heroku

To git@heroku.com:yabe-nkmrshn.git
   22989f1..6e542c5  master -> master

余談

Herokuすげー。

*1:Heroku for Java

*2:既にHerokuのアカウントやHerokuのGem、そしてgitコマンドなどが使える状態にあると想定。

*3:Tutorialのconf/initial-data.yml

プラスワンボタンを表示するLokkaプラグイン

プラスワインボタンを表示するLokkaプラグインを作ってみました。このボタンはGoogleが提供してくれるもので、プラグインのヘルパーメソッドでそれを呼び出すためのHTMLコードを挿入します。

使い方

ヘルパーメソッドとして、「plusone_js」と「plusone」を用意しました。APP_ROOT/public/pluginにgit cloneして、lokka-plusoneをダウンロードした後、お使いのテーマを修正してください。

headタグ内もしくは、bodyタグ後にplusone_jsを追加しscriptタグを挿入します。

<script type="text/javascript" src="https://apis.google.com/js/plusone.js"></script>

plusoneは、g:plusone(DOM)あるいはdivタグ(HTML5)を挿入します。

<g:plusone size="medium" count="false" lang="ja"></g:plusone>
<div class="g-plusone" data-size="medium" data-count="false" data-lang="ja"></div>

管理画面の[プラグイン]->[Plusone]でオプションを設定することができます。

コールバック関数など、プラワンボタンの詳細につきましては、GoogleAPI*1をご覧ください。

余談

しかし、ボタンが増えたなぁ...ソーシャルボタンの共通仕様APIとか業界で作らないのかなぁ...

全角1文字を半角2文字としてカウントするvalidator

auのメールは、件名が半角100文字、本文が半角10,000文字*1まで。それをvalidateするには、全角1文字を半角2文字としてカウントする必要があります。そこで、RailsのSexy Validationで独自のValidatiorを作ってみました。

ソース

全角文字(1バイト以上)は、半角2文字としてカウントし、maximumに指定した値を超えるかどうかを判定しています。

${APP_ROOT}/lib/length_with_wide_char_validator.rb

class LengthWithWideCharValidator < ActiveModel::EachValidator
  def validate_each(object, attribute, value)
    count = 0 
    value.split(//).each do |v| 
      v.bytesize > 1 ? count += 2 : count += 1
    end 
    object.errors[attribute] << (options[:message] || "is too long (maximum is %d characters)" % options[:maximum]) if count > options[:maximum]
  end 
end

使い方

これを、ActiveRecord::Baseを継承するモデルファイルの先頭で、requireしてやります。

require 'length_with_wide_char_validator'

そして、Sexy Validationで、最大半角文字数(:maximum)を指定。

validates :title, :length_with_wide_char => {:maximum => 100}

余談

2ヶ月ぶりにRailsを触っているので、大ボケかましてるかもしれません。