2013-09-21

Mountain Lionにアップグレード

Mountain Lionにアップグレードしたら、/etc/paths が上書きされて、brew doctorで警告が出るようになった。
$HOME/.bashrc でPATHを上書きした方が良かったかも。

2013-08-23

TinyMCEエディタにマークアップした初期値を表示

TinyMCE4で、HTMLをエディタの初期値に表示する方法。下書き保存とかした内容を再編集するさいに必要になる。
こんな感じにやればいいっぽい。

<script type="text/javascript">
        tinymce.init({
            selector: "textarea",
         });
        tinymce.on("AddEditor", function(e) {
            tinyMCE.activeEditor.on("init", function(event) {
                tinyMCE.activeEditor.setContent("<h1>見出し</h1>テキスト");
            });
        });
    </script>

djangoで使おうと思って、プラグインを導入した方がいいのか迷ったんだけど、管理者サイトで使うのでなければテンプレートでJavaScriptを編集するの良さそう。

2013-08-17

User-Agentに漢字が混ざっててエラー

djangoだと、request.META.get("HTTP_USER_AGENT", "") ってやってUser-Agentを取得できる。django1.3.1を使っているんだけど、ユニコードではなくて、バイト文字列が返されるみたい。普通はASCII文字以外は含まれていないから問題ないんだけど、中国とかベトナムからのアクセスだと、User-Agentに漢字などが含まれているものがあって、それが原因でエラーになってた。
request.META.get("HTTP_USER_AGENT", "").decode("utf-8")
ってやればたぶん大丈夫。

こんなのがある。

