べにやまぶろぐ

技術寄りの話を書くつもり

Embulk で任意のカラムをマスクする embulk-filter-mask プラグインを公開しました

久しぶりの投稿ですが生きております。

ふと Embulk のプラグインを見よう見まねで作ってみました。

github.com

Embulk で転送かけるデータのカラムを指定して * で置換を行うフィルタープラグインです。

センシティブな情報なのでマスクしたい、がカラムごと削ってしまうと入力有無がわからなくて困る…あるいは JSON の一部分だけ不要なんだけど他は連携する必要がある…などの時に使えるかなと思い作りました。

README にもある通り、例えば

first_name last_name gender age contact
Benjamin Bell male 30 bell.benjamin_dummy@example.com
Lucas Duncan male 20 lucas.duncan_dummy@example.com
Elizabeth May female 25 elizabeth.may_dummy@example.com
Christian Reid male 15 christian.reid_dummy@example.com
Amy Avery female 40 amy.avercy_dummy@example.com

というデータを input に食わせた時、

filters:
  - type: mask
    columns:
      - { name: last_name}
      - { name: age}
      - { name: contact, pattern: email, length: 5}

という設定を embulk の config に記述しておくと

first_name last_name gender age contact
Benjamin **** male ** *****@example.com
Lucas ****** male ** *****@example.com
Elizabeth *** female ** *****@example.com
Christian **** male ** *****@example.com
Amy ***** female ** *****@example.com

このようなデータが output に渡されます。

カラム名を指定しただけの状態では単純に文字数分の * に置換されますが、例えばlength オプションで5文字と指定することで一律 ***** とすることも可能です。文字長に意味を持たせたくないときなどによろしいかと思います。

あとは、pattern: email とするとメールアドレスのドメイン部分(@ 以降)は残したままでマスクを行います(デフォルトは pattern: all の全文字置換)。

JSON 型のサポートもしており、

{
  "full_name": {
    "first_name": "Benjamin",
    "last_name": "Bell"
  },
  "gender": "male",
  "age": 30,
  "email": "test_mail@example.com"
}

という構造のデータが入っている user というカラムがあった時、

filters:
  - type: mask
    columns:
      - { name: user, paths: [{key: $.full_name.first_name}, {key: $.email, pattern: email}]}    

などとすると $.full_name.first_name$.email の二つの JSONPath に合致するノードをマスクします。

またこの時、前述の patternlength オプションも個別に指定が可能なので、上記の例の出力は

{
  "full_name": {
    "first_name": "********",
    "last_name": "Bell"
  },
  "gender": "male",
  "age": 30,
  "email": "*********@example.com"
}

のようになります。

指定されたカラムの value が文字列以外の型だった場合は一回文字列に変換したものを置換します。例えば [0, 1, 2, 3] のような配列は ********* になります。

あるいは上の例で $.full_name などと指定すると

  {
    "first_name": "Benjamin",
    "last_name": "Bell"
  }

の部分が単なる文字列として解釈されてまるっと * になります。

だいぶ乱暴というか投げやりなのでこの辺は今後直して各ノードの value 部分だけをマスクして

  {
    "first_name": "********",
    "last_name": "****"
  }

などとできるようにしたいところです。

JSONPath については

github.com

を内部で使っていますので、そこで解釈できるパスであれば基本的に動作すると思います。

また今回プラグインの作り方、特にテストの書き方や JSON の扱い方などは

qiita.com

や、その中でも題材にされている embulk-filter-expand_json プラグイン

github.com

を参考にさせていただきました。ありがとうございました!

Facebook Messenger アプリに隠されたバスケットボールゲームのやり方

Facebook Messenger に隠れバスケットボールゲームがあるという記事 を読んだのですがいかんせんゲームの起動方法がわからない。英語圏のサイトでは basketball emoji をメッセージで送るだけ!って書いてあるんですが絵文字を開いても

f:id:beniyama:20160329000341p:plain

💩 はある癖にバスケットボールの絵文字が見つからない!

日本語のせいなのか自分のせいなのか悩みつつ、他のサイトで見つけた下のバスケットボールの絵文字

