あひる焼きfortune

この記事は あひる焼き Advent Calendar 2015 – Adventar の12月05日分の記事です.

みんなでまったり #あひる焼き すればええんじゃないかなと思います。

ということで最近焼いたあひるの話を.

発端

fortune というフォーチュンクッキーのような格言をランダムに表示するプログラムがあります.様々な辞書データが存在していて自作も出来ます.

pi@raspberrypi ~ $ sudo apt install fortunes            # fortuneの導入
pi@raspberrypi ~ $ fortune                              # fortuneの実行
Some of us are becoming the men we wanted to marry.
                -- Gloria Steinem
pi@raspberrypi /tmp $ cat <<__EOF__> data               # fortuneのデータ作成
テスト
%
1行目
2行目
%
__EOF__
pi@raspberrypi /tmp $ strfile data                      # データ変換
"data.dat" created
There were 2 strings
Longest string: 16 bytes
Shortest string: 10 bytes
pi@raspberrypi /tmp $ ls data*
data  data.dat
pi@raspberrypi /tmp $ fortune data                      # 自作データを利用
1行目
2行目
pi@raspberrypi /tmp $ fortune data
テスト

その辞書データに @ahiru3netさんのあひる焼きに対するmentionを使うと楽しいかもしれないと思いました.でもデータを集めるのが面倒だなとつぶやいたところ @shimadahさんにGitHub を教えてもらいました.

それを元にコネコネして……うまくいかないところに@ahiru3netさんの助言.

焼けた

やってることはahiru_yakunaプラグインのmentionのデータをもらってきて乱暴にfortuneで利用できる形式に変換して~/.zshrc に登録してログイン時に台詞を出すようにしています.

mkdir ~/.fortune;wget -O - https://github.com/Na0ki/ahiru_yakuna/raw/master/config.yml|grep ^\-\ \" | sed 's/^-\ \"//'| sed 's/"$/\n%/' | sed 's/\\n/\n/g' > ~/.fortune/ahiruyaki && strfile ~/.fortune/ahiruyaki ~/.fortune/ahiruyaki.dat && echo fortune ~/.fortune/ahiruyaki >> ~/.zshrc

これでログインのたびに以下のようにメッセージが表示されるようになりました :)

焼いちゃうのか?!本当に焼いちゃうのか?!
pi@raspberrypi ~ $

もっと焼く

でもメッセージだけだとちょっとさみしいです.
そこで cowsay を使ってみます.cowsay はアスキーアートで書かれた牛などのキャラクタに指定した台詞を喋らせることの出来るプログラムです.都合のいいことに選択できるキャラクタの中にあひるがいます.あひるに喋ってもらいましょう!

pi@raspberrypi ~ $ sudo apt install cowsay                  # cowsay 導入
pi@raspberrypi ~ $ cowsay hello cow                         # cowsay 実行
 ___________
< hello cow >
 -----------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
pi@raspberrypi ~ $ cowsay -f duck hello duck                # あひるに喋らせる
 ____________
< hello duck >
 ------------
 \
  \
   \ >()_
      (__)__ _
pi@raspberrypi ~ $ cowsay -f duck あひる焼き                 # 日本語を喋らせる
 _______
< あひる焼き >
 -------
 \
  \
   \ >()_
      (__)__ _

日本語を喋らせると吹き出しがずれてしまいます.あひる焼きの台詞の殆どは日本語なのでこのままではまずいです.調べてみるとバグレポートされていました.

中国語?もやっぱりずれちゃうみたいです.
文字数と見た目のキャラクタの文字数のズレから起こっているようです.とりあえず日本語だけでも動くように出来ないかと euc-jp に変換して文字数を確認してといったダメな修正をしていたところGoogle+の以下の投稿のコメントで +Masakazu Takahashiさんがさくっとパッチを作ってくれました!

このパッチは報告しましたが,取り込まれてもstretch以降でしょう.ということでDebianだと以下のようにしてソースを入手してパッチを当てることが出来ます.

pi@raspberrypi ~/src $ sudo apt install libtext-charwidth-perl      # 必要なパッケージの導入
pi@raspberrypi ~/src $ apt-get source cowsay                        # cowsay の source 入手
pi@raspberrypi ~/src $ cd cowsay-3.03+dfsg1                         # ディレクトリ移動とパッチ適用
pi@raspberrypi ~/src/cowsay-3.03+dfsg1 $ wget -O - https://gist.githubusercontent.com/emasaka/639a9168c6a9ddba044f/raw/1a55ec58ded59b3181f1721dbbe814a38d5ea4cb/cowsay-mbswidth.patch | patch -i -
patching file cowsay
pi@raspberrypi ~/src/cowsay-3.03+dfsg1 $ ./cowsay -f duck あひる焼き
 ____________
< あひる焼き >
 ------------
 \
  \
   \ >()_
      (__)__ _

~/bin 辺りにコピーして使ったり,以下のような感じで既存のパッケージを置き換えてしまってもいいかもしれません.

pi@raspberrypi ~/src/cowsay-3.03+dfsg1 $ vi debian/control
- Depends: ${misc:Depends}, ${perl:Depends}
+ Depends: ${misc:Depends}, ${perl:Depends}, libtext-charwidth-perl
pi@raspberrypi ~/src/cowsay-3.03+dfsg1 $ dpkg-buildpackage -b
pi@raspberrypi ~/src/cowsay-3.03+dfsg1 $ sudo debi

さて,fortuneのことを忘れてしまいそうですが以下のようにしてあひる焼きfortuneの結果をあひるに喋らせます.

pi@raspberrypi ~ $ cowsay -f duck `fortune ~/.fortune/ahiruyaki`
 ______________
< ヒッヒッヒッ >
 --------------
 \
  \
   \ >()_
      (__)__ _

いい感じです :)

~/.profile 辺りに登録しちゃいましょう.aliasも設定してみます.

pi@raspberrypi ~ $ echo 'alias a="fortune ~/.fortune/ahiruyaki | cowsay -f duck"' >> ~/.profile 
pi@raspberrypi ~ $ echo a >> ~/.profile

これでlogin時や a と入力することで実行されます.

Last login: Fri Dec  4 23:32:05 2015 from 192.168.2.210
 ________________________________________________________________________________
/ あひる焼きというものには鮮度があります。焼けば焼くほどに、あひる焼きとは廃れて \
\ いくものなのです。                                                             /
 --------------------------------------------------------------------------------
 \
  \
   \ >()_
      (__)__ _