Mozilla/5.0 (Linux; U; Android 4.2.1; zh-cn; W1+(MT6589/4核) Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30

Mozilla/5.0 (Linux; U; Android 4.1.2; vi-vn; IM-A830K Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Điện thoạiSafari/534.30

Mozilla/5.0 (Linux; U; Android 4.0.4; zh-cn; A10双核(8DM1) Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30

Gmailの連絡先エクスポートについて

Gmailの連絡先エクスポートについての公式ヘルプはこちら。https://support.google.com/mail/answer/24911?hl=ja

エクスポートの形式は3つある。
  1. Google CSV形式
  2. Outlook CSV形式
  3. vCard形式
Google CSV形式

文字コードはUTF-8。「google.csv」という名前のファイルがダウロードされる。CSVのカラムは次のとおり。
Name
Given Name
Additional Name
Family Name
Yomi Name
Given Name Yomi
Additional Name Yomi
Family Name Yomi
Name Prefix
Name Suffix
Initials
Nickname
Short Name
Maiden Name
Birthday
Gender
Location
Billing Information
Directory Server
Mileage
Occupation
Hobby
Sensitivity
Priority
Subject
Notes
Group Membership
E-mail 1 - Type
E-mail 1 - Value
E-mail 2 - Type
E-mail 2 - Value
IM 1 - Type
IM 1 - Service
IM 1 - Value
Phone 1 - Type
Phone 1 - Value
Phone 2 - Type
Phone 2 - Value
Phone 3 - Type
Phone 3 - Value
Phone 4 - Type
Phone 4 - Value
Address 1 - Type
Address 1 - Formatted
Address 1 - Street
Address 1 - City
Address 1 - PO Box
Address 1 - Region
Address 1 - Postal Code
Address 1 - Country
Address 1 - Extended Address
Organization 1 - Type
Organization 1 - Name
Organization 1 - Yomi Name
Organization 1 - Title
Organization 1 - Department
Organization 1 - Symbol
Organization 1 - Location
Organization 1 - Job Description
Website 1 - Type
Website 1 - Value
Outlook CSV形式
文字コードはShift_JIS。contacts.csvというファイル名でダウンロードされる。カラムは次のとおり。
First Name
Middle Name
Last Name
Title
Suffix
Initials
Web Page
Gender
Birthday
Anniversary
Location
Language
Internet Free Busy
Notes
E-mail Address
E-mail 2 Address
E-mail 3 Address
Primary Phone
Home Phone
Home Phone 2
Mobile Phone
Pager
Home Fax
Home Address
Home Street
Home Street 2
Home Street 3
Home Address PO Box
Home City
Home State
Home Postal Code
Home Country
Spouse
Children
Manager's Name
Assistant's Name
Referred By
Company Main Phone
Business Phone
Business Phone 2
Business Fax
Assistant's Phone
Company
Job Title
Department
Office Location
Organizational ID Number
Profession
Account
Business Address
Business Street
Business Street 2
Business Street 3
Business Address PO Box
Business City
Business State
Business Postal Code
Business Country
Other Phone
Other Fax
Other Address
Other Street
Other Street 2
Other Street 3
Other Address PO Box
Other City
Other State
Other Postal Code
Other Country
Callback
Car Phone
ISDN
Radio Phone
TTY/TDD Phone
Telex
User 1
User 2
User 3
User 4
Keywords
Mileage
Hobby
Billing Information
Directory Server
Sensitivity
Priority
Private
Categories

vCard
文字コードはUTF-8。http://en.wikipedia.org/wiki/VCard

Proguard: can't find referenced method 'void setPluginsEnabled(boolean)' in class android.webkit.WebSettings

Androidでproguard使ってたら、こんなエラーがでた。
[2013-08-17 00:00:00 - MyApp] Proguard returned with error code 1. See console
[2013-08-17 00:00:00 - MyApp] Note: there were 3594 duplicate class definitions.
[2013-08-17 00:00:00 - MyApp] Warning: jp.co.cayto.appc.sdk.android.AppCWebActivity: can't find referenced method 'void setPluginsEnabled(boolean)' in class android.webkit.WebSettings
[2013-08-17 00:00:00 - MyApp]       You should check if you need to specify additional program jars.
[2013-08-17 00:00:00 - MyApp] Warning: there were 1 unresolved references to program class members.
[2013-08-17 00:00:00 - MyApp]          Your input classes appear to be inconsistent.
[2013-08-17 00:00:00 - MyApp]          You may need to recompile them and try again.
[2013-08-17 00:00:00 - MyApp]          Alternatively, you may have to specify the option
[2013-08-17 00:00:00 - MyApp]          '-dontskipnonpubliclibraryclassmembers'.
[2013-08-17 00:00:00 - MyApp] java.io.IOException: Please correct the above warnings first.
[2013-08-17 00:00:00 - MyApp]     at proguard.Initializer.execute(Initializer.java:321)
[2013-08-17 00:00:00 - MyApp]     at proguard.ProGuard.initialize(ProGuard.java:211)
[2013-08-17 00:00:00 - MyApp]     at proguard.ProGuard.execute(ProGuard.java:86)
[2013-08-17 00:00:00 - MyApp]     at proguard.ProGuard.main(ProGuard.java:492)


proguardの設定ファイルに、
-keep public class android.webkit.WebSettings { *;}
って追加したら直ったみたい。
たぶん、古いバージョンのAndroidでも動くように、組み込んだjarでリフレクション使ってるからエラーになったのだろう。


2013-07-26

Cordova (PhoneGap) をインストール

Cordovaのバージョン3.0.0がリリースされている。http://cordova.apache.org/

1.xの時代に試してみたことはあるけど、公開中のアプリでは利用するのは控えた。でも、いろいろ改善されてそうだし、便利そうなのでまた試してみる。

インストールには、まず、node.jsが必要。Brewを使ってMacにいれる。
$ brew install npm
その後、
$ sudo npm install -g cordova
とやってcordovaをインストール。iOSやAndroid用のアプリにするには、それぞれのSDKが必要。これはすべて既にインストールされているはず。Android用にいくつかパスを通す必要があった。どこにSDKを置いているのかによるけど、次のような感じ。
export PATH=${PATH}:/Development/adt-bundle/sdk/platform-tools:/Development/adt-bundle/sdk/tools
あと、ドキュメントには特に書かれていないみたいだけど、自分の場合は「/usr/local/share/npm/bin」にパスを通す必要があった。そうしないと、cordovaコマンドが使えない。

さて、これでインストールは完了。公式ドキュメントに即してサンプルアプリを作ってみる。
$ cordova create HelloWorld com.example.hello "HelloWorld"
これで、カレントディレクトリにHelloworldディレクトリができる。そこに移動する。
 $ cd HelloWorld
「www」って名前のディレクトリの中に、jsファイルやらhtmlファイルがある。
  $ cordova platform add android
  $ cordova platform add ios
android用と、ios用のアプリをつくれるようになった。なお、androidの方は、ちゃんとパスを通していないと次のようなエラーになる。
$ cordova platform add android
[Error: The command `android` failed. Make sure you have the latest Android SDK installed, and the `android` command (inside the tools/ folder) added to your path. Output: /bin/sh: android: command not found
]
成功するとplatformsディレクトリに、androidやiosなどの名前でプラットフォームごとにディレクトリが作られる。どのファイルをどのくらい編集していいのか、まだよく分からないけど、今日はとりあえずこのへんで。

2013-07-09

Chrome Web Storeで公開できるアプリに上限があったことに驚愕

Chrome Web Storeにアプリを公開しようとしたら、公開できるアプリの上限は20個までだと表示されて公開できなかった。そんなの初耳。

デベロッパー登録をした際には「登録手数料をお支払いいただくと、アイテムをいくつでも公開できます。再度登録手数料をお支払いいただく必要はありません」と表示されていたのに。Googleが気まぐれにルールを変えたみたい。

そもそも上限を設ける理由がよく分からない。公開済みアプリを非公開にすることが推奨されてたけど、もう一個Googleアカウントをつくって登録手数料を払ってCromeウェブストアに公開できるようにしたらどうなるんだろうか?不正行為とみなされてアカウント停止なんてのは困る。

2013-07-05

MacPortsの後継としてHomebrewを導入してさらにgettextをインストール

ディスクの空きを増やしたくてMacPortsをアンインストールした。wineとか入れててやたらと重かったし、依存関係でごちゃごちゃしすぎてわけが分からなくなったので全部消してやった。でも、そしたらGNUのgettextが動かない。当たり前か。

Djangoで多言語対応をするためにはGNUのgettextが必要だ。そこで、MacPortsの代わりにHomebrewをインストールすることにした。MacPortsもHomebrew、パッケージ管理システムだが、Homebrewの方はMacにもともと入っているパッケージをなるべくつかうようにしているため、ビルドの時間やディスクの容量を節約できるという噂だ。

インストールのためには、Xcodeがインストールされていることが前提らしい。昔っからXcodeは入っているのでこれは問題なし。
あとは、ターミナルで
$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
と打ち込む。途中でパスワードを聞かれたから教えてあげた。
次のような出力があった。
$ ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
==> This script will install:
/usr/local/bin/brew
/usr/local/Library/...
/usr/local/share/man/man1/brew.1
==> The following directories will be made group writable:
/usr/local/.
/usr/local/bin
/usr/local/share
==> The following directories will have their group set to admin:
/usr/local/.
/usr/local/bin
/usr/local/share

Press ENTER to continue or any other key to abort
==> /usr/bin/sudo /bin/chmod g+rwx /usr/local/. /usr/local/bin /usr/local/share
Password:
==> /usr/bin/sudo /usr/bin/chgrp admin /usr/local/. /usr/local/bin /usr/local/share
==> Downloading and Installing Homebrew...
remote: Counting objects: 119077, done.
remote: Compressing objects: 100% (57206/57206), done.
remote: Total 119077 (delta 83061), reused 94319 (delta 60911)
Receiving objects: 100% (119077/119077), 18.97 MiB | 326 KiB/s, done.
Resolving deltas: 100% (83061/83061), done.
From https://github.com/mxcl/homebrew
* [new branch] master -> origin/master
HEAD is now at 4c74e09 fish: don't search extra folders for libiconv
==> Installation successful!
You should run `brew doctor' *before* you install anything.
Now type: brew help

最初に、ターミナルで「$ brew doctor」を実行しろって書いてある。やってみると次のような警告が出た。
Warning: /usr/bin occurs before /usr/local/bin
This means that system-provided programs will be used instead of those
provided by Homebrew. The following tools exist at both paths:
[省略]
Consider amending your PATH so that /usr/local/bin
occurs before /usr/bin in your PATH.
Homebrewもシステムと重複するプログラムとインストールすることもあるってことかな。とりあえず放ったらかし。

肝心なのは、gettextを入れること。インストールは「$ brew install なんちゃら」でいける。
$ brew install gettext
==> Downloading https://downloads.sf.net/project/machomebrew/Bottles/gettext-0.18.2.lion.bottle.tar.gz
######################################################################## 100.0%
==> Pouring gettext-0.18.2.lion.bottle.tar.gz
==> Caveats
This formula is keg-only: so it was not symlinked into /usr/local.

OS X provides the BSD gettext library and some software gets confused if both are in the library path.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

LDFLAGS: -L/usr/local/opt/gettext/lib
CPPFLAGS: -I/usr/local/opt/gettext/include

==> Summary
🍺 /usr/local/Cellar/gettext/0.18.2: 366 files, 11M

これでGNU gettextがインストールできた。しかし、「which gettext」とやっても何もでてこない。パスが通ってないからだ。
インストールのときの出力を見ると、OS XのBSD gettextと競合するかもしれないっていう配慮でパスを通していないようだ。こんな情報も見つけた。https://github.com/mxcl/homebrew/issues/8461

パスを通すには、「$ brew link --force gettext」とやる。いまは「--force」を忘れちゃダメみたい。

Djangoで静的ファイルを配信する

settings.pyの設定項目として、MEDIA_URL、MEDIA_ROOT、STATIC_URL、STATIC_ROOT、STATICFILES_DIRSなどがある。昔は、STATICなんちゃらという設定項目は存在しなかったと思う。しかし現在は、MEDIAなんちゃらはユーザがアップロードするファイルの保存と配信についての設定項目で、STATICなんちゃらは開発者があらかじめアップロードしておく静的ファイルの保存と配信のための設定という使い分けがされている。だから、MEDIAなんちゃらとSTATICなんちゃらを同じ値にしてはいけない。

さて、STATIC_URLは、静的ファイルをhttpで配信するときのURLの設定になる。templateのなかでは、{{STATIC_URL}} とやればその値を参照できる。たとえば、STATIC_URL='/static/'; という具合に設定する。

STATIC_URLを指定しても、実は、Djangoは静的ファイルの配信をまったくやってくれない。静的ファイルの配信はWebサーバーの仕事で、Djangoの仕事ではないから、というのがその理由だ。だから、ApacheならApacheを適切に設定してやらないといけない(Djangoの開発用サーバーを使っている場合については後述)。STATIC_URLは、Webサーバーの設定をやり易くしてくれるだけのものだ。

静的ファイル配信のためのWebサーバーの設定を簡単にするために大切なことは2つある。
ひとつは、URLが統一されていること(STATIC_URL)。
もうひとつは、配信する静的ファイルが同じディレクトリにまとめられていることだ。
どこにファイルをまとめることになるのかというと、STATIC_ROOTに設定したディレクトリの下だ。ファイルをまとめるにはツールをつかう。コンソールで「python manage.py collectstatic」を実行すれば、静的ファイルをいろんな場所から、STATIC_ROOTで指定した場所に集めてくれる。
すでに存在するファイルがあるときは、上書きしていいか「yes」か「no」で答えろと迫られる。処理を自動化したい場合は、「python manage.py collectstatic --noinput」としておけば黙って上書きしてくれる。

なんでcollectstaticするのかというと、アプリが複数個あったりプラグインを追加していたりして静的ファイルがいろんなところに散らばっているからだ。
では、collectstaticしたときに、どのディレクトリのファイルを集めてくるか?
ひとつは INSTALLED_APPSで指定したアプリのstaticディレクトリ。
あと、STATICFILES_DIRSに追加指定したディレクトリも対象となる。STATICFILES_DIRSには、タプルで複数の場所を登録できる。

Webサーバーの設定だが、Apacheの場合は、次のような感じだろう(仮に、STATIC_ROOT='/var/www/django/myproject/staticfiles/';とする)。
Alias /static/ /var/www/django/myproject/staticfiles/
<Directory /var/www/django/myproject/staticfiles>
    Order deny,allow
    Allow from all
</Directory>
Djangoの開発サーバーの場合は、urls.pyに、
from django.conf.urls.static import static
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
とやっておけば大丈夫だと思う。

2013-07-04

jQueryMobileで横すべりに半開きになるメニューを追加

最近スマホアプリでよく見かけるメニューの表示方法、ボタンを押すと横からメニューがニュッと出てくるやつ、これをjQueryMobileで実装するにはPanelを使う。

以前につくったページにPanelを追加したら、contentがカラム落ちしてしまうという問題が発生した。なんでだろうと思って調べたら、<div data-role="content"/>要素を記述し忘れていて、<div data-role="page"/>の直下に表示内容を記述していたことが原因だった。これまで正常に動作していたことがむしろ不思議だ。

2013-07-01

Android Developer Tools (ADT) とSDKをダウングレード

ADT (Android Developer Tools) をバージョン22に更新したら、ビルドがうまくいかなくなった。ADTに合わせて、SDK Toolsもr22に更新していた。そして、問題が発生。

Proguardを使うと、クラスが見つからなくてエラーが連発してビルドできない。Proguardなしだとビルドは成功するが、しかし実行しようとしたときに落ちる。タイミング悪く、バグの報告がきた。早く修正したアプリをアップロードしたいが、ADTを更新したせいでビルドが成功しない。困った。

仕方がないのでバージョン21.1.0にダウングレードすることにした。

古いバージョン21.10のADTは次のリンクからダウンロードできる。
http://dl.google.com/android/ADT-21.1.0.zip
21.1.0というバージョンの部分を書き換えれば、他のバージョンもダウンロードできるはず。過去にどんなバージョンがリリースされていたかは、ここでチェックできる。

昔のSDKについては、使っているOSに合わせて以下のいずれかからダウンロードする。
https://dl.google.com/android/android-sdk_r21.1-macosx.zip
https://dl.google.com/android/android-sdk_r21.1-windows.zip
https://dl.google.com/android/android-sdk_r21.1-linux.tgz
こちらも、別のバージョンをダウンロード可能。過去のバージョンはここで参照できる。

2013-04-07

PCH file built from a different branch ((clang-425.0.24)) than the compiler ((clang-425.0.27))

Xcodeを4.6.1にアップデートしてビルドすると、
 PCH file built from a different branch ((clang-425.0.24)) than the compiler ((clang-425.0.27))
とかいうエラーになった。

[Product]メニューから[Clean]を選択して、再ビルドすると成功した。

しかし、ビルドの設定を変えた方がいいという警告が出ていた。詳細はよく分からないまま、Xcodeの言いなりで[Perform Change]を行った。たぶんこれで問題ないと思う。

AppStoreでXcodeをアップデートできない

AppStoreアプリでXcodeをアップデートしようとすると、「ほかのアカウントで使用可能なアップデートがあります」「このアプリケーションをアップデートするには、購入時に使用したアカウントでサインインしてください」というメッセージが出て、アップデートができないで困った。

ネットで検索すると、Spotlightのインデックスを再構築をするとアップデート可能になるという情報があったので試してみたのだが、これにインデックスの再構築に数時間かかった上にアップデートできないままだった。

Xcode.appをゴミ箱に入れて再インストールすることで解決できた。再インストールは、AppStoreアプリから行える。