🏀

テキスト選択してからコピペしてメッセージで送り、送った🏀をタップしたらちゃんと起動しました。

なお、文章中に混ぜちゃうとダメで、絵文字単体でメッセージとして送る必要があるみたいです。

f:id:beniyama:20160329001747p:plain

ゲーム自体はすでにいろんなところでスクショ貼られていますが成功すると

f:id:beniyama:20160329002145p:plain

になったり失敗すると

f:id:beniyama:20160329002154p:plain

になったりします。

結果もちゃんと

f:id:beniyama:20160329002507p:plain

と日本語で表示されてました。

ちなみに

apps.timwhitlock.info

こちらのサイトによると🏀の名称は BASKETBALL AND HOOP で UTF8 で表すと F0 9F 8F 80 だそうです。Hoop どこいった…

また

emojipedia.org

こちらを見ると Hoop もあったりと同じ絵文字でも端末でだいぶ表現が違うようですね。あんまり絵文字についてこれまで気にしたことなかったので勉強になりました。

BOOKSCAN のプレミアム会員が、月に50冊以上の電子化を試みると何が起きるのか

二年ぶりの BOOKSCAN

およそ二年前に利用した 本・蔵書の電子書籍化サービス BOOKSCAN に再度お世話になりました。今回は実家の本を全て電子化するという目的があったのでプレミアム会員の月50冊上限に合わせて調整した前回より大がかりです。

二年前に初めて電子化した時の記事はこちら。

beniyama.hatenablog.jp

上記の記事でも触れているように、電子化終了後にプレミアム会員を解約して再び今回プレミアム化をしたのですが、途中無料会員の期間を挟んでも以前プレミアム会員の状態で電子化した書籍はマイ本棚に残っていました。通常会員の PDF 保存期間は3ヶ月と書かれていたので、ちょっと嬉しい誤算です。プレミアム会員として電子化したファイルが永続的に残るということなのかまでは確認できていません。

今回電子化したい冊数は304冊。月の無料枠50冊をゆうに超えています。

マイページを見ると

50冊/月スキャン無料 毎月50冊分(冊数の計算方法はこちら)まで無料でスキャン致します。(51冊分以上は、別途対応方法についてご相談させていただきます。)

とあるのですが、肝心の別途の対応方法が知りたいところ。 http://d.hatena.ne.jp/kitokitoki/20140416/p1 に問い合わせ結果が書かれてあり、大体の方向性がわかったのでその上で箱詰めして送ってしまいました。

「冊数オーバーについてのご連絡」が届く

本の到着が確認されると、サポートセンターに冊数超過のお知らせがきます。ちょっと長いですが具体的な金額が書かれているので引用します。

ブックスキャンです。

書籍の到着を確認致しました。
ありがとうございます。

届きました梱包を開封致しまして
弊社規定の方法にて冊数の確認をさせていただきましたところ、
293冊分で確認致しました。
今月分は既に11冊分ご注文いただいており、計304冊分になります。

よって、304冊分 - 50冊分で254冊分が超過している状態です。

書籍のページ数の冊数カウント方法については
以下URLをご参考ください。
URL: http://www.bookscan.co.jp/price.php

今後の処理方法につきまして
以下の方法をご提案させていただきます。
ご都合の良い方法をお選びいただければと思います。
━━━━━━━━━━━━━━━━━━━
1.届いた書籍全てをお客様へ一旦ご返送する
━━━━━━━━━━━━━━━━━━━
お客様へ今回届いた書籍全てをご返却させていただきます。
そのままのご返送になりますので、返送作業料はかかりません。
ただし、送料は着払いになります。
お手元に書籍が届きましたら
冊数を調整のうえ再度ブックスキャンへ
お送りいただければと思います。

【これまで1のみでしたが、お客様のご要望にお応えし他の案もご用意致しました。】

━━━━━━━━━━━━━━━━━━━
2.通常会員分として処理する
━━━━━━━━━━━━━━━━━━━
超過冊数分を通常の納期にて対応させていただきます。
この場合、現在ですとおよそ2ヶ月待ちになります。
お客様ご自身で超過冊数分の通常申し込みを行っていただき、
その後、発行された管理番号をこのメールへ返信にてお伝えください。