pi@raspberrypi ~ $ a
 ________________________
< バーニング通帳!!!! >
 ------------------------
 \
  \
   \ >()_
      (__)__ _

Xでも焼く

GUI の X 版のcowsayも存在します.こいつも試してみましょう.

pi@raspberrypi ~ $ sudo apt install xcowsay
pi@raspberrypi ~ $ xcowsay `fortune ~/.fortune/ahiruyaki`

https://www.flickr.com/photos/119142834@N05/23490968856/in/dateposted-public/

なかなか特徴的なcowが喋りました.せっかくなのであひるに喋らせましょう.吹き出しの向きと位置を変えてあひる画像を指定しています.

pi@raspberrypi ~ $ wget https://github.com/Na0ki/ahiru_yakuna/raw/master/ahiru240.jpg -O ~/.fortune/ahiru240.jpg
fortune ~/.fortune/ahiruyaki | xcowsay -l --bubble-at=0,-60 --image=$HOME/.fortune/ahiru240.jpg

https://www.flickr.com/photos/119142834@N05/23434841661/in/dateposted-public/

背景がちょっと邪魔なので透過処理をしてみます.

https://www.flickr.com/photos/119142834@N05/23149788589/in/dateposted-public/

いい感じです :)
例によってaliasにしておきます

pi@raspberrypi ~ $ echo alias xa='fortune ~/.fortune/ahiruyaki | xcowsay -l --bubble-at=0,-60 --image=$HOME/.fortune/ahiru240.png' >> ~/.profile

そんなこんなでみんなのおかげであひるがいい感じに焼けるようになりました.@shimadahさん, @ahiru3netさん, @emasakaさんありがとうございました!

#そうそう,以前はフレームバッファでもあひる焼きしてました.

Let’s Encrypt を使った https 設定

Let’s Encrypt に以前メールアドレスを登録していたのですが,

Let’s Encrypt Closed Beta Invite

とうことでメールが届いていたので試してみました.

ちなみに Let’s Encrypt は DV(Domain Validation)証明書が無料で取得できるサービスで,経路の暗号化はされるけど組織の実在確認まではしないレベルの物.

早速試してみます.
実行環境は Debian jessie amd64 + Apache httpd 2.4(2.4.10-10+deb8u3)

Let’s Encrypt のツールを入手して実行する.

$ git clone https://github.com/letsencrypt/letsencrypt.git
$ cd letsencrypt
$ ./letsencrypt-auto --agree-dev-preview --server https://acme-v01.api.letsencrypt.org/directory auth
Bootstrapping dependencies for Debian-based OSes...
[sudo] password for user:

とすると,必要なパッケージを自動的に導入し始めます.
質問がいくつか来るけど,メールアドレス(Let’s Encrypt 登録時のもの)とコモンネームにApache とそれ以外の選択くらい.これで自動的に Let’s Encrypt のサーバと通信を行い証明書の取得ホト損までしてくれます.
そして,最後にこんな注意書きが表示されました.

IMPORTANT NOTES:
 - If you lose your account credentials, you can recover through
   e-mails sent to user@example.org.
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.org/fullchain.pem. Your cert will
   expire on 2016-02-02. To obtain a new version of the certificate in
   the future, simply run Let's Encrypt again.
 - Your account credentials have been saved in your Let's Encrypt
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Let's
   Encrypt so making regular backups of this folder is ideal.

/etc 以下はデイリーでバックアップ取ってるので大丈夫なはず.24時間以上経ったけどメールは未だ届いていないよう.
そして,自動的に /etc/apache2/sites-available/009-example.conf を元に /etc/apache2/sites-available/009-example-le-ssl.conf が作られていました.
※このファイルは letsencrypt-auto を再実行すると消えて実行完了後再生成(以下の修正も必要)されたのでちょっと嫌.多分オプションとかで回避できると思うけど未確認.

以下の2行だけ修正して,

SSLCertificateFile /etc/letsencrypt/live/example.org/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem

a2ensite して restart で

$ sudo a2ensite 009-example-le-ssl
$ sudo service apache2 reload

とりあえず動いた

