Kotoriの問題点を考えてみる

前回の記事

やる気が欲しい
どうも、やっと就職先が決まった赤西真論です。 就活が終わったのでホッとしております。後は問題を起こすこと無く卒…

書く気力があるうちに次の記事を書きます。てか、バイトが無い日じゃないとこんなことやる気力が出ません。バイト自体は18時~22時なのに、なぜか昼間からやる気が出ません。どうしたもんかねぇ

さて、この記事では前回紹介したKotoriの技術的なお話と問題点を考えていきます。いきあたりばったりで書いていきますよー

 

技術的な面

ソースコードはもちろんオープンソースになっています。

marron-akanishi/kotori
Doujinshi Management Application. Contribute to marron-akanishi/kotori development by creating an account on GitHub.

KotoriはRuby + Sinatra + ActiveRecord(SQLite)をバックに利用し、jQuery + Honokaをフロントに利用しています。まあ、ごく一般的なWebアプリケーションです。

さて、今回なぜいつもPythonを使ってる僕がRubyを使ったのか。簡単なことです。Rubyを書いてみたかった、ただそれだけです。

別にTwitter APIを触るわけでも無いし、画像認識するわけでも無いから使ったこと無い言語で書くかーってなっただけです。

初めての言語で書くアプリケーションのサイズじゃないんですけど、これ…

すげー大規模になってしまって、Sinatraで良いのかこれ?Railsのほうが良いのでは?レベルになっています。

あと、ActiveRecordというかORマッパーを真面目に使うのが初めて全然使い方が分かりません。SQL文直書きしたい気分になっています。

フロントに関してはまあいつも通りって感じなんですけど、TakaneでVueを使って便利だと感じたので書き直したい気分になっています。というのも大枠に関してはerbで書いているのですが、リストであったり詳細情報に関してはAjaxで別のAPIを叩いてjsonを取得しているので、十分Vueで書けるんですよね。てか、erbで条件分岐書いたりしてるのでコードがえらいことになっていて…

今回はデータベースがメインのページということでER図もVisioで作成しました。割と面白い状態になっているので、載せます。別に全部オープンソースなのでデータベースの形状がバレてもいいです。見る人が見るとなんじゃこりゃっていう設計ですが…

クリックで拡大されます。中心はbooksテーブルです。ここがほとんど本体みたいなものです。もう一つ重要なのがusersテーブルです。これもまあ必須ですよね。

それらをuser_booksテーブルで繋いでいます。今回は中間テーブルを使ってテーブル同士を繋いでいます。一般的な正規化の感じですね。十分とは言えませんが…

booksテーブルの右にあるのが書籍の詳細情報として利用するテーブルです。大体カラム名で分かると思うのですが、使ってない項目が割とあります。この項目が全部使えるようになるのが1つの目標です。必要なものは大体付けたと思っています。まあ、必要になれば拡張するんですけど…

ちなみにこの設計は一度やり直しています。すべてのテーブルにcreated_atとupdated_atを付けるのべきなのに付けてなかったのとタグ、ジャンル、著者が複数になることを考慮して中間テーブルを設置するべきなのに設置していなかったからです。ちなみに頒布イベントとサークルに関しては複数になることは稀だと考えたため1対1で繋いでしまっています。

書籍情報収集時のスクレイピングですが、基本的にNokogiriでやっています。ただ、18禁表示チェックがサイトごとに異なる実装で回避が大変でした。

まず、メロンブックスです。ここは一番情報量が多く必要な情報がすべて載っています。ですが、18禁表示チェックがよく分からなくて困りました。URLをずっと見ているとあるパラメータを付けると18禁表示チェックをスキップして情報を表示してくれることが分かったので、URLにアクセスしてみて表示されないようだったらそのパラメータを付けてもう1度アクセスするといった感じになっています。

次にとらのあなです。ここは超簡単でURLの時点で分けてくれているのでそのまま貼り付けられたURLにアクセスするだけで行けました。

