読者です 読者をやめる 読者になる 読者になる

nicovideo Thumbinfo popup の動画情報取得方法その2

ニコニコ動画 Greasemonkey

最近チョビチョビと書き直してる。ポップアップの内容生成オブジェクトを,情報を各所から取得してくるオブジェクトと,その情報から内容を生成するオブジェクトの2つに分けるという計画。
データ取得後の内容生成や,あるデータの値によってデータを取得するURLが変わるようなデータの取得で楽をするためにwatch関数使いまくりになる予定。
で,そのために複数個のwatchに対応したwatchEx, unwatchExというメソッドを書くも妙な挙動に悩まされる。
ひとつめ。存在しないプロパティをwatchするとそのプロパティが生成される。これは仕様なんだろうか…。Firebugのコンソールで確認すると生成されないみたいなんだけど…。スクリプトのバグかも。プロパティが存在しているかどうかではなく,値がundefinedかどうかで判定するようにした。プロパティ値のundefinedに未定義以外の意味を持たせないようにする。
ふたつめ。watchから呼ばれた関数中でunwatchするとプロパティ値がundefinedになる。これはFirefoxのバグくさい。問題の切り分けはできてないのだけど,unwatchの呼び出しをsetTimeoutから呼び出すようにしてやるとundefinedにならなかった。謎。
で,これからデータ取得部分に着手する予定。現行バージョンでは適当に実装してカオスになったからまずはある程度整理しようかと。
というわけで以下にデータ取得順序を示す。

=> videoID
  -> getthumbinfo(videoID)
    => empty -> 「サーバが落ちているかメンテナンス中」
    => ok       -> 通常動画
    => error[deleted]
        -> watchpage(videoID)
          => 取得成功 -> 削除済み動画
          => 失敗     -> 非表示動画?
    => error[invalid] -> 「無効な動画ID or スレッドIDです」
    => error[community]
        -> watchpage(videoID)
          => 取得成功 -> アクセス可能なコミュニティ専用動画
          => 失敗     -> アクセス不可能なコミュニティ専用動画
                         or 動画IDではアクセスできないコミュニティ動画 (要スレッドID)
    => error[otherwise] -> 「予期せぬエラー」
=> threadID
  -> getthumbinfo(threadID)
    => empty -> 「鯖落ちorメンテ」
    => ok    -> 通常動画・マイメモリー
    => error[deleted || invalid] -> 動画IDの場合と同じ
    => error[community]
      -> getflv(threadID)
        => error -> 削除済み・観覧権限無しなど
        => optionalThreadID, videoIndex (videoIDの数字部分)
          -> getthumbinfo(optionalThreadID)
            => ok                -> コミュニティ動画
            => error[community]
              -> watchpage(threadID)
                => 取得成功 -> コミュニティ専用動画
                => 失敗     -> ??? (今のところ該当例無し)
        => optionalThreadID が無い -> 「予期せぬレスポンス」
    => error [otherwise] -> 「予期せぬエラー」

threadID -> error[community] 以下は videoID の場合みたいに watchpage に取りに行けばいいんだけど,それをやらないのは視聴履歴をできるだけ綺麗にしておきたいから。どうひっくり返ってもgetthumbinfoじゃ取得できないチャンネル動画の台頭でこのこだわりは余り意味を持たなくなってきたけど,まあ一応。
getthumbinfoと条件分岐だけで上のグラフ(?)は綺麗に整理できそう。実際のスクリプトの実装はそうする予定。

追記。

整理した。完全に俺文法。

  • > getthumbinfo(optionalThreadID || threadID || videoID)
=> empty -> 「サーバが落ちているかメンテナンス中」 => ok -> videoID: 通常動画 threadID: 通常動画 or マイメモリー optionalThreadID: コミュニティ動画 => error[deleted] -> watchpage(threadID || videoID) => 取得成功 -> 削除済み動画 => 失敗 -> 非表示動画? => error[invalid] -> 「無効な動画ID or スレッドIDです」 => error[community] optionalThreadID: -> watchpage(threadID) => 取得成功 -> コミュニティ専用動画 => 失敗 -> ??? (今のところ該当無し) threadID: -> getflv(threadID) => error -> 削除済み・観覧権限無しなど => optionalThreadID, videoIndex (videoIDの数字部分) を取得 -> getthumbinfo(optionalThreadID) => optionalThreadID が無い -> 「予期せぬレスポンス」 videoID: -> watchpage(videoID) => 取得成功 -> アクセス可能なコミュニティ専用動画 => 失敗 -> アクセス不可能なコミュニティ専用動画 or 動画IDではアクセスできないコミュニティ動画 (要スレッドID) => error[otherwise] -> 「予期せぬエラー」

多分上のと等価。

追追記

実際の実装にあわせて更に追記。あと状態変数を併記してみた。

getthumbinfo(optionalThreadID || threadID || videoID) {LOADING, 'loadingThumbinfo'}
  => empty -> 「サーバが落ちているかメンテナンス中」{ERROR, 'emptyThumbinfo'}
  => ok
    -> videoID: 通常動画 {COMPLETED, ''}
       threadID: 通常動画 or マイメモリー {COMPLETED, ''}
       optionalThreadID: コミュニティ動画 {COMPLETED, ''}
  => error[DELETED]
      -> watchpage(threadID || videoID)
  => error[NOT_FOUNR] -> 「無効な動画ID or スレッドIDです」 {ERROR, 'notFoundErrorThumbinfo'}
  => error[COMMUNITY]
    optionalThreadID:
    videoID:
      -> watchpage(threadID || videoID)
    threadID:
      -> getflv(threadID)
  => error[otherwise] -> 「予期せぬエラー」{ERROR, 'unknownErrorThumbinfo'}

getFLV(threadID) {LOADING, 'loadingGetFLV'}
  => error -> 削除済み・観覧権限無しなど {ERROR, 'flvError', flvData.error = {'invalid_v1', 'invalid_v2', 'invalid_v3', 'cant_get_detail', ...}}
  => optionalThreadID, videoIndex (videoIDの数字部分) を取得
    -> getthumbinfo(optionalThreadID)
  => optionalThreadID が無い -> 「予期せぬレスポンス」 {ERROR, 'flvError', 'invalid_response'}


watchpage(threadID || videoID) {LOADING, 'waitingForWatchPageConfirm' || 'loadingWatchPage'}
  => 取得成功
    error[DELETED]: 削除済み動画 {COMPLETED, ''}
    error[COMMUNITY]:
      threadID: コミュニティ専用動画 {COMPLETED, ''}
      videoID: アクセス可能なコミュニティ専用動画 {COMPLETED, ''}
  => 失敗
    error[DELETED]: 非表示動画 {ERROR, 'invalidDeletedWatchPage'}
    error[COMMUNITY]:
      threadID: ??? (今のところ該当無し) {ERROR, 'invalidCommunityWatchPage'}
      videoID: アクセス不可能なコミュニティ専用動画
               or 動画IDではアクセスできないコミュニティ動画 (要スレッドID)
               {ERROR, 'invalidDeletedWatchPage'}