また、通常料金に加えまして変更作業料として税込¥1,080.-、
さらに保管期間が発生するため保管料として¥30×254冊分で¥7,620、
税込で¥8,230.-となり、税込合計金額と致しまして¥9,310.-を頂戴致します。

■内訳
変更作業料(¥1,000/件)
保管料(¥30/冊)
【別途通常のご注文の確定が必要です】
━━━━━━━━━━━━━━━━━━━
3.超過している書籍をお客様へ一旦ご返送する
━━━━━━━━━━━━━━━━━━━
お客様へ超過分の書籍をご返却させていただきます。

返送作業料が¥500で 税込¥540.-、
送料が¥1,000×6箱で¥6,000で 税込¥6,480.-となるため
合計で 税込¥7,020.-が必要になります。
※申し訳ございませんが、トラブル防止のため書籍の選択は出来ません
━━━━━━━━━━━━━━━━━━━
4.翌月以降のプレミアム分として保管し、順次処理する
━━━━━━━━━━━━━━━━━━━
翌月以降もプレミアム会員をご継続いただく前提で、
超過している書籍を50冊分を上限に月別に移し替え管理番号を新たに発行し
翌月分以降のお客様のプレミアム会員枠にて順次ご対応させていただきます。
※プレミアム会員費は毎月の自動引き落としによりお支払いいただく形になり、
振り分け登録しました超過分はプレミアム会員更新後の作業開始となります。

小分け作業料・変更手数料と致しまして、
¥100×254冊分=¥25,400で 税込¥27,432.-を頂戴することになります。
※申し訳ございませんが、トラブル防止のため書籍の選択は出来ません

■内訳
小分け作業料・変更手数料 (¥100/冊分)
━━━━━━━━━━━━━━━━━━━
5.このままお受けして、プレミアム枠分と一緒にスキャンする
━━━━━━━━━━━━━━━━━━━
1冊分あたり¥350をお支払いいただくことで、
プレミアム枠の書籍としてお送りいただいた分と合わせて作業し、
1週間を目安に納品させていただく事が可能です。

追加料金は¥350 × 254冊分=¥88,900となり 税込¥96,012.-になります。

■内訳
スキャン・お急ぎスキャン (OCR・名前変更無料)(¥350/冊分)
--------------------------------------

上記から、ご希望の方法をお選びください。

1をご希望の際はその旨お申し付けください。
早急にご返送の手続きを致します。
その他のプランをご希望の際は、以下の口座へお振込みいただけましたら
お手数ですが再度サポートセンターまでご連絡をいただければと思います。

▼振込先
XXXXXXXX

その他の案をご希望でしたら、
可能かどうか検討させていただきますのでご返信いただければと思います。

ご不明点等ございましたらお問い合わせください。
何とぞよろしくお願い致します。

実際いくらかかりそうなのか?

注意しないといけないのは会費が含まれていないので、書籍を処理する期間に応じてトータルの支払いが変わるであろうという点です。 なのでそれぞれのパターンについて自分なりに計算してみました(正式な見積もりではないので間違っている可能性があります)。

プレミアム会員状態でのスキャンと比較するためにOCRと名前変更付きオプションをつけて計算しています。 また、返却の選択肢 1.届いた書籍全てをお客様へ一旦ご返送する3.超過している書籍をお客様へ一旦ご返送する は除外しています。

2.通常会員分として処理する

プレミアム会員を初月で解約したとして、

  • プレミアム会員費1ヶ月分 : 9,505 x 1.08 = 10,266 円
  • 通常会員としてのスキャン(OCR・名前変更付き) : (100 + 100 + 50) x 254 x 1.08 = 68,580 円
  • 変更作業料 : 1,080 円
  • 保管料 : 30 x 254 x 1.08 = 8,230 円

合計(多分) 88,156 円(ただし超過分のスキャンは早くても2ヶ月後に開始 & PDFの保持期間はおそらく3ヶ月)

4.翌月以降のプレミアム分として保管し、順次処理する