最後にらしんばんです。こいつが一番の曲者でした。18禁表示チェックをセッションごとに行っているので、認証が通ったセッションを持ったまま詳細ページに進む必要があります。色々調べた結果、Mechanizeを使えばいけました。ここが実装的には一番きちんとしているかもしれません。

実は駿河屋対応も考えたのですが、引っ張ってこれる情報が少なすぎるので止めました。個人的には中古で買うことも多いので、対応させても良かったのですが…

問題点

さて、問題点を考えていきます。前の記事も見ながらのほうが良いかもしれません。というか僕自身が前の記事を見ながら書いてますw

マイページ(所有書籍一覧画面)

初っ端から大幅な仕様変更が必要になっています。こちらをご覧ください。

これはマイページを表示する際にバックで通信しているAPIです。4つ表示されていますね。これ、何をしているのかというと著者すべて、書籍すべて、著者と書籍の中間テーブルすべて、自分のみに絞り込んだユーザーと書籍の中間テーブルを取得しています。

は?っていう感じですよね。僕も思います。

なんでこんな仕様になっているのかというとActiveRecordで中間テーブルを介したテーブルの連結方法が分からないんですよw

なので、JavaScriptで無理やりくっつけています。でくっついたデータからユーザー書籍テーブルを利用して必要な書籍を取り出し、表示しています。ものすごいというかアホというか脳筋すぎる実装です。絶対にやっちゃダメです。

これやると取得に超絶時間がかかります。ここも僕の悪いクセなんですけど、非同期が嫌いすぎてAjax通信時に非同期を切ってますw なので、全部取得が完了するまで表示されません。意味が分からん!

これはマジで直さないとダメです。本当はページごとに通信をして、50件ずつとかの取得にしたいんですけど、それをすると検索時のレスポンスが下がって使い勝手が悪くなるので、所有書籍を一番最初に取得するのだけは譲れないポイントではあります。これが1000件とかなってくるとどのぐらいレスポンスが悪くなるのかが未知数なんですよね。SQLiteの時点で遅いのに…

次は検索部分ですね。検索としか書いてないので、範囲が全然分かりませんがタイトルでしか検索出来ません。これの範囲は出来れば書籍情報すべて+メモにはしたいです。所有登録日とか発行日とかの範囲設定も出来たら良いかもしれません。そうなってくるとやはり検索欄1つだと足りないので、折りたたんで詳細検索ぐらいでも付けるのがベストですかね…

次はソート部分です。これは所有登録日とタイトルにしか対応してないんですけど、著者ぐらいも必要かなと思ってます。絞り込みでは無いので、詳細情報すべてみたいなのは要らないと思っています。それなら検索で絞り込んでくれって感じになります。

最後に1ページ当たりの表示数ですね。これは今グリッドビューが30件、リストビューが50件で固定です。僕としてはあんまり困っては無いんですけど、人によっては1ページに100件表示したいとか25件ぐらいにして欲しいとかあると思うので、最低限対応しようかなと思っています。

どの機能を付けるにしても最初に一覧取得の部分を変えないとダメですね。あと、URLのパラメータとしてソート順や表示数を渡していないので他のページから戻ってきた時にリセットされてしまいます。これに関してはグリッドビューとリストビューの切り替え情報をCookieに保存しているので同じように保存してしまえば問題ないと考えています。

書籍詳細画面

ここはまずパンくずリストが欲しいです。

実は最初このページには戻るボタンが付いていました。ですが、今はありません。理由は来たページが分からないという面白い状態だからです。

この画面に来る方法ってマイページ・登録一覧・情報編集後・外部からのアクセスとまあ様々あるんですよね。なので、1つのボタンに付けると全部網羅して条件分岐を書く必要があります。めんどくさいです。

なので、外しました。最初はブラウザの戻るボタンと一緒でもいいかなーってなったんですけど、それをすると情報編集画面に戻ってしまうという問題が発生して、使い勝手が悪いので却下しました。

