Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

CodeMirrorでphrasesオプションを使ってUIを日本語化できるようになったという話

2018年8月25日にリリースされたCodeMirrorの5.40.0から、検索ダイアログなどのUIを日本語化できるようになりました。

New features

New method phrase and option phrases to make translating UI text in addons easier.

github.com

何が嬉しいのか

CodeMirrorの検索アドオンなどを使うとき、ダイアログ内の一部UIを英語から日本語に置き換えられませんでした。 例えば Search:(Use /re/ syntax for regexp search) という文言が変更できませんでした (それほど難しい文言でもないので英語のままでも良いですが、置き換えられるとUI上、言語を統一できてキレイです)。

CodeMirror: Search/Replace Demo

phrasesオプションに指定して変更できます

phrases というオプションをCodeMirrorに指定して、置き換える言葉を設定できます。 プロパティーにキーになる文言を、値に変更したい文言を指定します。

以下の例では searchアドオンのフレーズ を置き換えています。

CodeMirror(targetElement, {
  ...,
  phrases: {
    'Search:': '検索:',
    'Replace:': '置換:',
    '(Use /re/ syntax for regexp search)': '(/正規表現/ と書いて正規表現で検索できます)',
    'With:': '置換する文字:',
    'Replace?': '置換しますか?',
    'Yes': 'はい',
    'No': 'いいえ',
    'All': 'すべて',
    'Stop': 'やめる'
  }
})

そうすると、表示される文言を日本語に変更できます。

f:id:hirokiky:20180903193303p:plain

文言がユーザーのAccept-Languageによって切り替わるわけではないので「国際化」とは呼べなそうですが、僕はかなりありがたい機能だと思います。

DjangoRestFrameworkのSerializerから関数/メソッドの結果をフィールドの値として返す

DjangoRestFrameworkのSerializer(ModelSerializer)で、フィールドの値を関数/メソッドの結果で返したいことがあります。 これはバリデーションとしてSerializerを使うのでなく、モデルから辞書に値を変換したい場合の話です。

例えば、フィールドの日時が何日前かや、何かしら加工した値が欲しい場合です。 もちろんモデル自体にプロパティとして実装すれば疑問なくフィールドとして使えますが、そのSerializerでだけやりたい処理の場合はこの方法が有効です。

以下の例では Foo モデルに、 bar というフィールドでメソッドの結果を返すようにしています。 serializers.SerializerMethodField を使ってできます。この場合 bar はリードオンリーのフィールドになります。

class FooSerializer(serializers.ModelSerializer):
    bar = serializers.SerializerMethodField()

    def get_bar(self, obj):
        return obj.bar.title()

    class Meta:
        model = Foo
        fields = (
            ...
            'bar'
        )

SerializerMethodField に何も指定しないと、メソッド名は get_bar がデフォルトで指定されます。 メソッド名を特別に指定したい場合は SerializerMethodField("calc_bar") のようにします。

でもこのときにメソッド名もフィールドと同じ名前(上記では bar )にしてしまうと、フィールドが無効になってしまうので気をつけてください。 (名前が被ってしまうので、クラス内の値として後に書いたものだけが有効になってしまう)。

www.django-rest-framework.org

Ansibleでファイルの存在確認にstatを使ったら大きいファイルには動作が遅すぎたのでやったこと

Ansibleでファイルが存在しているかによって処理を分けたいことがあります。 そんなときは stat を使うとできますが、対象のファイルが数GB単位で大きいと処理が遅くなります。

下の例ではファイルが存在しないときだけ実行するタスクを書いています。

    - name: とあるファイルが存在しているかチェックする
      stat:
        path: /path/to/file
      register: the_file_stat
    - name: (ファイルが存在してないときだけやりたい処理)
      shell: ...
      when: the_file_stat.stat.exists == False

ですがこの stat は、ファイルをチェックするだけでなくてチェックサムなども計算してくれます。 かなり重いファイルの場合、この処理で時間がかかってしまいます。 ファイルの存在チェックだけで良い場合は、チェックサムは不要なので以下のようにして遅くなる原因の処理を無くせます。

    - name: とあるファイルが存在しているかチェックする
      stat:
        path: /path/to/file
        get_checksum: false
        get_md5: false
      register: the_file_stat

このIssueで自己解決してる人が居たので、参考になりました。

github.com

Ubuntu18.04でDockerのDNS解決がホストのDNSにならない問題の話

Ubuntu18.04でDocker (17) を動かすとホストのDNSの設定を使わずに 8.8.8.8 を使ってしまう問題がありました。

何が困るかというと、AWSで動かしている場合ローカルのDNSを使わずにパブリックIPを引いてしまうとSecurityGroupの許可設定が効かないことです。 例えば、コンテナー内部からデーターベースにアクセスできないなどの問題が起こります (システムの都合上ECSなど使わずにEC2にDockerを入れて自分で可動させています)。

github.com

原因としては、ホストPCで systemd-resolved を見る設定になっているのだけど、 その設定を使おうとしたDockerコンテナーが使えずに 8.8.8.8 にフォールバックしたみたいな話のようです。

systemd-resolved 伝わないようにしちゃうみたいな回避が効きますが、まぁあんまり良い気持ちではないですね。 上記のIssueコメントで紹介されています。

pay.jpでプランを変更すると変更前のプランの金額で決済される不具合(修正済み)に当たった

注意書き

以下の本文は情報だけを伝えようと書いています。 この文章は個人や企業を評価する意図はありません。

本文

pay.jp で定期課金のプランを契約期間中に変更すると、変更前のプランの料金で決済される不具合に当たりました。 この不具合は現在(2018/08/09)、修正済みです。

2018年7月ごろに、有料のプランから他の有料のプランへ変更する際に発生する不具合でした。 例えば月額5000円のプランから3000円のプランに変更したとき、元の料金を返金後に通常3000円で決済されますが、決済が5000円になっていたという不具合でした

昔からあったというわけではなく、新しく発生した不具合でした。 プランの返金は有効にしていましたが、発生したケースが厳密にはどういう場合なのか私には分かりません。

pay.jp にSlackから問い合わせし、不具合の修正とお客様への返金の処理を依頼しました。 このとき追加で問題が発生しました。不具合の対応用の返金をする処理に間違いがあったらしく、該当のお客様にさらに決済されるという問題も起こりました。この重ねての問題も現在は返金にて対応いただきました。

pay.jp は2016年春ごろから導入しており、現在2018年までの2年間で不具合は2件目です (サービスの障害やメンテナンスは除く)。

おわりに

私個人としてはpay.jpさんには今後も頑張って欲しいと思っています。 一緒に良いサービスを作っていきたいと応援の気持ちがとても大きいです。

改めてになりますが、今回の不具合によってご迷惑、ご心配をおかけした方々、申し訳ありませんでした。 pay.jpさんも対応いただきありがとうございました。

クラウドファンディングは支援(バック)するときが気持ちの最高潮なのかなと思った

www.kickstarter.com

クラウドファンディングは支援(バック)するときが気持ちとして最高潮なんじゃないかなって思ったという話です。

僕はクラウドファンディングが好きでKickstarterで色々眺めたり支援したりしています。 PebbleTime、PebbleTime2、HighPerformanceDjango、Magit、ガジェットっぽいものとかOSS系とかを見ています。

そのうちの一つ、以前DeusExAriaというプロジェクトを支援していました。 これはスマートウォッチに取り付けるデバイスで、腕の筋肉を検知してスマートウォッチの操作ができるというものです。

www.kickstarter.com

これはすごくないですか。

スマートウォッチを愛用している人であれば、ふと時計を見たときに簡単に操作するのであれば片手で済ませれば便利だなと思うと思います。 電車のつり革に掴まっているときなど、片手がふさがっているときは結構多いです。それを解決するDeusExAria、これはすごい、と。 支援したのは2年くらい前で、僕はPebble Timeが大好きだったのでそれと互換があるこの製品も支援しました。

支援したときはプロジェクトの支援を呼びかける動画を見返したり、ワクワクしていました。 Pebble Timeも最高でしたし、このとき気持ちの最高潮を迎えるわけです。

人間面白いもので、他に面白いことがあるとスッカリ忘れるものです。今になって完成した製品が届きました。

ただ残念なことにPebble用のリワードで支援したのに、そのPebble自体が死んでしまったのでAndroidWatch用の製品が届きました。 僕はスマートウォッチへの情熱を失っていたので、全く持って要らないものを手に入れてしまったことになります。 あー、なんとも悲しいスタートアップ支援、というお話でした。

ちなみに今はプロジェクト名が変わって Flicktek となっています。 このプロジェクトが成功したのは純粋に嬉しいのですが、僕の求めてたものとはミスマッチになってしまいました。

こんな感じで、クラウドファンディングというのは支援する瞬間こそが気持ちとしての最高潮で、プロジェクトが成功する瞬間や製品が届くのは2の次なのかなと思います (PebbleTime2はどうしようもなく成功してほしかったですが)。 クラウドファンディングは「何かを作ろう」とかのプロジェクトに、お金を払って応援する仕組みですよね。 そういう意味での支援したときが気持ちとして最高潮というのは間違ってないのかもしれません。

応援したい気持ちがあれば支援することはとても良いと僕も思いますし大好きですが、資産の流動性を失っている点や、失敗したときに返金されるかどうかは気をつけたほうが良いですね。 リワードがあっても自分の期待するものとは限りません。 自分の可処分所得というか、その中でも特に使って良い「寄付枠」みたいなものから使うと良いと思います(それにも増してクラウドファンディングは夢があって素晴らしいですが)。

技術書のクラウドファンディング PEAKS も僕もしょっちゅう見ていますが、支援貧乏にならないようには気をつけたいと思います。 見返りを期待しない程度に留めるのが良いのではないでしょうか。 そのほうが夢があって素敵ですしね。

Ubuntu18.04でIMEの切り替えが遅い気がしたのでibusからfcitxに変えた

Ubuntu18.04を使っていてIMEの切り替えがどうにも遅い気がした。 ほんの0.5秒程度もたくつ気がするレベルなんだけど、HTMLとか書いていると頻繁に英語と日本語の入力を切り替えるのでかなりストレスになっていた。

原因は分からないけど、とりあえずibusから馴染みのfcitxにすることにした。

Ubuntu18.04で、以下でインストール

$ sudo apt install fcitx-mozc fcitx-modules

次にターミナルから im-config を起動。 アプリケーションの「入力メソッド」でも良いです。

$ im-config

設定に従って「fcitx」に変更。 この辺も参考にして、既存の設定消したりもしてね。

kledgeb.blogspot.com

違いはかなり感じるんだけど、こんなに違うもんなのかな。 まぁ、早くなったならいっか。。

Ubuntu18.04はXなので、17.10みたいにWaylandじゃないから苦労はなかった。

blog.hirokiky.org

画面右上のメニューバーにもキレイに映ってるし良かった。