From 96dee267246dcd1db0749bfa7601bc8823ca1ba0 Mon Sep 17 00:00:00 2001 From: miteruzo Date: Mon, 16 Sep 2024 07:11:11 +0900 Subject: [PATCH] =?UTF-8?q?=20=E6=9C=AC=E6=97=A5=E4=BD=9C=E6=A5=AD?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- update_db.py | 153 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 update_db.py diff --git a/update_db.py b/update_db.py new file mode 100644 index 0000000..ec1e717 --- /dev/null +++ b/update_db.py @@ -0,0 +1,153 @@ +import json +import os +import random +import string +import time +from dataclasses import dataclass +from datetime import datetime + +import mysql.connector +import requests + + +def main ( +) -> None: + conn = mysql.connector.connect (host = os.environ['MYSQL_HOST'], + user = os.environ['MYSQL_USER'], + password = os.environ['MYSQL_PASS']) + + +def fetch_comments ( + video_id: str, +) -> list: + headers = { 'X-Frontend-Id': '6', + 'X-Frontend-Version': '0' } + + action_track_id = ( + ''.join (random.choice (string.ascii_letters + string.digits) + for _ in range (10)) + + '_' + + str (random.randrange (10 ** 12, 10 ** 13))) + + url = (f"https://www.nicovideo.jp/api/watch/v3_guest/{ video_id }" + + f"?actionTrackId={ action_track_id }") + + res = requests.post (url, headers = headers, timeout = 60).json () + + try: + nv_comment = res['data']['comment']['nvComment'] + except (NameError, AttributeError): + return [] + if nv_comment is None: + return [] + + headers = { 'X-Frontend-Id': '6', + 'X-Frontend-Version': '0', + 'Content-Type': 'application/json' } + + params = { 'params': nv_comment['params'], + 'additionals': { }, + 'threadKey': nv_comment['threadKey'] } + + url = nv_comment['server'] + '/v1/threads' + + res = (requests.post (url, json.dumps (params), + headers = headers, + timeout = 60) + .json ()) + + try: + return res['data']['threads'][1]['comments'] + except (NameError, AttributeError): + return [] + + +def search_nico_by_tag ( + tag: str, +) -> list[dict]: + return search_nico_by_tags ([tag]) + + +def search_nico_by_tags ( + tags: list[str], +) -> list[dict]: + url = ('https://snapshot.search.nicovideo.jp' + + '/api/v2/snapshot/video/contents/search') + + query_filter = json.dumps ({ 'type': 'or', + 'filters': [ + { 'type': 'range', + 'field': 'startTime', + 'from': f"{year}-{start}T00:00:00+09:00", + 'to': f"{year}-{end}T23:59:59+09:00", + 'include_lower': True }] }) + + params: dict[str, int | str] + params = { 'q': ' OR '.join (tags), + 'targets': 'tagsExact', + '_sort': '-viewCounter', + 'fields': 'contentId,title,tags,viewCounter,startTime', + '_limit': 100, + 'jsonFilter': query_filter } + + res = requests.get (url, params = params, timeout = 60).json () + + return res['data'] + + +class VideoDao: + def __init__ ( + self, + conn + ): + self.conn = conn + + def fetch_all ( + with_relation_tables: bool = True, + ) -> list[VideoDto]: + with self.conn.cursor () as c: + c.execute (""" + SELECT + id, + code, + title, + description, + uploaded_at, + deleted_at + FROM + videos""") + for video in c.fetchall (): + if with_relation_tables: + video_tags = VideoTagDao (conn).fetch_all (False) + comments = CommentDao (conn).fetch_all (False) + video_histories = VideoHistoryDao (conn).fetch_all (False) + else: + video_tags = None + comments = None + video_histories = None + return VideoDto (id_ = video['id'], + code = video['code'], + title = video['title'], + description = video['description'], + uploaded_at = video['uploaded_at'], + deleted_at = video['deleted_at'], + video_tags = video_tags, + comments = comments, + video_histories = video_histories) + + +@dataclass (slots = True) +class VideoDto: + id_: int + code: str + title: str + description: str + uploaded_at: datetime + deleted_at: datetime | None + video_tags: VideoTagDto | None + comments: CommentDto | None + video_histories: VideoHistoryDto | None + + +if __name__ == '__main__': + main ()