OSDN Git Service

一部の動画でのコメント取得の不具合を修正。
authordyknon <dyknon@users.sourceforge.jp>
Tue, 15 Apr 2014 11:29:02 +0000 (20:29 +0900)
committerdyknon <dyknon@users.sourceforge.jp>
Tue, 15 Apr 2014 11:29:02 +0000 (20:29 +0900)
nicovideo/access.py

index becab36..ccb8ab2 100644 (file)
@@ -329,16 +329,44 @@ class Video:
                                self.info["play_thread_id"] = play_info["thread_id"]
                        if "nicos_id" in play_info:
                                self.info["play_nicos_id"] = play_info["nicos_id"]
+                       if "optional_thread_id" in play_info:
+                               self.info["play_optional_thread_id"] = \
+                                       play_info["optional_thread_id"]
                        if "ms" in play_info:
                                self.info["play_comments_url"] = play_info["ms"]
                        if "url" in play_info:
                                self.info["play_video_url"] = play_info["url"]
+                       if "needs_key" in play_info:
+                               self.info["play_needs_key"] = play_info["needs_key"]
                else:
                        conn.close()
                        raise err.HttpErr(res.status, res.reason)
                conn.close()
                self.info_downloaded["playinfo"] = play_info
 
+       def get_thread_key(self, thread, lang_id=0):
+               conn = http.client.HTTPConnection("ext.nicovideo.jp")
+               conn.request("GET", "/api/getthreadkey?language_id={}&thread={}".
+                       format(lang_id, thread))
+               res = conn.getresponse()
+               key = {}
+               if res.status == 200:
+                       raw_body = res.read().decode("ascii", "replace")
+                       logger.debug("thread_key_info:\n" + raw_body)
+                       for item in raw_body.split("&"):
+                               ind = item.find("=")
+                               if ind == -1:
+                                       key[urllib.parse.unquote_plus(item)] = True
+                               else:
+                                       key[urllib.parse.unquote_plus(item[:ind])] = urllib.parse.unquote_plus(item[ind+1:])
+               else:
+                       conn.close()
+                       raise err.HttpErr(res.status, res.reason)
+
+               conn.close()
+
+               return key
+
        def generate_connection_to_coments(self):
                #get_play_info()などで取得した情報を元に、
                #ニコニコ動画のプレイヤーがサーバーから取得しているものに近い
@@ -375,18 +403,28 @@ class Video:
 
                threads = ""
 
-               #通常のコメント取得分
-               #threads += '<thread thread="' + self.play_thread_id + '" version="20061206" res_from="' + comment_from + '" scores="1"/>'
-               threads += '<thread thread="' + self.info["play_thread_id"] + '" version="20090904" res_from="' + comment_from + '" scores="1"/>'
-               #時間帯ごとのコメント追加分(暫定処理,多分要修正)
-               #要解析:このスレッドについてはリクエストの詳細がわかりません。
-               #lvnは↑で取得した個数(これに含まれないものが取得できる)
-               #minsは動画の長さ(分)を小数点以下切り捨てしたものですが、
-               #これが正しい指定方法かは不明です。
-               #レスポンスから推測すると、何かしらの間違いがあると思われます。
+               #1分ごとの追加リクエストのための事前計算
                lvn = "{}".format(-int(comment_from))
                mins = "{}".format(int(self.info["length"] / 60))
-               threads += '<thread_leaves thread="' + self.info["play_thread_id"] + '" scores="1">0-' + mins + ':100,' + lvn + '</thread_leaves>'
+
+               #謎スレッド。コメントではなく動画再生数とかが取得できる?
+               #公式配信とかにあるみたい。
+               if "play_optional_thread_id" in self.info:
+                       threads += '<thread thread="' + self.info["play_optional_thread_id"] + '" version="20090904" scores="1"/>'
+                       threads += '<thread_leaves thread="' + self.info["play_optional_thread_id"] + '" scores="1">0-' + mins + ':100,' + lvn + '</thread_leaves>'
+
+               #通常のコメント取得分
+               if "play_needs_key" in self.info and int(self.info["play_needs_key"]):
+                       thread_key = self.get_thread_key(self.info["play_thread_id"])
+                       thread_ops = ""
+                       for kky in thread_key.keys():
+                               thread_ops += kky + "=\""
+                               thread_ops += thread_key[kky] + "\" "
+                       threads += '<thread thread="' + self.info["play_thread_id"] + '" version="20090904" ' + thread_ops + 'scores="1"/>'
+                       threads += '<thread_leaves thread="' + self.info["play_thread_id"] + '" ' + thread_ops + 'scores="1">0-' + mins + ':100,' + lvn + '</thread_leaves>'
+               else:
+                       threads += '<thread thread="' + self.info["play_thread_id"] + '" version="20090904" res_from="' + comment_from + '" scores="1"/>'
+                       threads += '<thread_leaves thread="' + self.info["play_thread_id"] + '" scores="1">0-' + mins + ':100,' + lvn + '</thread_leaves>'
 
                #ニコスクリプトによって投稿されたコメント?
                #詳細不明。