2015年7月20日月曜日

[MovableType] [Data API] [Perl] 画像タイプのカスタムフィールドを持つエントリーをData APIを使って投稿する


MovableTypeで画像タイプのカスタムフィールドを持つエントリー(記事)をData APIを使って投稿する方法について(しかもPerlで)

これを実現するには、
1.画像をData APIを使ってアップロードし、アイテム(Asset)に登録する
2.エントリーをData APIを使って投稿する際に、1で登録したアイテムを紐付けて登録する
という手順が必要です。

サンプルを見るのが一番わかりやすいと思いますので、次にコードを提示します。

(私的)ハマりポイントは次の通り。

1.画像をアップロードする場合にはX-MT-Authorizationでトークンを渡すだけでなく、Content-Type: multiple/form-dataも渡す必要がある。boundaryとか自力でやろうとするとこれは大変なので、HTTP::Request::CommonのPOSTメソッドを使いました。POSTメソッドにて、POST(url, Content_Type => 'form-data', ... );とすることでHTTP::Request::Commonがboundaryも含めたヘッダをよしなに処理してくれます。POSTメソッドへの引数がContent-Typeではなく、Content_Typeになっていることに要注意です。

2. 画像の実体の指定もHTTP::Request::CommonのPOSTメソッドを利用すれば、Contentパラメータ内で['ファイルのパス']とすることで処理してくれます。自力でファイルを開いたり(binmode指定して頑張ったりもして)、IO::Fileオブジェクト作って渡してみたり、色々やってみましたが、これらの方法はうまくいきません。

3.画像タイプのアセットを記事に紐付けて、編集画面にも埋め込んで表示するには、サンプルの通り、
 sprintf(qq{<form mt:asset-id='%d' class='mt-enclosure mt-enclosure-%s' style='display: inline'><a href="%s"><img src="%s"/ width="500"></a></form>}, $json->{id}, $json->{class}, $json->{url}, $json->{url})
というように、formタグの中にimgやaタグを組み込んだ値を指定します。style='display: inline;'というように';'を含んだ値を渡すとJSONモジュールがエラー吐いて死にますので、外します。formの他の属性はおまじないだと思ってください。

参考:
 MovableType Data API v2
 HTTP::Request::Common
 実装メモ:Movable Type 6の便利なData APIを利用して画像を出力する : アークウェブのブログ
 

2015年7月19日日曜日

[ImageMagick] 縦長画像のみ90度回転して表示される問題を解決する

昨今のデジカメやiPhoneなどで撮影した画像をWebにアップすると縦長画像が90度回転して表示されてしまう問題に遭遇しました。画像のExif情報が悪さしている模様です。

全てが縦長の画像であれば対処は単純なのですが、横長と混在している状態だとどうしたらいいの?ってなります。が、ご安心。ImageMagickに素敵なオプションがありました。
auto-orientです。次のように使うと、縦長の画像だけ判定して90度回転してくれます。


[ImageMagick] 画像のリサイズ(圧縮率変更)、サムネイルを作成する

大量の画像のリサイズ(圧縮率変更)、サムネイルの作成はImageMagickのconvertコマンドを使って次のように簡単に行えます。画像の縦横比もキープされます。(Linux、MacOSX環境)

参考:
 第102回 ImageMagickでコマンドラインから画像加工:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
 ImageMagickでいろいろなサムネイル画像作成に挑戦

2015年7月10日金曜日

[Google Account] Google Accountからプログラムでログアウトする方法

Google Accountからプログラムでログアウトする方法が検索してもなかなか見つからなかったのでメモっておきます。といってもやることは単純。とあるURLにプログラムでHTTPアクセスするだけです。PHPだと次のようになります。



ログアウト後の戻り先のURLをgetパラメータcontinueに与えるのをお忘れなく。

2015年7月7日火曜日

[Android] アクティビティの多重起動を防ぐ

Serviceを使ってマルチスレッドからActivityを呼び出す(startActivity())ことをやっていると、Activityが多重起動してしまいErrorが生じてしまうケースがあります。(スレッドセーフに作られているActivityならいいのですけどね)。

このケースの解決方法として、アクティビティの多重起動を防ぐという方法があります。やり方は簡単で、AndroidManifestで多重起動を防ぎたいアクティビティのactivityタグでandroid:launchMode="singleInstance"を指定するだけです。
記述例は次の通り。

参考:
 プログラムの多重起動と連続起動について - fの備忘録

2015年5月24日日曜日

[Android] In-app Billing v3を使ってライセンス購入を実装する

Androidアプリでアプリ内課金を行う場合、Google Play In-app Billingを使ってGoogle Playに決済を任せる設計が一般的&楽です。

アプリ内課金には、スポット課金(一度きりの購入)と定期購読(繰り返し自動課金)を使うことができ、スポット課金を利用するとアプリのライセンス購入を表現することができます。

最初は、無料でダウンロードしてもらって使ってみてもらい、気に入ったらライセンスを購入してもらって、加えていた制限(例えば利用期限だったり、機能制限だったり、広告非表示だったり、色々)を解除することが可能というわけです。

このアプリ内課金を実装するための手順は次の記事が参考になります。

Androidのアプリ内課金IABv2のサービス終了と新しいIABv3への移行方法 - Qiita

基本的には、挙げた記事の通り、環境を作って、Googleが提供しているサンプルを取り込んでゴチャゴチャやればOKなのですが、今後はシンプルにやりたいと思いましたので(=今回は初めててで結構苦戦しました)、ライセンス管理を行うユーティリティクラスをGoogleのサンプルをベースに作りましたのでGitHubで公開しておきます。ライセンスはMITです。

https://github.com/shinchit/LicenseManager

使い方は、次の通りです。



onActivityResultメソッドでは、特に購入処理の実行結果によってなんらかの処理を行う必要がなければ、シンプルにスーパークラスのonActivityResultに処理を転送すればOKです。

あと、実装以外にもライセンス購入の組み込みには色々と落とし穴もあるので、次の記事も必読です。

アプリ内課金の実機テストのワナ - GADGET FACTORY 雑記帳


2015年4月19日日曜日

[JavaScript] [jQuery] 任意の年月の月末日を得る

年、月、日のプルダウンが存在していて、年、月が選択されたタイミングで日のプルダウンの値を更新する仕組みを考えます。この時、日の月末日は閏年の判定も含めて、年、月の値に応じて変化させる必要があります。

このために、任意の年月の月末日を得る必要があります。例を示します。



例では、任意の月末日を得たのち、年、月のプルダウンが変化(change)するタイミングで、その時の年、月の組み合わせで月末日(endDay)を求めて、この値を使って動的に日のselectのoption要素を動的に生成しています。

参考
 JavaScript による日付・時刻・時間の計算・演算のまとめ – hoge256 blog