% openssl s_client -connect example.org:443
CONNECTED(00000003)
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify return:1
depth=0 CN = example.org
verify return:1
---
Certificate chain
 0 s:/CN=example.org
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIE/TCCA+WgAwIBAgISAbbh6Bp+aXaatBj/TJ7lkyyZMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTAeFw0xNTExMDQxNjQ4MDBaFw0x
NjAyMDIxNjQ4MDBaMBYxFDASBgNVBAMTC2thZ29sdWcub3JnMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzb79Wux4LWzC+ZKTRRXN53+/IRraso2AZRrt
/wesf4EBEIl8i6Iu4Dl0FjLoomxZUCN0T7C5iJ4aPy629UkWDZrawFWGkXYT00ed
UziOKTXpYYTM9BBp9Qx1aw/CT8XY6TjOtaJ21AjcIXZBZ8EPnf6fWcHEFCsNYLKk
7U/e59WJ1B1ciXowS7nMwDy1c3rvu7tlzGRuO/xSx/hu0R5DYL8zyPlLwGZyfVv/
UYYtY6Wf8ItzgthpzltqtbMv4Kuohwu2mPwKQJ73MJoOghUD4p6oxiJ3nsgLY8DO
mIlW6ScXihlZ/pWfzjWaohKsvWM+qgnQpWNUQoaXNj0ES34m4QIDAQABo4ICDzCC
AgswDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQH4Pb+Brg5Q0PWhEZ7CEdAkxWKxzAf
BgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBwBggrBgEFBQcBAQRkMGIw
LwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLmludC14MS5sZXRzZW5jcnlwdC5vcmcv
MC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDEubGV0c2VuY3J5cHQub3Jn
LzAWBgNVHREEDzANggtrYWdvbHVnLm9yZzCCAQAGA1UdIASB+DCB9TAKBgZngQwB
AgEwADCB5gYLKwYBBAGC3xMBAQEwgdYwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMu
bGV0c2VuY3J5cHQub3JnMIGrBggrBgEFBQcCAjCBngyBm1RoaXMgQ2VydGlmaWNh
dGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVwb24gYnkgUmVseWluZyBQYXJ0aWVzIGFu
ZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgQ2VydGlmaWNhdGUgUG9saWN5
IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2VuY3J5cHQub3JnL3JlcG9zaXRvcnkvMA0G
CSqGSIb3DQEBCwUAA4IBAQBa5DjWSE/d6alvGUDNW4guiJauqvxB3B+YULzRTseb
0kXGyu46u16F4av+Ate0Jxq3NnZdOpy8OTiL/wGQeWOWs33zdlxii5o8R12pMMTS
/NWFxawiCkJnzpWkhdLQGv3RNUUQn0w5yXDSY/4wK8nZYJiHXJyNQen2V6vkRPUA
U+u24R4iytsrCXW08bGa+B3F9VIadBa8Br3bbJxV5hxCC2nCE6J8C9jRERc3GKTG
YBuSlM/gaLFopgFjRIDHY5IY5tCB3P8YFbbahqNHCXkh3Ilnlbmn3WW3sOXGOJDT
2s4AbSyzJHdAk3OqtMUoVl/7fk2a70mFiQi0JWotcsoa
-----END CERTIFICATE-----
subject=/CN=example.org
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3171 bytes and written 441 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-GCM-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: 21463ABE9EDCAF2B93E782CC2C4252E8CAA9A98B6B0036F957218C42A81419CE
    Session-ID-ctx:
    Master-Key: 0B652E199D83894F04BEAB5E268EEA8806F0DAB300AA4F5AA26C3B6361D57766FE5ACF08353DAD07781960A95BDFB7BB
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - be 38 de da a3 27 cf 1e-be 39 ee df 1c f0 2e e3   .8...'...9......
    0010 - 47 4e a1 ad 15 8f 43 3c-89 2b 1b 1f ea ef 46 a1   GN....C<.+....F.
    0020 - 09 d3 1b 0d c6 09 9a 99-e1 c2 d7 22 fd e0 b7 6f   ..........."...o
    0030 - 08 cb ba 73 d8 cb 3a 82-55 59 ee 5f 05 56 9c d6   ...s..:.UY._.V..
    0040 - bc 80 1a b3 b0 8c 87 16-2f fc 69 e2 03 0c a2 7f   ......../.i.....
    0050 - 9d e2 1f 2b d3 14 fb b7-78 28 22 48 3b ff 28 52   ...+....x("H;.(R
    0060 - 5e 89 bd cd 9f 3d 4f 26-aa 1d 2d bb af 4a 84 cf   ^....=O&..-..J..
    0070 - ce 3c 20 ac 55 84 33 56-10 6c 19 1a d3 15 ce 30   .< .U.3V.l.....0
    0080 - 7e e7 0b 6f f9 31 ef 92-c0 11 7f 95 de a6 fa 80   ~..o.1..........
    0090 - c1 5d 46 92 d6 b5 0c 5a-78 75 92 ad 1f bb 6f c0   .]F....Zxu....o.
    00a0 - 7f 35 ac 07 41 07 0a c7-a5 f5 5b 3f 16 ca b7 4e   .5..A.....[?...N
    00b0 - d7 7f c1 68 dc 28 e8 15-f9 95 d9 e1 a7 bf d0 c4   ...h.(..........
 
    Start Time: 1446664204
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
 
% cat cer
-----BEGIN CERTIFICATE-----
MIIE/TCCA+WgAwIBAgISAbbh6Bp+aXaatBj/TJ7lkyyZMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTAeFw0xNTExMDQxNjQ4MDBaFw0x
NjAyMDIxNjQ4MDBaMBYxFDASBgNVBAMTC2thZ29sdWcub3JnMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzb79Wux4LWzC+ZKTRRXN53+/IRraso2AZRrt
/wesf4EBEIl8i6Iu4Dl0FjLoomxZUCN0T7C5iJ4aPy629UkWDZrawFWGkXYT00ed
UziOKTXpYYTM9BBp9Qx1aw/CT8XY6TjOtaJ21AjcIXZBZ8EPnf6fWcHEFCsNYLKk
7U/e59WJ1B1ciXowS7nMwDy1c3rvu7tlzGRuO/xSx/hu0R5DYL8zyPlLwGZyfVv/
UYYtY6Wf8ItzgthpzltqtbMv4Kuohwu2mPwKQJ73MJoOghUD4p6oxiJ3nsgLY8DO
mIlW6ScXihlZ/pWfzjWaohKsvWM+qgnQpWNUQoaXNj0ES34m4QIDAQABo4ICDzCC
AgswDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQH4Pb+Brg5Q0PWhEZ7CEdAkxWKxzAf
BgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBwBggrBgEFBQcBAQRkMGIw
LwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLmludC14MS5sZXRzZW5jcnlwdC5vcmcv
MC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDEubGV0c2VuY3J5cHQub3Jn
LzAWBgNVHREEDzANggtrYWdvbHVnLm9yZzCCAQAGA1UdIASB+DCB9TAKBgZngQwB
AgEwADCB5gYLKwYBBAGC3xMBAQEwgdYwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMu
bGV0c2VuY3J5cHQub3JnMIGrBggrBgEFBQcCAjCBngyBm1RoaXMgQ2VydGlmaWNh
dGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVwb24gYnkgUmVseWluZyBQYXJ0aWVzIGFu
ZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgQ2VydGlmaWNhdGUgUG9saWN5
IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2VuY3J5cHQub3JnL3JlcG9zaXRvcnkvMA0G
CSqGSIb3DQEBCwUAA4IBAQBa5DjWSE/d6alvGUDNW4guiJauqvxB3B+YULzRTseb
0kXGyu46u16F4av+Ate0Jxq3NnZdOpy8OTiL/wGQeWOWs33zdlxii5o8R12pMMTS
/NWFxawiCkJnzpWkhdLQGv3RNUUQn0w5yXDSY/4wK8nZYJiHXJyNQen2V6vkRPUA
U+u24R4iytsrCXW08bGa+B3F9VIadBa8Br3bbJxV5hxCC2nCE6J8C9jRERc3GKTG
YBuSlM/gaLFopgFjRIDHY5IY5tCB3P8YFbbahqNHCXkh3Ilnlbmn3WW3sOXGOJDT
2s4AbSyzJHdAk3OqtMUoVl/7fk2a70mFiQi0JWotcsoa
-----END CERTIFICATE-----
% openssl x509 -in cer -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            01:b6:e1:e8:1a:7e:69:76:9a:b4:18:ff:4c:9e:e5:93:2c:99
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X1
        Validity
            Not Before: Nov  4 16:48:00 2015 GMT
            Not After : Feb  2 16:48:00 2016 GMT
        Subject: CN=example.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:cd:be:fd:5a:ec:78:2d:6c:c2:f9:92:93:45:15:
                    cd:e7:7f:bf:21:1a:da:b2:8d:80:65:1a:ed:ff:07:
                    ac:7f:81:01:10:89:7c:8b:a2:2e:e0:39:74:16:32:
                    e8:a2:6c:59:50:23:74:4f:b0:b9:88:9e:1a:3f:2e:
                    b6:f5:49:16:0d:9a:da:c0:55:86:91:76:13:d3:47:
                    9d:53:38:8e:29:35:e9:61:84:cc:f4:10:69:f5:0c:
                    75:6b:0f:c2:4f:c5:d8:e9:38:ce:b5:a2:76:d4:08:
                    dc:21:76:41:67:c1:0f:9d:fe:9f:59:c1:c4:14:2b:
                    0d:60:b2:a4:ed:4f:de:e7:d5:89:d4:1d:5c:89:7a:
                    30:4b:b9:cc:c0:3c:b5:73:7a:ef:bb:bb:65:cc:64:
                    6e:3b:fc:52:c7:f8:6e:d1:1e:43:60:bf:33:c8:f9:
                    4b:c0:66:72:7d:5b:ff:51:86:2d:63:a5:9f:f0:8b:
                    73:82:d8:69:ce:5b:6a:b5:b3:2f:e0:ab:a8:87:0b:
                    b6:98:fc:0a:40:9e:f7:30:9a:0e:82:15:03:e2:9e:
                    a8:c6:22:77:9e:c8:0b:63:c0:ce:98:89:56:e9:27:
                    17:8a:19:59:fe:95:9f:ce:35:9a:a2:12:ac:bd:63:
                    3e:aa:09:d0:a5:63:54:42:86:97:36:3d:04:4b:7e:
                    26:e1
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Subject Key Identifier:
                07:E0:F6:FE:06:B8:39:43:43:D6:84:46:7B:08:47:40:93:15:8A:C7
            X509v3 Authority Key Identifier:
                keyid:A8:4A:6A:63:04:7D:DD:BA:E6:D1:39:B7:A6:45:65:EF:F3:A8:EC:A1
 
            Authority Information Access:
                OCSP - URI:http://ocsp.int-x1.letsencrypt.org/
                CA Issuers - URI:http://cert.int-x1.letsencrypt.org/
 
            X509v3 Subject Alternative Name:
                DNS:example.org
            X509v3 Certificate Policies:
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.letsencrypt.org
                  User Notice:
                    Explicit Text: This Certificate may only be relied upon by Relying Parties and only in accordance with the Certificate Policy found at https://letsencrypt.org/repository/
 
    Signature Algorithm: sha256WithRSAEncryption
         5a:e4:38:d6:48:4f:dd:e9:a9:6f:19:40:cd:5b:88:2e:88:96:
         ae:aa:fc:41:dc:1f:98:50:bc:d1:4e:c7:9b:d2:45:c6:ca:ee:
         3a:bb:5e:85:e1:ab:fe:02:d7:b4:27:1a:b7:36:76:5d:3a:9c:
         bc:39:38:8b:ff:01:90:79:63:96:b3:7d:f3:76:5c:62:8b:9a:
         3c:47:5d:a9:30:c4:d2:fc:d5:85:c5:ac:22:0a:42:67:ce:95:
         a4:85:d2:d0:1a:fd:d1:35:45:10:9f:4c:39:c9:70:d2:63:fe:
         30:2b:c9:d9:60:98:87:5c:9c:8d:41:e9:f6:57:ab:e4:44:f5:
         00:53:eb:b6:e1:1e:22:ca:db:2b:09:75:b4:f1:b1:9a:f8:1d:
         c5:f5:52:1a:74:16:bc:06:bd:db:6c:9c:55:e6:1c:42:0b:69:
         c2:13:a2:7c:0b:d8:d1:11:17:37:18:a4:c6:60:1b:92:94:cf:
         e0:68:b1:68:a6:01:63:44:80:c7:63:92:18:e6:d0:81:dc:ff:
         18:15:b6:da:86:a3:47:09:79:21:dc:89:67:95:b9:a7:dd:65:
         b7:b0:e5:c6:38:90:d3:da:ce:00:6d:2c:b3:24:77:40:93:73:
         aa:b4:c5:28:56:5f:fb:7e:4d:9a:ef:49:85:89:08:b4:25:6a:
         2d:72:ca:1a
-----BEGIN CERTIFICATE-----
MIIE/TCCA+WgAwIBAgISAbbh6Bp+aXaatBj/TJ7lkyyZMA0GCSqGSIb3DQEBCwUA
MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD
ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTAeFw0xNTExMDQxNjQ4MDBaFw0x
NjAyMDIxNjQ4MDBaMBYxFDASBgNVBAMTC2thZ29sdWcub3JnMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzb79Wux4LWzC+ZKTRRXN53+/IRraso2AZRrt
/wesf4EBEIl8i6Iu4Dl0FjLoomxZUCN0T7C5iJ4aPy629UkWDZrawFWGkXYT00ed
UziOKTXpYYTM9BBp9Qx1aw/CT8XY6TjOtaJ21AjcIXZBZ8EPnf6fWcHEFCsNYLKk
7U/e59WJ1B1ciXowS7nMwDy1c3rvu7tlzGRuO/xSx/hu0R5DYL8zyPlLwGZyfVv/
UYYtY6Wf8ItzgthpzltqtbMv4Kuohwu2mPwKQJ73MJoOghUD4p6oxiJ3nsgLY8DO
mIlW6ScXihlZ/pWfzjWaohKsvWM+qgnQpWNUQoaXNj0ES34m4QIDAQABo4ICDzCC
AgswDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcD
AjAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQH4Pb+Brg5Q0PWhEZ7CEdAkxWKxzAf
BgNVHSMEGDAWgBSoSmpjBH3duubRObemRWXv86jsoTBwBggrBgEFBQcBAQRkMGIw
LwYIKwYBBQUHMAGGI2h0dHA6Ly9vY3NwLmludC14MS5sZXRzZW5jcnlwdC5vcmcv
MC8GCCsGAQUFBzAChiNodHRwOi8vY2VydC5pbnQteDEubGV0c2VuY3J5cHQub3Jn
LzAWBgNVHREEDzANggtrYWdvbHVnLm9yZzCCAQAGA1UdIASB+DCB9TAKBgZngQwB
AgEwADCB5gYLKwYBBAGC3xMBAQEwgdYwJgYIKwYBBQUHAgEWGmh0dHA6Ly9jcHMu
bGV0c2VuY3J5cHQub3JnMIGrBggrBgEFBQcCAjCBngyBm1RoaXMgQ2VydGlmaWNh
dGUgbWF5IG9ubHkgYmUgcmVsaWVkIHVwb24gYnkgUmVseWluZyBQYXJ0aWVzIGFu
ZCBvbmx5IGluIGFjY29yZGFuY2Ugd2l0aCB0aGUgQ2VydGlmaWNhdGUgUG9saWN5
IGZvdW5kIGF0IGh0dHBzOi8vbGV0c2VuY3J5cHQub3JnL3JlcG9zaXRvcnkvMA0G
CSqGSIb3DQEBCwUAA4IBAQBa5DjWSE/d6alvGUDNW4guiJauqvxB3B+YULzRTseb
0kXGyu46u16F4av+Ate0Jxq3NnZdOpy8OTiL/wGQeWOWs33zdlxii5o8R12pMMTS
/NWFxawiCkJnzpWkhdLQGv3RNUUQn0w5yXDSY/4wK8nZYJiHXJyNQen2V6vkRPUA
U+u24R4iytsrCXW08bGa+B3F9VIadBa8Br3bbJxV5hxCC2nCE6J8C9jRERc3GKTG
YBuSlM/gaLFopgFjRIDHY5IY5tCB3P8YFbbahqNHCXkh3Ilnlbmn3WW3sOXGOJDT
2s4AbSyzJHdAk3OqtMUoVl/7fk2a70mFiQi0JWotcsoa
-----END CERTIFICATE-----

後はコンテンツを全部 https に設定して http から転送するようにしないといけないですね.

とりあえず無料で使える StartSSL,安めの Rapid SSL,キャンペーンや乗り換えで一定期間無料とか色々ありますが,そのくらいのレベルであれば代替になるかなと思います.それ以上は大抵 EV になるでしょうし.ただ CNしか無かったり期間が短いのが気になりますね.

Android の Google Authenticator のデータをダンプしてバックアップする

Android の Google Authenticator 色々な認証に使えて便利ですが,以前 Nexus5 を紛失した時や LGL22 でデータが飛んでしまった後復旧が面倒でした.どうにかバックアップが取れないかなと調べてみました.

Android からデータを取得

/data/data/com.google.android.apps.authenticator2/databases/databases がデータが格納されているファイルらしいです.
adb pull で持ってきたいけど権限がないので一旦 /storage/sdcard0/ に cp する

% adb shell
shell@g2:/ $ su
root@g2:/ # cp /data/data/com.google.android.apps.authenticator2/databases/databases /storage/sdcard0/

ローカルPC に退避

% adb pull /storage/sdcard0/databases .

/storage/sdcard0/ に cp したデータを消す.暗号化領域の下のはずだけど一応上書きしてから削除

% adb shell
shell@g2:/ $ su
root@g2:/ # ls -l /storage/sdcard0/databases
-rw-rw---- root     sdcard_r    16384 2015-10-09 22:51 databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # head -c 16384 /dev/random > /storage/sdcard0/databases
root@g2:/ # rm /storage/sdcard0/databases
root@g2:/ # ^D
shell@g2:/ $ ^D

データ形式を確認してdump

該当ファイルは file コマンドによると SQLite3 のようなので dump してみる

% file ./databases
./databases: SQLite 3.x database
% sqlite3 ./databases
SQLite version 3.8.11.1 2015-07-29 20:00:57
Enter ".help" for usage hints.
sqlite> .dump
PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE android_metadata (locale TEXT);
INSERT INTO "android_metadata" VALUES('ja_JP');
CREATE TABLE accounts (_id INTEGER PRIMARY KEY, email TEXT NOT NULL, secret TEXT NOT NULL, counter INTEGER DEFAULT 0, type INTEGER, provider INTEGER DEFAULT 0, issuer TEXT DEFAULT NULL, original_name TEXT DEFAULT NULL);
 :

ここで取得した PRIMARY KEY を HOTP TOKEN を割り出す script の "google-authenticator.py に食わせると Android App と同じコードが帰ってくるのを確認しました.勿論普通に認証も可能.

IMG_20151010_012917

ということで要root ですが, /data/data/com.google.android.apps.authenticator2/databases/databases を退避して他の端末に持って行っても動作するかも.少なくとも PRIMARY KEY は入手できるので手動で入力すれば OK ですね.
とはいえ端末紛失時には作りなおしたほうが良いでしょうが.

root が取れない場合は登録時に PRIMARY KEY をメモしておくくらいですかね.QR Code だけしか見えない場合は Google Authenticator に食わせる前に別のリーダーを利用したりすれば可能です
例えば以下のような読み取り内容の場合 6QHI5WW6H3FMJ2ZI が PRIMARY KEY です.

otpauth://t│·········· otp/mk@micro?secret=6QHI5WW6H3FMJ2ZI

Node.js製 Slack クライアントの plaidchat を試してみる

ということで plaidchat も少し試してみました.

導入は特に苦労はなくページに書いてあるとおり npm install で一発でした.

Slack 製の物に比べると機能は少ないです.多分1プロジェクトのみの対応です.でもリソースの省比量は大分少なくメインウィンドウを隠すことも出来ます.
About が後ろに行って複数出せてしまったり,窓の中が真っ白になったり未だこなれてない感じです.これからに期待です.

20150928_08:09:00-13716

% ps aux | grep -i plaidchat | awk '{print $6}' | xargs echo| sed -e 's/\ /\+/g' | bc
326480

RAM 消費量が少ないとはいってもそこそこ消費するので今度は Slack IRC GW なども試してみたいです.

Slack の Linux版公式クライアントを試してみる

サポートディストリビューションも多そう!ということで試してみました.
Twitter の画像ではたくさんのディストリビューションのロゴがあったのですが,ダウンロードページに行くとこんだけでした><

20150924_10:09:57-20642

ダウンロードして Debian testing stretch amd64 環境で展開して試してみると特に問題なく動きました.

ダウンロードしたパッケージはこんな感じ

% dpkg --info ~/Downloads/slack-desktop-1.2.2-amd64.deb          
 新形式 debian パッケージ、バージョン 2.0。
 サイズ 45815918 バイト: コントロールアーカイブ = 446 バイト。
     473 バイト、   12 行      control              
 Package: slack-desktop
 Version: 1.2.2
 Depends: gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils, apt-transport-https
 Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0
 Replaces: slack (<< 1.2.1~)
 Breaks: slack (<< 1.2.1~)
 Section: misc
 Priority: optional
 Architecture: amd64
 Installed-Size: 134268
 Maintainer: Slack Technologies <feedback@slack.com>
 Description: Slack Desktop

とりあえず実行.( dpkg -i でインストールしてもとりあえず動いています.)

% ar x ~/Downloads/slack-desktop-1.2.2-amd64.deb
% tar xf ../data.tar.xz
% ./usr/bin/slack

20150924_10:09:08-13152

日本語のリソースファイルぽいものもあるけど日本語が表示されないなと思ったのですが,中身は他の言語も含め全て空でした.この辺はこれからのようですね.

% ls -l ./usr/share/slack/locales/ja.pak 
-rw-r--r-- 1 mk mk 0  9月 23 14:42 ./usr/share/slack/locales/ja.pak

起動すると ブラウザと同じような感じでログインできます.
20150924_11:09:35-26588

タスクトレイのメニューはこんな感じでした.タスクトレイからウィンドウを開いた後タスクトレイへの格納は出来ないようです.
20150927_07:09:20-30617

複数の team にも対応しています.
20150927_07:09:15-1275

日本語の表示や入力も問題なく行えました.
と,ここまではいい感じかなー.と思っていたのですが起動に時間がかかるのはともかくメモリ消費量が大きいです.

% ps aux| head -1                                                           
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
% ps aux| grep -i slack                                                     
mk        2463  0.1  0.5 1331200 40756 ?       Sl   01:48   0:09 /usr/share/slack/slack
mk        2497  0.0  0.1 313440  8020 ?        S    01:48   0:00 /usr/share/slack/slack --type=zygote --no-sandbox
mk        2597  0.0  0.5 581152 44584 ?        Sl   01:48   0:04 /usr/share/slack/slack --type=gpu-process --channel=2463.0.1022154471 --no-sandbox --supports-dual-gpus=false --gpu-driver-bug-workarounds=2,14,43 --disable-accelerated-video-decode --gpu-vendor-id=0x8086 --gpu-device-id=0x0046 --gpu-driver-vendor --gpu-driver-version
mk        2648  0.1 11.4 2024760 909348 ?      Sl   01:48   0:16 /usr/share/slack/slack --type=renderer --force-device-scale-factor=1 --no-sandbox --enable-deferred-image-decoding --lang=ja --node-integration=true --enable-plugins --subpixel-font-scaling=true --enable-pinch-virtual-viewport --enable-delegated-renderer --num-raster-threads=2 --enable-gpu-rasterization --use-image-texture-target=3553 --disable-accelerated-video-decode --channel=2463.1.1087300934
mk        2750  0.3 13.5 2102980 1082316 ?     Sl   01:49   0:37 /usr/share/slack/slack --type=renderer --force-device-scale-factor=1 --no-sandbox --enable-deferred-image-decoding --lang=ja --guest-instance-id=1 --node-integration=false --enable-plugins --preload=/usr/share/slack/resources/app.asar/static/ssb-interop --enable-pinch-virtual-viewport --enable-delegated-renderer --num-raster-threads=2 --enable-gpu-rasterization --use-image-texture-target=3553 --disable-accelerated-video-decode --channel=2463.2.1767621685
mk        3127  0.0  0.0  13700  2224 pts/2    S+   04:25   0:00 grep -i slack
% ps aux | grep -i slack | awk '{print $6}' | xargs echo| sed -e 's/\ /\+/g' | bc
2087260
% pstree 29317
slack─┬─slack─┬─slack─┬─{Chrome_ChildIOT}
      │       │       ├─2*[{CompositorTileW}]
      │       │       ├─{Compositor}
      │       │       ├─{HTMLParserThrea}
      │       │       ├─{handle-watcher-}
      │       │       └─5*[{slack}]
      │       └─slack─┬─{Chrome_ChildIOT}
      │               ├─2*[{CompositorTileW}]
      │               ├─{Compositor}
      │               ├─{HTMLParserThrea}
      │               ├─{ScriptStreamerT}
      │               ├─{handle-watcher-}
      │               └─{slack}
      ├─slack─┬─{Chrome_ChildIOT}
      │       └─{Watchdog}
      ├─{AudioThread}
      ├─3*[{BrowserBlocking}]
      ├─5*[{CachePoolWorker}]
      ├─{Chrome_CacheThr}
      ├─{Chrome_DBThread}
      ├─{Chrome_FileThre}
      ├─{Chrome_FileUser}
      ├─{Chrome_IOThread}
      ├─{Chrome_ProcessL}
      ├─{IndexedDB}
      ├─{NSS SSL ThreadW}
      ├─{NetworkChangeNo}
      ├─{gdbus}
      ├─{gmain}
      ├─{handle-watcher-}
      ├─{inotify_reader}
      ├─{sandbox_ipc_thr}
      ├─5*[{slack}]
      └─{threaded-ml}
% free
              total        used        free      shared  buff/cache   available
Mem:        7971864     6427012      245032      344740     1299820     1111572
% kill 29317
% free
              total        used        free      shared  buff/cache   available
Mem:        7971864     4251376     2457392      306516     1263096     3325500

この作りだと Chrome/Chromium を併用している場合 Chrome アプリケーションにしてもらったほうがリソース食わないんじゃないかなと思ったりも.

ちなみに Hipchat には以前から Linux Client は存在していてこんな感じです.Slack に比べると大分軽いです.

% ps aux | grep hipchat 
mk        1953  2.4  1.6 2584884 128724 ?      Ssl  08:23   0:01 /usr/bin/hipchat
% pstree 1953
hipchat.bin─┬─{QProcessManager}
            ├─2*[{QQmlThread}]
            ├─{QXcbEventReader}
            ├─{Qt HTTP thread}
            ├─{Qt bearer threa}
            └─5*[{hipchat.bin}]

Node.ja で作られた plaidchat というクライアントもあるようです.これも試してみようと思います.

ReText 翻訳のメモ

ReText 5.1.0 を翻訳してみました.そのとき遠回りしたのでメモしておきます.

このアプリケーションの翻訳ファイルは Qt の .ts を翻訳して .qm で利用する形のようです.この辺りは以下のエントリを参照して下さい.

先ずは ReText の source を入手.

% git clone https://github.com/retext-project/retext.git
% cd retext/locale
% linguist retext_ja.ts

これで一旦翻訳してみましたが, git log 見て Transifex 使ってるぽいのを見つけましたorz

locale: Updated French translation from Transifex

Transifex を見に行くとありましたorz

とりあえず未翻訳でわかる部分は翻訳しておきました.結果をダウンロードして反映してみると大体日本語化出来た感じですが,以下の部分は翻訳しないほうがいいと思うのですが ReText の中に見当たりません.

corp

.ts や source 全部から検索

% grep ページ ./locale/retext_ja.ts
% grep -i PageDown ./locale/retext_ja.ts
% find . -type f | xargs grep -i PageDown    
./ReText/window.py:                     lambda: self.switchTab(1), shct=Qt.CTRL+Qt.Key_PageDown)

ReText パッケージ全部から検索

% dpkg -L retext | xargs -I{} sh -c "if test -f {} ; then grep ページ {} ; fi"
 

ベースの Qtの方かなと思って,全 .ts からも探してみます.

% find /usr/share -type f -name "*_ja.ts"| xargs grep 'ページ'
find: `/usr/share/doc/google-chrome-stable': 許可がありません
/usr/share/skype/lang/skype_ja.ts:        <translation>ページ%1</translation>
/usr/share/skype/lang/skype_ja.ts:        <translation>ホームページ:</translation>
/usr/share/skype/lang/skype_ja.ts:        <translation>ダウンロードページを開く</translation>
/usr/share/skype/lang/skype_ja.ts:        <translation>アカウントページの閲覧</translation>

.ts が用意されていないパッケージにあるのかもしれないと .qm から .ts に変換する方法を探すと lconvert コマンドを見つけました.( 簡単な利用方法は次のエントリに追記した 翻訳ファイルの .ts の翻訳方法 | matoken’s meme )

*_ja.qm を.ts にして検索すると発見しました.

% find /usr/share -type f -name "*_ja.qm" | xargs -n1 -I{} lconvert -if qm -i {} -of ts -o - | grep 'ページアップ'
        <translation>ページアップ</translation>
        <translation>ページアップ</translation>
% find /usr/share -type f -name "*_ja.qm" | xargs -n1 -I{} lconvert -if qm -i {} -of ts -o - | grep 'ページダウン'
        <translation>ページダウン</translation>
        <translation>ページダウン</translation>

これはどのファイルに含まれているのかを確認すると /usr/share/qt5/translations/qtbase_ja.qm

% find /usr/share -type f -name "*_ja.qm" | xargs -n1 -I{} sh -c "lconvert -if qm -i {} -of ts -o - | grep 'ページアップ'; echo {}"
 
/usr/share/gnuplot/gnuplot/4.6/qt/qtgnuplot_ja.qm
/usr/share/virtualbox/nls/VirtualBox_ja.qm
/usr/share/virtualbox/nls/qt_ja.qm
/usr/share/qt5/translations/qtmultimedia_ja.qm
/usr/share/qt5/translations/linguist_ja.qm
/usr/share/qt5/translations/qtdeclarative_ja.qm
/usr/share/qt5/translations/qtquick1_ja.qm
/usr/share/qt5/translations/qmlviewer_ja.qm
/usr/share/qt5/translations/qtconfig_ja.qm
/usr/share/qt5/translations/qtscript_ja.qm
/usr/share/qt5/translations/qt_ja.qm
/usr/share/qt5/translations/qtquickcontrols_ja.qm
/usr/share/qt5/translations/assistant_ja.qm
/usr/share/qt5/translations/designer_ja.qm
/usr/share/qt5/translations/qtxmlpatterns_ja.qm
        <translation>ページアップ</translation>
        <translation>ページアップ</translation>
/usr/share/qt5/translations/qtbase_ja.qm
/usr/share/qt5/translations/qt_help_ja.qm
/usr/share/gnuplot5/gnuplot/5.0/qt/qtgnuplot_ja.qm
/usr/share/libqtxdg/libqtxdg_ja.qm
/usr/share/librazorqt/librazorqt_ja.qm
/usr/share/owncloud/i18n/client_ja.qm
/usr/share/skype/lang/skype_ja.qm
 
% lconvert -if qm -i /usr/share/qt5/translations/qtbase_ja.qm -of ts -o - | grep 'ページアップ'
 
        <translation>ページアップ</translation>
        <translation>ページアップ</translation>
% lconvert -if qm -i /usr/share/qt5/translations/qtbase_ja.qm -of ts -o - | grep 'ページダウン'
 
        <translation>ページダウン</translation>
        <translation>ページダウン</translation>

このファイルはどのパッケージに含まれているか確認すると qttranslations5-l10n でした.

% apt-file search qtbase_ja.qm
qttranslations5-l10n: /usr/share/qt5/translations/qtbase_ja.qm

Transifex を探すと qttranslations の qtbase にそれらしいものがありました.

該当部分はここ

.ts をダウンロードして該当部分を以下のように書き換えて

@@-5569,12 +5571,12 @@
     <message>
         <location line="+1"/>
         <source>PgUp</source>
-        <translation>ページアップ</translation>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>
         <source>PgDown</source>
-        <translation>ページダウン</translation>
+        <translation type="unfinished"></translation>
     </message>
     <message>
         <location line="+1"/>

.qm を作って反映してみると,

% sudo cp ~/Downloads/for_use_qtbase_qtbase_ja.qm /usr/share/qt5/translations/qtbase_ja.qm

以下のように反映されました.

20150919_09:09:58-6829

とりあえず「翻訳のために qttranslations team チームに参加」を押して申請をだしてみました.

Yandex.Disk を試してみる

Yandex.Disk は Linux と BSD に ODF 閲覧機能まで!ってことでロシアでシェアの大きいらしい Yandex のアカウントを取ってみました.
# matoken 空いてた:)
##ここからアカウントを作ると +512MB
https://disk.yandex.com/invite/?hash=URJFTFG9

早速 Yandex.Disk に日本語の .odt をUp してみると,

20150918_05:09:39-19415
20150918_05:09:25-20153

  • 日本語ファイル名ok
  • ファイル一覧画面でのプレビューは日本語豆腐
  • ファイル閲覧ページはは日本語表示ok

という感じでした.

ファイル共有サービスの BSD サポートは実は WebDAV が使えるので Nautilus や Dolphin で繋いでねって感じでした.これはちょっとがっかり.WebDAV で OK だと Otixo や ownCloud 経由でかなりのサービスで対応出来てますね.

Linux のクライアントは .deb/.rpm のパッケージが提供されていて,.deb はリポジトリも用意されているので手間が省けていいです.但し Console client なので GUI がいい人は WebDAV でいいこともあるかもしれません.(サードパーティ製の GUI はあるみたい)

ちなみに Yandex は OSM にこういう貢献もしてるので好印象だったりします.

今のところ ODF の編集は ownCloud で簡易編集が可能,Microsoft OfficeOnline でも編集可能らしい(未検証).案外選択肢無いですね…….
Android/iOS 辺りのサポートもされると出先でのプレゼンテーションなどで便利になりそう.(でもこっちは無線プロジェクターの普及が進まないと利用者が増えないかな?)

翻訳ファイルの .ts の翻訳方法

翻訳ファイルの .tsPoedit では開けない.Qt Linguist というものが使えるそうなので Debian だと wheezy-backports 以降に存在する qttools5-dev-tools を導入する.

% sudo apt install qttools5-dev-tools
% /usr/lib/x86_64-linux-gnu/qt5/bin/linguist

20150917_18:09:30-3415

20150917_18:09:24-3340

翻訳して保存,「ファイル」->「リリース」で .ts から .qm が作られる.これをコピーして対象アプリケーションを起動すると翻訳が反映されるはず.

% sudo cp ./retext_ja.?? /usr/share/retext/locale

<追記>
コマンドラインで変換する場合は qtchooser パッケージに含まれる lrelease が利用できる.

% lrelease ./retext_ja.ts -qm ./retext_ja.qm

若しくは同パッケージの lconvert でもok.これは qm から ts への変換や pot / po / qph / xlf にも対応している.

% lconvert -i retext_ja.ts -o retext_ja2.qm
% lconvert -if qm -i retext_ja.qm -of ts -o retext_ja2.ts

</追記>

awesome wm の時計をカスタマイズ & メニューを最新に追従

20150912_00:09:11-13117

時計をカスタマイズ

デスクトップの右上に時計が表示されますが,秒が表示されません.ここに秒も表示したいです. `awful.widget.textclock() で実現しているようなのでここのパラメーターを変更することで実現できました.

Parameters:
 
format The time format. Default is " %a %b %d, %H:%M ".
timeout How often update the time. Default is 60.

以下のように書き換えました.

-- {{{ Wibox
-- Create a textclock widget
-mytextclock = awful.widget.textclock()
+mytextclock = awful.widget.textclock("%a %b %d, %H:%M:%S", 1)

規定値は %a %b %d, %H:%M", 60 で前半の " で囲ってある部分は date の FORMAT のようなので man date を参照して :%S を末尾に追加,後半の 60 は更新時間(秒)のようなのでこのままでは60秒に1回しか更新されないので1秒単位で更新されるように 1 を指定しました.

メニューを最新に追従するようにする

左上の awesome のメニューの Debian ツリーに導入されたアプリケーションメニューがありますが,awesome 初回実行時にコピーされたものが参照されます.そのためそれ以降に導入,削除したものは反映されません.大元の設定は随時反映されるのでそちらを参照するようにします.

  • 参照しているメニューファイル: ~/.config/awesome/debian/menu.lua
  • 元メニューファイル: /etc/xdg/awesome/debian/menu.lua

自分のホーム以下のメニューは削除してしまってシンボリックリンクを貼ることにします.

% rm -rf ~/.config/awesome/debian
% ln -s /etc/xdg/awesome/debian ~/.config/awesome/debian

メニューのカスタマイズは以下のような感じで rc.lua 内で行うようにしました.数が増えるようならファイルを分けるといいかもしれません.

+fav_menu = {
+   { "Nautilus", "nautilus" },
+   { "Atom", "atom" },
+   { "Chromium privacy", "/home/mk/script/chromium-privacy.bash" },
+   { "mikutter", "mikutter" },
+   { "LibreOffice", "libreoffice" },
+}
+
 mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
                                     { "Debian", debian.menu.Debian_menu.Debian },
+                                    { "fav", fav_menu },
                                     { "open terminal", terminal }
                                   }
                         })

全体の設定は以下の Gist を参照して下さい.

これまでの awesome 関連のエントリは以下を参照してください.

awesome wm の時計をカスタマイズ & メニューを最新に追従

20150912_00:09:11-13117

時計をカスタマイズ

デスクトップの右上に時計が表示されますが,秒が表示されません.ここに秒も表示したいです. `awful.widget.textclock() で実現しているようなのでここのパラメーターを変更することで実現できました.

Parameters:
 
format The time format. Default is " %a %b %d, %H:%M ".
timeout How often update the time. Default is 60.

以下のように書き換えました.

-- {{{ Wibox
-- Create a textclock widget
-mytextclock = awful.widget.textclock()
+mytextclock = awful.widget.textclock("%a %b %d, %H:%M:%S", 1)

規定値は %a %b %d, %H:%M", 60 で前半の " で囲ってある部分は date の FORMAT のようなので man date を参照して :%S を末尾に追加,後半の 60 は更新時間(秒)のようなのでこのままでは60秒に1回しか更新されないので1秒単位で更新されるように 1 を指定しました.

メニューを最新に追従するようにする

左上の awesome のメニューの Debian ツリーに導入されたアプリケーションメニューがありますが,awesome 初回実行時にコピーされたものが参照されます.そのためそれ以降に導入,削除したものは反映されません.大元の設定は随時反映されるのでそちらを参照するようにします.

  • 参照しているメニューファイル: ~/.config/awesome/debian/menu.lua
  • 元メニューファイル: /etc/xdg/awesome/debian/menu.lua

自分のホーム以下のメニューは削除してしまってシンボリックリンクを貼ることにします.

% rm -rf ~/.config/awesome/debian
% ln -s /etc/xdg/awesome/debian ~/.config/awesome/debian

メニューのカスタマイズは以下のような感じで rc.lua 内で行うようにしました.数が増えるようならファイルを分けるといいかもしれません.

+fav_menu = {
+   { "Nautilus", "nautilus" },
+   { "Atom", "atom" },
+   { "Chromium privacy", "/home/mk/script/chromium-privacy.bash" },
+   { "mikutter", "mikutter" },
+   { "LibreOffice", "libreoffice" },
+}
+
 mymainmenu = awful.menu({ items = { { "awesome", myawesomemenu, beautiful.awesome_icon },
                                     { "Debian", debian.menu.Debian_menu.Debian },
+                                    { "fav", fav_menu },
                                     { "open terminal", terminal }
                                   }
                         })

全体の設定は以下の Gist を参照して下さい.

これまでの awesome 関連のエントリは以下を参照してください.