2016-05-11

iOSのSafariとUIWebViewでspeechSynthesis.getVoices()が空っぽ

JavaScriptで、speechSynthesis.getVoices() とやれば、テキストを音声読み上げするときに設定するvoiceのリストが返ってくるはずなんだけど、iOSだと空っぽのemptyリストが返ってきてしまう。実際には、音声読み上げ可能なはずなのに、空っぽ。iOSのバージョン9.2でしかチェックしていない。

さあ困った。どうする?

予想としては、Objective-Cのコードで  [AVSpeechSynthesisVoice speechVoices]; とやったときに取得できるvoiceは利用可能なのでないかと思う。

実際に試してみる。やっぱりそうみたい。利用可能なのはこんな感じ。(ここから転載

LocaleLanguage/Country
ar-SAArabic (Saudi Arabia)
en-ZAEnglish (South Africa)
th-THThai (Thailand)
nl-BEDutch (Belgium)
en-AUEnglish (Australia)
de-DEGerman (Germany)
en-USEnglish (United States)
pt-BRPortuguese (Brazil)
pl-PLPolish (Poland)
en-IEEnglish (Ireland)
el-GRGreek (Greece)
id-IDIndonesian (Indonesia)
sv-SESwedish (Sweden)
tr-TRTurkish (Turkey)
pt-PTPortuguese (Portugal)
ja-JPJapanese (Japan)
ko-KRKorean (Korea)
hu-HUHungarian (Hungary)
cs-CZCzech (Czech Republic)
da-DKDanish (Denmark)
es-MXSpanish (Mexico)
fr-CAFrench (Canada)
nl-NLDutch (Netherlands)
fi-FIFinnish (Finland)
es-ESSpanish (Spain)
it-ITItalian (Italy)
ro-RORomanian (Romania)
no-NONorwegian(Norway)
zh-HKChinese (Hong Kong)
zh-TWChinese (Taiwan)
sk-SKSlovak (Slovakia)
zh-CNChinese (China)
ru-RURussian (Russia)
en-GBEnglish (United Kingdom)
fr-FRFrench (France)
hi-INHindi (India)

var msg = new SpeechSynthesisUtterance("てきすと");
msg.lang = "ja-JP";
speechSynthesis.speak(msg);

のように地域コードつきでlangを指定する。言語コードだけ指定して、msg.lang = "ja"; とやるのではダメみたい。

2016-05-04

HTML5のバリデーションチェックを使うのやめた

翻訳コンニャクで、HTML5のバリデーション(checkValidityなど)を利用してみたのだが、ブラウザごとの挙動にばらつきがありすぎて使いにくい。これから書き直して、サーバーサイドのチェックだけにする予定。

特に、Safariの挙動が制御しにくい。checkValidityは動くし、validationMessageも設定されているのだが、それにもかかわらずポップアップでエラー表示が行われない。Safariのためにゴチャゴチャ処理を書くとわけわからないことになりそう。

Safariは、executeCommandも動かないし、最近のIEよりも扱いにくい。

2016-03-09

Gitでハードリンクしたファイルを管理するのはやめたほうがいい

たぶん、checkoutしたときなどにファイルの上書きが起こって、そこでリンクが切れてしまうということなのだろう。いつの間にかリンクが切れてた。

シンボリックリンクだとメタ情報がコミットされるだけだし、ハードリンクだといつの間にかリンクが切れる。やっぱり、リンクとgitを組み合わせて使うのは良くなさそう。

サブモジュールとかいう機能を使うのと面倒くさくなりそうだし、どうしようかなー。

2016-02-25

django.db.utils.ProgrammingError: relation "auth_group" does not exist

Djangoで、manage.py test をしたら、
django.db.utils.ProgrammingError: relation "auth_group" does not exist
とかいうエラーになって困った。開発環境のmacの上では起こらないんだけど、Ubuntu Server14.04で起こる。データベースはPostgreSQL。

何だろうっていろいろ調べたけど、ここが答えをくれた。 次のように言ってる人がいた。
Did you run python manage.py makemigrations appname first, where "appname" is the name of the app containing your custom user model inheriting from AbstractUser?
AbstractUserを定義しているappnameを指定して、makemigrationsをしたら解決。モデルがちゃんとつくられていなかったみたい。そういえば、DBをflushした後、これを実行するの忘れてたかも。

migrationのテーブルに不完全なデータしかない状態で、テスト用のテーブルを作成しようとしてエラーになっていたということだろうか。

外付けUSBメモリをexFATでフォーマットしたらタイムカプセルできなかった

MacBookのディスクに空きがなくなって困ったので外付けのUSBメモリを買った。親指の爪くらいの小ささで、出っ張らないやつを挿しっぱなしにする計画。

で、外付けUSBのフォーマットについてなんだけど、USBメモリはデフォルトではFATで、これだと大きいサイズのファイルを扱えないかった。exFATにフォーマットしたら、Windowsパソコンともデータを共有できていいんじゃないかと思った。いまはVirtualBoxの中にしかWindows入ってないけど、そのうちWindowsのパソコンも買うかもしれないから、そのときに便利なようにという配慮。

しかし、exFATにはタイムカプセルでバックアップをとれないという落とし穴があった。バックアップはとっておきたい。小さなUSBメモリは嬉しいんだけど、なんかそのうち壊れたりするんじゃないだろうかって不安になる。

ということで、データを一時的に退避させて「Mac OS 拡張(ジャーナリング)」ってやつにフォーマットしなおすことにした。「Mac OS 拡張(大文字/小文字を区別、ジャーナリング)」というのもあるけど、大文字/小文字は区別しないのが普通みたい。実際のところ、Max OSXでは、大文字/小文字が異なるだけで同じ名前のファイルを作成できない。というわけで、大文字/小文字を区別しない方の「Mac OS 拡張(ジャーナリング)」にフォーマットするのが無難な選択のようだ。

もう再フォーマットはしたくない。けど、USB3.0はなかなか速い。

2016-02-17

DjangoでModelFormのカスタマイズ

DjangoでModelFormを使っていて、FormFieldを追加するとき。Modelのinstanceとの値のやりとりをどうしようか迷う。どうやら、初期値はModelFormの__init__()でモデルからフォームに渡してやり、フォームからモデルへの値の変更はModelFormの_post_save()でやるのが良さそう。

理解可能なように説明すると面倒くさいからできそうにない。

class ArticleForm(forms.ModelForm):
 
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.fields["text"].initial = self.instance.get_nice_text()
    
    def _post_clean(self):
        super()._post_clean()
        self.instance.set_nice_text(self.cleaned_data["text"])


という感じだといいのではないか。

2016-02-12

django-allauthを使ってTwitterアカウントでログイン

django-allauthを使って、Twitterアカウントでログインする機能を追加しようとしている。いくつか注意点。

django-allauth側の設定としては、settings.pyでの設定と、Webの管理画面でのDBの設定と二つやらないとダメ。管理画面では、social applicationsのとこでサイトIDを忘れずにと追加してあげないといけない。

Twitter側の設定としては、Callback URLを指定していないと、Twitterでログインする機能を利用できないでエラーになる。「Allow this application to be used to Sign in with Twitter」っていうのにチェックを入れていても、それだけじゃダメ。




ちなみに、Twitterにウェブアプリを登録しようとしたんだけど、現時点では日本語ドメインに対応していないみたい。punycodeでもダメ。不正はURLとして扱われる。

2016-02-11

Ubuntu14.04でDjangoを複数動かす

Apache2.4のVirtualHost、python3.4のvenv、mod_wsgiのdaemon mode、これらを使った。手順というよりも注意点を書き留めておく。

Ubuntu14.04では、python3のvenvが失敗するという情報があったけど、大丈夫だった。venv(もしくはpyvenv)は、「apt-get install python3.4-venv」でインストールしないといけない。
venvが失敗するというのは、ensurepipモジュールが欠けていて、pipがインストールされないとのことだった。その場合に、手動でpipをインストールすれば良いとかいう情報もあった(手動でpipをインストールした場合、apt-getからインストールしたpython3-psycopg2とかpython3-lxmlとかへのパスが通っているのかは謎)。しかし、問題なくvenvを実行できた。

仮想環境をつくるときは、pyvenvではなく、python3 -m venv を呼び出すクセをつけておいた方が良さそう。複数のバージョンのpython3が入っている場合に、どのpython3を使ってvenvを実行するのかで、仮想環境で使うpythonのバージョンを選択できるからだ。pyvenvだとこれができない。

とはいえ、mod_wsgiを動かすpythonのバージョンを細かく指定することは、たぶんできない。だから本番のサーバーではpyvenvを使おうがvenvを使おうが同じことだ。

仮想環境をつくるときは、「python3 -m venv --system-site-packages --symlinks 仮想環境ディレクトリへのパス」という具合にオプションを与えておくと、activateしたときに、mod_wsgiを動かすときに近い環境になるはず。--upgradeを付けとけば、失敗してもやり直せる。(--upgrade なしでもやり直せそう。あと、--symlinks はデフォルト値だから省略していい。)

activateするには、「source 仮想環境ディレクトリへのパス/bin/activate」。 activateした後でsudoすると、環境変数が上書きされてしまうのでやってはいけない。たとえば、activateした後で「sudo pip install django」とやると、デフォルトのpython2のsite-packagesにdjangoがインストールされてしまう。そうならないように「sudo -s」としてから、activateする。で「pip install django」とやれば、仮想環境のsite-packagesにインストールされる。



2016-02-10

Apache2.4でBasic認証の設定が効かないで困った

Apache2.4で、Basic認証を設定しようとしたんだけど、普通にアクセスできてしまって困った。Apach2.2では動作していた設定を、ほとんどそのままコピーしたつもりだったのに、何がいけないんだか悩んだ。

Basic認証のために「Require valid-user」と設定したかったのに、「Require all granted」が前の方に書かれていて、これが効いてしまっていたのが原因だった。

2016-02-08

Ubuntu Serverでapache2の設定変更が反映されないで困った

Ubuntu Serverでapache2の設定変更が反映されないで困っていた。
a2ensiteやらa2dissiteやらで設定するのに慣れていないため、どこかにミスがあるのだろうと長時間にわたり試行錯誤。

結局のところ、
service apache2 restart
とコマンドを打つところで、sudo を忘れていただけだった。「 * Restarting web server apache2」というメッセージが出るだけだったから、権限で失敗していることに気づかずに、履歴から同じコマンドを叩きまくっていた。

なお、「apachectl restart」なら、「Permission denied」って失敗のメッセージが出る。ただし、このコマンドだと成功したときには何もメッセージが出ないから不安になる。「echo $?」とやって、戻り値が0なら成功、それ以外なら失敗と判断することもできるが。

2016-02-07

Ubuntu Server 14.4 で sshd -t するとエラーが出るんだけどこれは何だろう?

sshd -t は、/etc/ssh/sshd_config の設定内容などをテストしてくれるコマンドだ。Ubuntu Server 14.4 で実行してみたら、こんなエラーが出るんだけど何でだろう?
# sshd -t
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/etc/ssh/ssh_host_ed25519_key' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /etc/ssh/ssh_host_ed25519_key
Could not load host key: /etc/ssh/ssh_host_ed25519_key
ssh_host_ed25519_keyは、秘密鍵のファイル名だけど、パーミッションを調べたら、
-rw-r--r--  1 root root
となっていて誰でも読めてしまう状態になっていた。だから、
# chmod 600 ssh_host_ed25519_key
ってやったらエラーは出なくなった。けど、なんでパーミッションがこんな状態になっていたのかよく分からない。

2016-02-06

VirtualBoxのUbuntu Serverに固定IPアドレスを設定する

VirtualBoxで、IPアドレスを固定する方法。設定 > ネットワーク > アダプター2 に、ホストオンリーアダプターを割り当てることを前提にして、以下のようにやってみた。

CentOSの場合は、root 権限で、/etc/sysconfig/network-scripts/ifcfg-eth1 というファイルを作成して次のように書き込む。(なお、HWADDR= の後はMACアドレスなので、設定 > ネットワーク > アダプター2 などで割り当てられている値を確認する。)
DEVICE=eth1
TYPE=Ethernet
ONBOOT=yes
BOOTPROTO=static
HWADDR=08:00:27:FD:1A:54
IPADDR=192.168.56.9
NETMASK=255.255.255.0
NETWORK=192.168.56.1
それから、コマンドラインで
$ sudo service network restart
とする。
もっと丁寧には、ここらへんが参考になる。http://qiita.com/boscoworks/items/56d2ab2a9c5b1b100ce6


Ubuntu Serverで、これに相当することをやるとどうなるか。

まず、root権限で、/etc/network/interfaces の末尾に次のように書き込む。
auto eth1
iface eth1 inet static
address 192.168.56.10
netmask 255.255.255.0
 で、コマンドラインで、
$sudo /etc/init.d/netwok restart 
もしくは、
$ sudo /etc/init.d/networking restart
 とやる。Ubuntuはこうしないと、そもそもホストオンリーアダプターのときにホストから接続できないっぽい。
ちなみに、手元のスマホからVirtualBox上のサーバーにアクセスしたいときには、ホストオンリーアダプターでは駄目で、ブリッジアダプターを使うことになる。

Macで特定のユーザーをログイン画面から消したい

Macで特定のユーザーを、ログイン画面に表示しないようにする方法がある。https://support.apple.com/ja-jp/HT203998

PostgreSQLをインストールしたときに、PostgreSQL用のユーザーを作った。しかし、それがログイン画面に出てくるのが鬱陶しいので消したい。ユーザーを削除したいわけではなくて、ログイン画面に表示されないようにしたいだけ。 次のコマンドで非表示にできるはず。(「postpres」のところは、非表示にしたいユーザー名)
sudo dscl . create /Users/postgres IsHidden 1
  このコマンドを打った後で、ログインウィンドを開いたら、ちゃんとユーザーが消えている。

2016-02-05

ApacheのVirtualHostの設定で、ServerNameにもServerAliasにもヒットしない場合

ApacheのVirtualHostの設定で、ServerNameにもServerAliasにもヒットしない場合は、最初に設定されたVirtualHostが使われる。このことは公式ドキュメントにも書いてある。
リクエストが来ると、サーバはまず最初に <NameVirtualHost> にマッチする IP アドレスかどうかをチェックします。マッチすれば マッチした IP アドレスの <VirtualHost> のそれぞれのセクションの中から ServerNameServerAlias に要求されたホスト名があるか探します。 見つかればそのサーバ用の設定を使います。マッチするバーチャルホストが見つからなければ、マッチした IP アドレスの リストの最初にあるバーチャルホスト が使われます。
 思ったように動いてくれないと思ったら、設定ミスってて
「見つからない場合は、リストの最初にバーチャルホストが使われる」っていうルルールが効いていた。

あと、複数のDjangoをVirtualHostを使って動かす場合は、mod_wsgiで、daemon modeってやつにしないといけない。これの設定がちょっと大変。

2016-02-04

MacのApp Store設定で「新しいアップデートをバックグラウンドでダウンロード」はOFFっとく

WindowsからMacに切り替えてずいぶん長いこと経つ。もうWindowsの使い方は忘れてしまった。けど、まだMacのことがよく分からないときがある。

今回失敗したのは、App Storeの自動アップデート関連。システム環境設定 > App Store で設定するやつ。「アップデートを自動的に確認」をONにしていたのはいいんだけど、「新しいアップデートをバックグラウンドでダウンロード」もONにしていたのが良くなかった。

モバイルルータでインターネットに接続しているのにも拘らず、4ギガ以上あるXcodeをアップデートしようとバックグラウンドでずっと動いていた。で、ファイルが大きすぎて途中でエラーになる。この繰り返し。モバイルルータの通信容量の制限をオーバーしてしまいそうな勢い。今月は始まったばかりなのに。

というわけで、モバイルルーターを使うのなら、 「新しいアップデートをバックグラウンドでダウンロード」はオフっておいたほうが良い。そうすると、「自動アップデートをONにしますか」ってよく尋ねられるけど、断る。

2016-02-02

mkvirtualenvのとき --always-copy しておきたい

Macで、virtualenvwrapperというのを使って、複数バージョンのpythonを管理している。プロジェクトごとにsite-packageを管理できたりして便利なやつだ。
これで仮想環境をつくるとき、
mkvirtualenv --python=python3 --always-copy project_name
みたいに引数に、--always-copy を入れておくと良さげ。

というのは、MacでHomeBrewを使ってPythonを入れていると、古いバージョンのPythonがなくなって困る可能性があるから。