304冊 / 月50冊 で全部で7ヶ月間プレミアム会員を継続する必要があります。

  • プレミアム会員費7ヶ月分 : 9,505 x 7 x 1.08 = 71,858 円
  • 小分け作業料・変更手数料 : 100×254 x 1.08 = 27,432 円

合計(多分) 99,290 円(ただし全ての書籍のスキャンが終わるのは7ヶ月後)

5.このままお受けして、プレミアム枠分と一緒にスキャンする

プレミアム会員初月以内に全ての処理が終わる前提です。

  • プレミアム会員費1ヶ月分 : 9,505 x 1.08 = 10,266 円
  • スキャン : 350 × 254 x 1.08 = 96,012 円

合計(多分) 106,278 円(最も高いが初月中に全て完了・PDF保存期間無制限)

どのプランも高いですが、あとは総作業期間がどれだけ気になるかでしょうか。

プランが決まったらメール中に指定された口座に振り込みを行い、サポートセンターへの返信を行った後に着金が確認されると処理が開始されます。

あくまで個人的に計算してみた結果ですので、実際にご利用なされる際はサポートセンターに問い合わせをお願いいたします。

ちなみにスキャンした場合に何冊分になるかや電子化を拒否されていないかなど手軽に確認できるアプリが公開されているので本の選別に活用できます。

BOOKSCAN Checker

BOOKSCAN Checker

  • BOOKSCAN Inc.
  • ユーティリティ
  • 無料

StaticPress で静的化した WordPress を S3 に置いてデザインが崩れた時は css の Content-Type を確認しよう

大学時代の研究をまとめたサイトを WordPress で構築して EC2 でホストしてたのですが、

  • ラトビアあたりからの不正ログイン試行のアラートが Wordfence から頻繁に送られてくるようになった
  • そもそも更新もしないし PV も少ないし micro インスタンスでも運用するコストが見合わない

という理由で静的化プラグインの StaticPress で静的化して S3 から配信することにしました。

今回作業したのはこちらのサイト。

beniyama.com

具体的な作業内容はまたどこかで書ければと思うのですが、諸々の設定が終わった後はまったのがデザイン崩れ。崩れというより css が当たっていない。

f:id:beniyama:20160104234324p:plain

テーマが対応していないとダメだ、という記事も見かけたのですが結論としては css のファイルが S3 アップロード時に Content-Type:text/plain になってしまっていたのが原因。Content-Type:text/css に変更することで問題なくデザインが適用されました。

/tmp/static 以下に StaticPress で静的 html を吐いたとして、

s3cmd put -r --acl-public /tmp/static/* s3://<バケット名>

などとするとバケットにファイルが転送されますが、そのままだと css ファイルのメタデータは下記のようになってしまいます。

f:id:beniyama:20160104235300p:plain

s3cmd でバケット内のファイルのメタデータを一括変更することが可能ですので、続けて

s3cmd modify --add-header='Content-Type':'text/css' s3://<バケット名>/*/*.css

などとすればバケット内の全 css の Content-Type が書き換わります。

f:id:beniyama:20160105002652p:plain

これで WordPress と同じデザインが再現されました。

ちなみに余談ですが、http://jushock.hateblo.jp/entry/2014/08/05/203840 に書かれている

記事のタイトルは 〜.html というリンクになっているがアクセスするとディレクトリになってしまうという事だった。

という問題にもはまり(ページ名.html というディレクトリができてしまう)、試行錯誤した結果、パーマリンク設定のカスタム構造は

http://beniyama.com/%category%/%postname%/

で落ち着きました(%postname%.html などとしなくて良かった)。

参考)

Runtastic で始める中年エンジニアのヘルスケア

遡ること7月、転職前に受けた健康診断でお医者様に「肝臓壊れてるね〜」と言われ、それから節酒&食事改善&運動の習慣化などを始めました。

せっかく運動するんだからヘルスケア系のサービスを使ってみようと思い、只今絶賛 Runtastic まみれになっています。

きっちり競合比較していませんが、Runtastic の特徴は最も知名度のあるであろうランニングアプリ「Runtastic」だけでなく実に多様な、というか多すぎるくらいのアプリの品揃えだと思います。

https://itunes.apple.com/jp/app/runtastic-pro-gps-ranningu/id366626332?mt=8&uo=4&at=1010l7Ba

2015/10/3 現在、App Store には iPhone アプリだけで29種(PRO / Lite 版含む)も上がっていました

例えば腹筋運動だけ見ても CG を活用した多彩なトレーニングを提供する「Runtastic Six Pack」と単純に腹筋のカウントだけする「Runtastic Sit Ups」の2つが提供されています。

https://itunes.apple.com/jp/app/runtastic-six-pack-fu-jinwo/id685857245?mt=8&uo=4&at=1010l7Ba

https://itunes.apple.com/jp/app/runtastic-sit-ups-pro-fu-jinkaunto/id570183057?mt=8&uo=4&at=1010l7Ba

他には腕立て専用やスクワット専用、歩数計、体重計…などなど割とそれぞれの機能に特化してアプリが作られています。ただ、先ほどの腹筋アプリのように若干機能・ジャンルが被っているところがあって紛らわしいです。

また Runtastic 社からはいくつかデバイスも提供されており、自分は腕につけて使用する活動量計 Runtastic Orbit を使っています。

[asin:B00M1UILU8:detail]

Orbit は歩数のカウントや消費カロリーの計算、また睡眠モニタリングなどを行うことができます。Fitbit のようにおしゃれでもなく心拍も取れませんが、この辺は Watch OS2 の登場で AppleWatch から心拍が取れるようになったりしているのでそれで代替できるようになるといいなと思っています。Orbit は Runtastic Me というアプリでデータを吸い上げ管理します。

https://itunes.apple.com/jp/app/runtastic-me-bu-shukauntotsuki/id893528604?mt=8&uo=4&at=1010l7Ba

しかしながら先に挙げたように歩数計が Runtastic Pedometer、睡眠モニタリングは Runtastic Sleep Better というそれぞれのアプリ単体で動作するものが別にあってまたややこしいです。

https://itunes.apple.com/jp/app/runtastic-pedometer-pro-bu/id442894126?mt=8&uo=4&at=1010l7Ba

https://itunes.apple.com/jp/app/runtastic-sleep-better-mu/id922541792?mt=8&uo=4&at=1010l7Ba

なんとなくアプリに Orbit を足すとより精緻なデータが取れるようになると思ってしまいますが、そうではなくあくまで別アプリの別データとして管理されます。

Runtastic の各種アプリで記録されたデータはポータルサイトから確認することができます。

f:id:beniyama:20151003163445p:plain

走行距離や消費カロリーの記録、また体重・体脂肪率の変遷を可視化したりもできます。

f:id:beniyama:20151003163501p:plain

ちなみにこれは自分の実際のログです。体重・体脂肪率は記録するタイミングによって結構ぶれるのであまり綺麗なグラフではないですが、とはいえ運動開始時より着実に落ちてきている実感はあります。

この体重・体脂肪は体重管理アプリ Runtastic Libra で記録できるのですが、ワイヤレス体重計 Runtastic Libra(同じ名前です)を使うと体重計に乗るだけで自動的にデータを飛ばしてくれ、かつ筋肉量や骨質量といった値も取れるようです。

https://itunes.apple.com/jp/app/runtastic-libra-ti-zhonggurafu/id694034625?mt=8&uo=4&at=1010l7Ba

しかしながらこの体重計、日本語の案内はあるものの公式ストアに行くと日本からの購入に対応していないらしく購入することができません。他のサイトで取り扱っているところもあるようなのですがだいぶ高い気がするので、自分は体重・体脂肪率を手打ちで入力しています。

現状、連携したアプリのデータをまとめて見られます程度でデザインだったりデータの見せ方だったりはまだ改善の余地があるものの、そもそも運動や体の状況の可視化をしたことがない人にとっては十分生活習慣の改善のきっかけになりうるサービスだと思います。

もう少し効果が出始めてきたら個別アプリのレビューを書いていきたいです。

OS X El Capitan にアップデートして App Store などに繋がらなくなった時の対処法