でも、パンくずリストのほうが難しいんですよね。マイページから来たのか、登録一覧から来たのかさえ分かればいいんですけど、いい方法を考えないといけません。(ちなみにURLを見てもらうとどこから来たのかを格納しようと努力している跡が見れますw)

他はまあ特に問題ないですかね。ここが高機能になる必要は無いので…

登録で著者、ジャンル、タグを複数登録出来るようになった場合はそれを複数表示出来るようにしないといけませんが、まあ簡単に対応できるので大丈夫でしょう。

登録一覧画面

ここもまずはAPIの変更が必要ですね。バックで全データを取得してきているので増えれば増えるほど時間がかかるようになります。なので、取得時点で並び替えと1ページ当たりの表示数を渡してその数だけ取得するようにしようと考えています。

ただ、それをするとまた検索の時に問題が発生するので悩んでいます。全取得かつ名前(タイトル)のみならもしかするとそこまでレスポンスが落ちないかもしれないです。というのも時間がかかるのって中間テーブルを介した情報の連結と検索なので、それが起きない限りはすぐに取得できると思っているからです。大規模なDBを触った経験が無いのでなんとも言えませんが..

マイページ同様にソートとページ当たりの表示数対応も必要ですね。

検索機能は書籍以外の一覧に関しては現状の名前のみでも大丈夫でしょう。問題は書籍です。ここはKotoriに登録されているすべての書籍が集まってくるので、検索機能が重要になってきます。タイトルのみを高速で検索出来るようにし、そのほかの条件に関してはバックで検索をかけるぐらいがちょうどいいかもしれません。全データが含まれたjsonなんてどんな規模になるのか分からないので…

各詳細画面

書籍詳細画面以外の詳細画面です。

これに関しては前回の記事でも言ったとおり、サークル詳細に関してはどうせならサークルのHPレベルで情報が載せられるようにしようと思っています。どれだけサークル側の協力を得られるかが重要になってきますが…

著者詳細もまあなるべく説明が欲しいかなと思っています。別にサークル詳細とのリンクだったり、pixivやTwitterなどのリンクだけでも良いとは思いますが…

その他のジャンル、イベント、あとは後ほど追加予定のタグに関しては現状のままでも問題はないかと思っています。イベントの開始終了日時に関しては、コミケぐらい大規模にならないと複数日程で組まれないのでどうしようかなって感じです。ただ、これを登録しておくと書籍登録時にイベントを指定しただけで日時が自動入力されるという機能を付けることが可能になります。誰が登録するんだ問題が一番大きいのですが…

書籍追加画面

こいつも結構問題児なので修正箇所が多いです。

まず、最初のタイトル追加画面ですけど、ここは別に問題が無いと思っています。URL貼っつけて決定押すかタイトルを手動で入力するかなので…

問題は次です。タイトル入力後の一致検索です。

この部分に関してはバックで検索を行っているのですが、ActiveRecordの検索(find_by)をそのまま使っているので完全一致検索になっています。これが大問題です。

完全一致検索ということは半角全角スペースも別物として判定されます。これが結構厄介です。ここに表示されないと登録されていないと思われて、重複登録になってしまいます。なので、上手く検索をかける方法を実装する必要があります。

これは著者、サークル名、ジャンル、頒布イベント名、タグでも同じで重複登録が一番厄介です。なるべくすでに登録してあるデータと同じになるように作ってもらいたいのでそれを上手く支援する必要があります。

現状の選択機能はうんちすぎるので流石に直します。最低でも入力と同時に検索をするシステムを導入して、全部入力しても出なければ登録ボタンを出すっていう感じにするのが一番だと思っています。また、コミケのように何回目の開催が後ろに付いているものは「コミックマーケット96」「コミックマーケット 96」「コミックマーケット 96」のように3種類入力が出来てしまいます。ここのブレを吸収するにはスペースを消してしまうのが一番ラクなのですが、それをするとおかしくなる可能性があるので、悩んでいます。現状はすべてメロンブックス準拠にしようと思っているので「コミックマーケット 96」が適切になります。まあ、僕が登録したやつはすべて「コミックマーケット96」形式になっているので直さないといけないんですけど…
(2019/08/13 追記)
メロブは「コミックマーケット96」形式でした…

