ぼざろクリーチャーシリーズ DB 兼 API(自分用)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

154 lines
4.7 KiB

  1. import json
  2. import os
  3. import random
  4. import string
  5. import time
  6. from dataclasses import dataclass
  7. from datetime import datetime
  8. import mysql.connector
  9. import requests
  10. def main (
  11. ) -> None:
  12. conn = mysql.connector.connect (host = os.environ['MYSQL_HOST'],
  13. user = os.environ['MYSQL_USER'],
  14. password = os.environ['MYSQL_PASS'])
  15. def fetch_comments (
  16. video_id: str,
  17. ) -> list:
  18. headers = { 'X-Frontend-Id': '6',
  19. 'X-Frontend-Version': '0' }
  20. action_track_id = (
  21. ''.join (random.choice (string.ascii_letters + string.digits)
  22. for _ in range (10))
  23. + '_'
  24. + str (random.randrange (10 ** 12, 10 ** 13)))
  25. url = (f"https://www.nicovideo.jp/api/watch/v3_guest/{ video_id }"
  26. + f"?actionTrackId={ action_track_id }")
  27. res = requests.post (url, headers = headers, timeout = 60).json ()
  28. try:
  29. nv_comment = res['data']['comment']['nvComment']
  30. except (NameError, AttributeError):
  31. return []
  32. if nv_comment is None:
  33. return []
  34. headers = { 'X-Frontend-Id': '6',
  35. 'X-Frontend-Version': '0',
  36. 'Content-Type': 'application/json' }
  37. params = { 'params': nv_comment['params'],
  38. 'additionals': { },
  39. 'threadKey': nv_comment['threadKey'] }
  40. url = nv_comment['server'] + '/v1/threads'
  41. res = (requests.post (url, json.dumps (params),
  42. headers = headers,
  43. timeout = 60)
  44. .json ())
  45. try:
  46. return res['data']['threads'][1]['comments']
  47. except (NameError, AttributeError):
  48. return []
  49. def search_nico_by_tag (
  50. tag: str,
  51. ) -> list[dict]:
  52. return search_nico_by_tags ([tag])
  53. def search_nico_by_tags (
  54. tags: list[str],
  55. ) -> list[dict]:
  56. url = ('https://snapshot.search.nicovideo.jp'
  57. + '/api/v2/snapshot/video/contents/search')
  58. query_filter = json.dumps ({ 'type': 'or',
  59. 'filters': [
  60. { 'type': 'range',
  61. 'field': 'startTime',
  62. 'from': f"{year}-{start}T00:00:00+09:00",
  63. 'to': f"{year}-{end}T23:59:59+09:00",
  64. 'include_lower': True }] })
  65. params: dict[str, int | str]
  66. params = { 'q': ' OR '.join (tags),
  67. 'targets': 'tagsExact',
  68. '_sort': '-viewCounter',
  69. 'fields': 'contentId,title,tags,viewCounter,startTime',
  70. '_limit': 100,
  71. 'jsonFilter': query_filter }
  72. res = requests.get (url, params = params, timeout = 60).json ()
  73. return res['data']
  74. class VideoDao:
  75. def __init__ (
  76. self,
  77. conn
  78. ):
  79. self.conn = conn
  80. def fetch_all (
  81. with_relation_tables: bool = True,
  82. ) -> list[VideoDto]:
  83. with self.conn.cursor () as c:
  84. c.execute ("""
  85. SELECT
  86. id,
  87. code,
  88. title,
  89. description,
  90. uploaded_at,
  91. deleted_at
  92. FROM
  93. videos""")
  94. for video in c.fetchall ():
  95. if with_relation_tables:
  96. video_tags = VideoTagDao (conn).fetch_all (False)
  97. comments = CommentDao (conn).fetch_all (False)
  98. video_histories = VideoHistoryDao (conn).fetch_all (False)
  99. else:
  100. video_tags = None
  101. comments = None
  102. video_histories = None
  103. return VideoDto (id_ = video['id'],
  104. code = video['code'],
  105. title = video['title'],
  106. description = video['description'],
  107. uploaded_at = video['uploaded_at'],
  108. deleted_at = video['deleted_at'],
  109. video_tags = video_tags,
  110. comments = comments,
  111. video_histories = video_histories)
  112. @dataclass (slots = True)
  113. class VideoDto:
  114. id_: int
  115. code: str
  116. title: str
  117. description: str
  118. uploaded_at: datetime
  119. deleted_at: datetime | None
  120. video_tags: VideoTagDto | None
  121. comments: CommentDto | None
  122. video_histories: VideoHistoryDto | None
  123. if __name__ == '__main__':
  124. main ()