App Store からカジュアルに OS アプデできるようになったのは良いのですが、Apple のアプデは危険ということを忘れうっかりポチッとすると人柱真っ逆さまだよというお話です。

仕事を終えてふと愛機を El Capitan に更新した直後から挙動がおかしくなり、

  • CPU 使用率が異常に高くなりファンが止まらない
  • Office 365 のログインページなど特定のサイトに繋がらない(その後はブラウザを再起動しないと他のサイトにも繋げなくなる)
  • 挙げ句の果てには App Store に繋がらない(= 修正版リリースされてもアプデできない!\(^o^)/)

となってちょっと途方に暮れていたのですが色々調べていくと SSL 周りの不具合だということがわかり、結論としてはキーチェーンで証明書の使用ポリシーを変更することで解消できました。

「キーチェーンアクセス」を立ち上げ、左上の項目(キーチェーン)で「システムルート」を選択。VeriSign を検索します。

f:id:beniyama:20151002233740p:plain

ここで表示された証明書を片っ端からダブルクリックで開き、「▶︎信頼」を展開して「この証明書を使用するとき」を「システムデフォルトを使用」に変えます。

f:id:beniyama:20151002234125p:plain

これで App Store などにつないでみて正常に表示されれば、ひとまず危機的状況は脱出したっぽいです。

参考になったのはこれらのポストでした。

forums.developer.apple.com

forums.developer.apple.com

ちなみに Safari や Chrome では上記のサイトも見られなくなってしまうのですが、自前で証明書を管理している Firefox だと今回の問題の影響を受けません。

症状も改善したのでスクショとって意気揚々と記事あげようとした間際、すでに昨夜のうちにえふしんさんがさらっと書かれていたことに気づいたのですが、せっかくなのでこのまま公開しちゃいます。

f-shin.net

自分の場合は VeriSign の証明書を変更するだけで App Store につながったので、このケースより楽でした。

Mac でコーディングする人は「スマート引用符とスマートダッシュ」を OFF にしようという話

突然ですが問題です。

下記の一見同じに見える二つのクエリ、実は意味が異なるのですがその違いがわかりますでしょうか?

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

これでわかったらかなりの選球眼の持ち主です。

それでは試しにシンタックスハイライトをかけてみましょう。

-- クエリ1
SELECT * FROM customers
WHERE customer_id IN ('0001', '0002', '0003', '0004');

-- クエリ2
SELECT * FROM customers
WHERE customer_id IN ('0001’, ’0002', '0003', '0004');

いかがでしょうか?これでもよく見ないとわからないと思います。

正解は、クエリ1の customer_id の一致条件が 00010002000300044パターンなのに対し、クエリ2は 0001’, ’0002000300043パターンだということです。よく見るとクエリ2の IN 句内の最初のカンマが文字列の一部になっているのがわかると思います。

明らかに意図したクエリになっていないのですが、なぜそもそもこんなことが起きるかというと問題は Mac 標準の入力サポート機能にありました。

「システム環境設定」から「キーボード」を開くと「ユーザ辞書」のタブ内に「スマート引用符とスマートダッシュを使用」という項目があります。

f:id:beniyama:20150924232105p:plain

これが ON になっているとテキストエディタなどで SQL を編集した際に勝手にシングルクォーテーションや二重引用符を変換されてしまい、予期せぬ意味のクエリになってしまう可能性があります。

https://support.apple.com/kb/PH14294?locale=ja_JP&viewlocale=ja_JP によれば

まっすぐな引用符を体裁上適切な(「丸い」)引用符に自動的に置き換えます。

とあります。体裁上は適切かもしれませんがコーディング上は不適切なわけです。

自分のケースでは軽く Evernote 上でコピペと編集を繰り返しているうちに、上述のようなエラーにはならないんだけど意味が違うクエリが生まれてしまいました。検算して初めて問題と原因に気づいたので軽く冷や汗かきました。

ちょっとしたクエリなどは手元のエディタで編集して〜とやりたくなりますが、Mac を使われる場合はその前に一度キーボードの設定を見直そうというお話でした。

参考)