複数登録機能も必要です。まあ、これに関しては追加ボタン→リストから選択→決定を繰り返して複数登録するみたいな感じにするかチェックボックスみたいに複数選択で一括登録みたいな感じにすればいいかなと思っています。表示追加のDOM操作もそこまで面倒ではないので…

発行日部分もちょっとお粗末なんですよね。HTML5のdateインプットを利用しているのですが、これが超クソです。IMEオン状態だとすぐ入力出来ません。なので、どうにかしようと思います。

詳細、メモは廃止予定です。これ、何に使おうと思ったんですかね。感想でも書けるようにします?

タグ機能は後日追加って感じです。DB側にはテーブルが存在するので、枠付ければ完成って感じになっています。

その他

その他の未実装部分だったり、問題点です。

まず、一括登録機能が必要です。一度に複数冊購入して1つ1つ入力しているとめっちゃ時間がかかります。また、初回ログイン後にすでに所有している書籍を入力するのも大変です。てか、100冊程度でも結構時間がかかりました。それもスクレイピング機能実装前だったので、全部手動です。やばいです。

一括登録の方法はURLを一覧で入れてもらってそれを取得するかCSVなどのファイルで一括登録出来るようするのどちらかかなと思っています。ただ、表紙画像を入れるとなるとテキストでは対応出来ないんですよね。URLならそこから画像を引っ張ってくるのでこちらが先に実装されるかもしれないです。ただ、委託されてない本も多いというか大多数がそちらだと思うので、データを流し込めるようにはしたいですね。画像をzipで入れるとかはセキュリティー的に怖いので採用したくないところ…

あとは18禁タイトル表示の切り替えですね。現状は全部出ます。登場人物は全員18歳以上状態です。ダメですね。早く対応させます。ER図を見ればわかりますが、フラグを格納するところは存在するのでそれを利用します。ただし、マイページに関してはこのフラグを無視してすべて表示します。あくまで全一覧画面だけです。

重要なところで言うとエラー処理が全然書けていません。てか、しょっちゅうエラー吐きます。現状は割と高確率でSinatraのエラー画面が出るはずです。問題すぎるので直します。

やりたいこと

上の問題を大体解決出来たら次はこっちも取り掛かりたいですね。

まず、オフライン対応です。やっぱりオフラインでも確認出来たほうが便利なので対応させたいと思うのですが、それをするとなるとやっぱりアプリ化が必要だと感じます。PWAでも出来ないことはないと思うんですけど、どうなんですかね。あんまり調べられてないのでなんとも言えません。

次にChrome拡張機能の作成です。これはメロブとかの詳細画面を表示した際にすでに購入しているかを表示したりだとかすぐにKotoriに登録をするボタンを表示したりだとか出来ると便利かなと思っています。

あとは購入予定リストの作成ですね。これはイベントで購入予定リストを作成すると思うのですが、それの支援機能を付けることが出来るといいかなって思っています。特にサークル側で書籍を登録出来るようにした際にイベント前に登録してもらって、どこで頒布するのかを登録してもらえばいちいち自分でまとめる必要が無いと思うんですよね。まあ、ここに関してはすでにあるアプリとの差別化が必要ですし、それこそオフラインでも使えないと意味がないので難しいかもしれません。

 

とりあえず、こんな感じで

結構長くなってしまいました。お腹が減ったのでこれで終わります。また何かあれば追記していくかもしれません。

投稿者: 赤西 真論

アイマスに人生を変えられ、コードを書くのが嫌いになった大学生

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください