Kindle書籍を買ったけどダウンロード・配信できない問題と解決法
ググっても今回起きた問題と同一のものが見つからなかったのでメモしておきます。なおTwitterで検索したら数件見つかったのでごく稀に起きる現象のようです。
今回の現象
- 12月14日0時頃、1-Clickで購入
- 購入完了画面が出る
- Kindle Cloud Readerで読む→試し読み版になる*1
- 配信ボタンを押してもできませんと出る
- Android端末はグーレアウト
- Kindle Cloud Reader, iPod Touchの配信ボタンは押せるが、配信できませんと出る。
- 注文の詳細・領収書は見れる
- 注文履歴に入っている
- 未発送の注文にも入っている*2
- ご注文の確認メールが来ていない
特徴としては、ご注文の確認メールが来てない所になるかもしれません。
解決法
といっても大したことではなく、お問い合わせしただけです。
- 画面下部メニュー、右下「カスタマーサービスに連絡」
- 「カスタマーサービスに連絡」ボタン
- お問い合わせ方法を選択: 電話、チャット、Eメールの3択
- 夜中だったのでEメールにした
- 適当に埋める
- 注文番号とかも書いておいた。
翌日
- 3時頃にご注文の確認メールが来た様子
- 10時頃にお知らせメールが来た
このたびは、Kindle本のご注文について、ご迷惑をおかけしていることをお詫びいたします。
12月13日から14日にかけてご注文いただいたKindle本について、注文の処理に時間がかかりダウンロードが開始されない件について、問題が修復いたしましたのでお知らせいたします。
なお、この問題が発生している間に、同じKindle本を重複してご注文いただいている場合、一方の注文をキャンセルし、返金処理を行います。返金処理が完了しだい、Eメールでお知らせいたしますので、今しばらくお待ちください。(本メールと入れ違いで、お受け取りいただいている場合はご容赦ください。)
その他、ご不明な点がございましたらご遠慮なくお問い合わせください。
どうせこんなことだろうと思い、重複注文しなくて正解でした。
Kindle配信の仕組みの推測
- step
- ユーザ: 1-Clickで購入ボタンを押す。
- step
- サーバ: 該当商品を購入キューに入れる。
- ユーザ: 画面が切り替わる。
- step
- サーバ: なるはやでキューが処理される。完了時にご注文の確認メール送信。
- ユーザ: KindleReaderで書籍をダウンロード。
今までも購入後、Kindel Cloud Readerで読む時にお試し版になる現象は何度も起きていました。この原因は3rdステップのタイミングの問題と推測されます。
今回の問題は、3rdステップのサーバ側処理が何らかの原因でスタックしたことが原因ではないかと推測しています。
Perlワンライナーメモ
至るところで語り尽くされているネタですが、使おっかなーと思うときには大抵忘れており毎回調べる羽目になるので、備忘としてメモします。
perl -e
オプションで与えた文字列をそのまま評価。
# はろーわーるど perl -e 'print "Hello, World!\n"' # モジュールのバージョン確認 perl -e 'use Term::ANSIColor; print $Term::ANSIColor::VERSION, "\n";'
perl -M
モジュールのロードをオプションで指定。
# モジュールのバージョン確認 v2 perl -MTerm::ANSIColor -e 'print $Term::ANSIColor::VERSION, "\n";'
perl -le
処理後にprint $/
してくれる。デフォルトでは$/
は改行コードなので、改行されます。
# モジュールのバージョン確認 v3 perl -MTerm::ANSIColor -le 'print $Term::ANSIColor::VERSION;' # インストール済みCPANモジュール一覧表示 # https://gist.github.com/s-shin/10267831 perl -MExtUtils::Installed -le 'print join "\n" => sort ExtUtils::Installed->new->modules;'
perl -ne
ループ内while (<>) { HERE }
のような感じでコードを評価。
# $_には"foo\n"と"bar\n"が渡る。 echo -e "foo\nbar" | perl -ne 'print $_'
perl -pe
ループ内while (<>) { HERE; print $_; }
のような感じでコードを評価。
# $_には"foo\n"と"bar\n"が渡る。処理後の$_は自動的にprintされる。 echo -e "foo\nbar" | perl -pe 's/^(.*)$/$1\n/g'
perl -ple
ループ内while (<>) { chomp; HERE; print $_, "\n"; }
のような感じでコードを評価。
# $_には"foo"と"bar"が渡る。処理後の$_は自動的にsayされる。 echo -e "foo\nbar" | perl -ple 's/^(.*)$/$1\n/g'
perl -i
ファイルによる入出力。
# "[...]"を"{...}"に置換。ファイルはa.txtに上書き。 perl -i -ple 's/\[(.*)\]/{$1}/g' a.txt # "[...]"を"{...}"に置換。a.txtに上書きされるが、元ファイルはa.txt.bkとしてコピーされる。 perl -i.bk -ple 's/\[(.*)\]/{$1}/g' a.txt
しーぱんおーさーになってみた
いわゆるCPAN Authorデビューしたのでその記録。
何作ったのか
RNCryptorというAESのベストプラクティス的なファイルフォーマット及びiOSライブラリがあるのですが、
The primary target is Objective-C, but implementations are available in C++, C#, Java, PHP, Python, Javascript, and Ruby.
RNCryptor/RNCryptor · GitHub
Perl版が無い…ということでRNCryptorフォーマットを取り扱うためのPerlモジュールを作りました。その名もCrypt::RNCryptorです。
余談:暗号化の面倒くさいお話
何故にこんなものを作ったのかというと、最近、Perl・iOS・Androidで共通鍵暗号のAESを扱う機会があったのですが、AESもとい暗号化というものは想像以上に面倒ということが分かり、いい感じのライブラリを探していたらRNCryptorに辿り着いたものの、Perlの実装がなかったというわけです。
もっとも、実際の所、Perlだけで暗号化・復号する分にはそれ程面倒ではないです。
AESであれば、Crypt::CBCで-cipher => 'Crypt::OpenSSL::AES'
を指定すれば後はライブラリがよしなにやってくれます。
ですが、これを別のプラットフォームに送るとなるとこれが結構厄介で、色々取り決めが必要となります。
例えばAESの場合、暗号化を行う際に考慮すべきファクターは、ざっと思いつくだけでも以下のようになります。
- 暗号利用モードをどうするか
- 鍵の長さをどうするか
- 今は32文字*1のAES256が主流っぽい?
- 鍵をどう取り扱うか
- IVをどうするか
- 使わない(全部0固定にする)のか、使うならどうやって渡すのか。
- (そもそもIVとか初耳だった…)
- paddingをどうするか
- 等々
いやはや面倒ですね。
てなわけで、RNCryptorはこの辺りをトレンドを踏まえつついい感じに決めてくれています。
実は、OpenSSLも独自の取り決めを作っており、
'Salted__' + Salt(8 byte) + CipherText(16 x n byte)OpenSSLの暗号文をJava/Perl/Rubyで開く - mixi Engineers' Blog
というヘッダを暗号化データに付けるようですが、それ以外についてはストレッチング1回とか、ある程度決めの部分があるようです。詳しくは以下の記事をば*2。
RNCryptorはOpenSSLより汎用的*3で頑強な*4設計になっています。
そしてなによりObjective-CやJavaのライブラリが既にあるのが一番大きな強みです。
閑話休題。
CPANモジュールの作り方
モジュールの作成には、tokuhirom氏謹製のMinillaを使いました。
この手の支援ツールはExtUtils::MakeMakerやShipItなど色々あるようですが*5、Minillaはその中でも最も新しい統合的なオーサリングツールといえるかと思います。
Minillaの基本はこんな感じです。
# インストール cpanm Minilla # 大枠作成 minil new Crypt::RNCryptor cd Crypt-RNCryptor # 好みのエディタでコード書く atom . # テスト minil test # リリース minil release
Minilla Tips
慣れるまで戸惑う点が結構あったので記録しておきます。
README.mdは直接いじらない
メインモジュール(例えばCrypt::RNCryptor)のPODが自動でREADME.mdとして出力されます。
Travis CIを使う
シンプルなモジュールなら自動生成の.travis.ymlで問題無いです。
README.mdにバッジを表示したい場合は、minil.tomlに
badges = ["travis"]
を追記します。ここを変えればcoverallsのバッジも置けます。
テスト
minil testはgitリポジトリの今の状態をサンドボックス環境へ持ってきて、その中でテストしてくれます。そのためか、新規ファイルはgit addしておく必要があります。
サンドボックスが必要ないのであれば、普通にproveしても問題無いです。
余談ですが、proveする際には、Test::Prettyを入れて、.provercを以下のようにすると幸せになれます。
--lib --color --failures --trap -P Pretty --verbose
$VERSIONは触らない。
Minillaが勝手にインクリメントとかするようなので、手動での変更は必要ありません。
gitでバージョンのtagは付けない
minil release時に自動的に付けられるので、必要ありません。
Changesの編集
この辺りの仕組みはよくわかっていないのですが、ChangesというのはCPANのSpecial Filesの1つで、CPANにアップする際には、Changesファイルに変更内容を記述するのが慣例のようです。
この時、タイムスタンプを入れる必要がありますが、これをMinillaが自動的に入れてくれます。
minil relase前に{{$NEXT}}の下に色々書くよう習慣づければ良さそうです。
{{$NEXT}} - write something
minil release時の"missing user argument ... UploadToCPAN.pm"エラー
よっしゃ書いた書いた公開しちゃうぜー、というノリでminil releaseしたら出てきたエラーです*6。
結論から言えば、~/.pauseファイル(PAUSEに関しては後述)が無いor記述が足りない場合に出ます。
minil releaseするには、以下のような~/.pauseを作成しておく必要があります。
user sshin password himitsu
しかし、生のパスワードを書くのは抵抗があるのですが、何とかならないのでしょうかね。今のところ対応策が見つけられてないのですが…仕方ないので、releaseの時だけ書いて、終わったら消してます。
PAUSEに登録
gemsとかnpmにはモジュールを公開するのにユーザ登録が必要ですが、CPANにももちろんあります。それがPAUSE(The [Perl programming] Authors Upload Server)*7です。
少し驚きだったのは、歴史が長いからかアクティブユーザ数が少ないからかは分かりませんが、何かと人によるチェックが入るところです。そして登録フローもまたアナログです*8。
人が絡む最大のメリットは世界のPerl Mongers達がdisってくれることらしいです。
DISられるということは、それだけドキュメントやコードをを読んでいただいている証拠...だと思うので、DISには感謝しましょう。
何事からも学び、そして感謝するのです。謙虚な姿勢が大事なのです。アザマス!!
「CPAN Author になったよ」のつづき - hayajoのはてなブログ
Minilla使えば、コード関係ない所でdisられることはなくなるんじゃないかな(汗。
モジュール公開までの流れ
一応、公開までの流れを簡単に書いておきます。