diff --git a/assets/tv.png b/assets/tv.png new file mode 100644 index 0000000..5be21d4 Binary files /dev/null and b/assets/tv.png differ diff --git a/main.py b/main.py index 65dc95f..62fb1ac 100644 --- a/main.py +++ b/main.py @@ -1,15 +1,17 @@ from __future__ import annotations +import json import math import os import random +import subprocess import sys import time import wave from datetime import datetime, timedelta from enum import Enum, auto from io import BytesIO -from typing import Callable, TypedDict +from typing import Callable, TypedDict, cast import cv2 import emoji @@ -34,6 +36,8 @@ from nizika_ai.config import DB from nizika_ai.consts import Character, GPTModel, Platform, QueryType from nizika_ai.models import Answer, AnsweredFlag, Query, User +NIZIKA_NICO_DIR = os.environ.get ('NIZIKA_NICO_DIR') or '/root/nizika_nico' + pygame.init () FPS = 30 @@ -42,6 +46,8 @@ SYSTEM_FONT = pygame.font.SysFont ('notosanscjkjp', 11, bold = True) USER_FONT = pygame.font.SysFont ('notosanscjkjp', 15, italic = True) DEERJIKA_FONT = pygame.font.SysFont ('07nikumarufont', 23) +WATCHING_MSG = 'それじゃあ、さっそく見てみるぬ゛ん゛!' + def main ( ) -> None: @@ -61,7 +67,7 @@ def main ( except KeyError: broadcast = None - waiting_balloon = (False, '', '') + waiting_balloon: tuple[bool, str | None, str] = (False, '', '') last_flags_poll: float = 0 traced_af_ids: list[int] = [] @@ -76,7 +82,10 @@ def main ( if (not balloon.enabled) and (not snack_time.enabled): if waiting_balloon[0]: deerjika.talk (waiting_balloon[1], waiting_balloon[2]) - waiting_balloon = (False, '', '') + if waiting_balloon[2] == WATCHING_MSG: + ... + else: + waiting_balloon = (False, '', '') if now_m - last_flags_poll >= 1: last_flags_poll = now_m @@ -104,6 +113,12 @@ def main ( waiting_balloon = (True, query.content, answer.content) answer_flag.answered = True answer_flag.save () + case QueryType.KIRIBAN: + query = Query.find (answer.query_id) + deerjika.talk (None, answer.content) + waiting_balloon = (True, None, WATCHING_MSG) + answer_flag.answered = True + answer_flag.save () case _: traced_af_ids.append (answer_flag.id) DB.commit () @@ -490,7 +505,7 @@ class Deerjika (Creature): def talk ( self, - query: str, + query: str | None, answer: str, ) -> None: self.bell () @@ -560,7 +575,7 @@ class Balloon (GameObject): answer (str): 回答テキスト image_url (str, None): 画像 URL length (int): 表示する時間 (frame) - query (str): 質問テキスト + query (str, None): 質問テキスト surface (Surface): 吹出し Surface x_flip (bool): 左右反転フラグ y_flip (bool): 上下反転フラグ @@ -569,7 +584,7 @@ class Balloon (GameObject): answer: str = '' image_url: str | None = None length: int = 300 - query: str = '' + query: str | None = None surface: Surface x_flip: bool = False y_flip: bool = False @@ -595,8 +610,10 @@ class Balloon (GameObject): self.game.last_answered_at = self.game.now return query = self.query - if CommonModule.len_by_full (query) > 21: + if query and CommonModule.len_by_full (query) > 21: query = CommonModule.mid_by_full (query, 0, 19.5) + '...' + if query is not None: + query = '>' + query answer = Surface ( (375, int (((CommonModule.len_by_full (self.answer) - 1) // 16 + 1) * 23.4375)), pygame.SRCALPHA) @@ -605,7 +622,7 @@ class Balloon (GameObject): CommonModule.mid_by_full (self.answer, 16 * i, 16), True, (192, 0, 0)), (0, 23.4375 * i)) surface = self.surface.copy () - surface.blit (USER_FONT.render ('>' + query, True, (0, 0, 0)), (56.25, 32.8125)) + surface.blit (USER_FONT.render (query, True, (0, 0, 0)), (56.25, 32.8125)) y: float if self.frame < 30: y = 0 @@ -619,7 +636,7 @@ class Balloon (GameObject): def talk ( self, - query: str, + query: str | None, answer: str, image_url: str | None = None, length: int = 300, @@ -815,7 +832,7 @@ class Broadcast: def __init__ ( self, - broadcast_code, + broadcast_code: str, ): self.code = broadcast_code self.chat = pytchat.create (self.code) @@ -955,7 +972,13 @@ class Video (GameObject): class NicoVideo (Video): - ... + def __init__ ( + self, + game: Game, + video_code: str, + ): + comments = fetch_comments (video_code) + #super ().__init__ (game, ) class SnackTime (Video): @@ -977,6 +1000,17 @@ def fetch_bytes_from_url ( return res.content +def fetch_comments ( + video_code: str, +) -> list[CommentDict]: + result = subprocess.run ( + ['python3', 'get_kiriban_list.py', video_code], + cwd = NIZIKA_NICO_DIR, + env = os.environ, + capture_output = True, + text = True) + return cast(list[CommentDict], json.loads (result.stdout)) + def add_query ( broadcast: Broadcast, ) -> None: @@ -1007,6 +1041,11 @@ def add_query ( DB.commit () +class CommentDict (TypedDict): + content: str + vpos_ms: int + + def log ( msg: str, ) -> None: