このコミットが含まれているのは:
バイナリ
バイナリファイルは表示されません.
|
変更後 幅: | 高さ: | サイズ: 463 KiB |
@@ -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,6 +82,9 @@ def main (
|
||||
if (not balloon.enabled) and (not snack_time.enabled):
|
||||
if waiting_balloon[0]:
|
||||
deerjika.talk (waiting_balloon[1], waiting_balloon[2])
|
||||
if waiting_balloon[2] == WATCHING_MSG:
|
||||
...
|
||||
else:
|
||||
waiting_balloon = (False, '', '')
|
||||
|
||||
if now_m - last_flags_poll >= 1:
|
||||
@@ -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:
|
||||
|
||||
新しい課題から参照
ユーザをブロックする