このコミットが含まれているのは:
バイナリ
バイナリファイルは表示されません.
|
変更後 幅: | 高さ: | サイズ: 463 KiB |
@@ -1,15 +1,17 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
import math
|
import math
|
||||||
import os
|
import os
|
||||||
import random
|
import random
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import wave
|
import wave
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from enum import Enum, auto
|
from enum import Enum, auto
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from typing import Callable, TypedDict
|
from typing import Callable, TypedDict, cast
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
import emoji
|
import emoji
|
||||||
@@ -34,6 +36,8 @@ from nizika_ai.config import DB
|
|||||||
from nizika_ai.consts import Character, GPTModel, Platform, QueryType
|
from nizika_ai.consts import Character, GPTModel, Platform, QueryType
|
||||||
from nizika_ai.models import Answer, AnsweredFlag, Query, User
|
from nizika_ai.models import Answer, AnsweredFlag, Query, User
|
||||||
|
|
||||||
|
NIZIKA_NICO_DIR = os.environ.get ('NIZIKA_NICO_DIR') or '/root/nizika_nico'
|
||||||
|
|
||||||
pygame.init ()
|
pygame.init ()
|
||||||
|
|
||||||
FPS = 30
|
FPS = 30
|
||||||
@@ -42,6 +46,8 @@ SYSTEM_FONT = pygame.font.SysFont ('notosanscjkjp', 11, bold = True)
|
|||||||
USER_FONT = pygame.font.SysFont ('notosanscjkjp', 15, italic = True)
|
USER_FONT = pygame.font.SysFont ('notosanscjkjp', 15, italic = True)
|
||||||
DEERJIKA_FONT = pygame.font.SysFont ('07nikumarufont', 23)
|
DEERJIKA_FONT = pygame.font.SysFont ('07nikumarufont', 23)
|
||||||
|
|
||||||
|
WATCHING_MSG = 'それじゃあ、さっそく見てみるぬ゛ん゛!'
|
||||||
|
|
||||||
|
|
||||||
def main (
|
def main (
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -61,7 +67,7 @@ def main (
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
broadcast = None
|
broadcast = None
|
||||||
|
|
||||||
waiting_balloon = (False, '', '')
|
waiting_balloon: tuple[bool, str | None, str] = (False, '', '')
|
||||||
last_flags_poll: float = 0
|
last_flags_poll: float = 0
|
||||||
traced_af_ids: list[int] = []
|
traced_af_ids: list[int] = []
|
||||||
|
|
||||||
@@ -76,6 +82,9 @@ def main (
|
|||||||
if (not balloon.enabled) and (not snack_time.enabled):
|
if (not balloon.enabled) and (not snack_time.enabled):
|
||||||
if waiting_balloon[0]:
|
if waiting_balloon[0]:
|
||||||
deerjika.talk (waiting_balloon[1], waiting_balloon[2])
|
deerjika.talk (waiting_balloon[1], waiting_balloon[2])
|
||||||
|
if waiting_balloon[2] == WATCHING_MSG:
|
||||||
|
...
|
||||||
|
else:
|
||||||
waiting_balloon = (False, '', '')
|
waiting_balloon = (False, '', '')
|
||||||
|
|
||||||
if now_m - last_flags_poll >= 1:
|
if now_m - last_flags_poll >= 1:
|
||||||
@@ -104,6 +113,12 @@ def main (
|
|||||||
waiting_balloon = (True, query.content, answer.content)
|
waiting_balloon = (True, query.content, answer.content)
|
||||||
answer_flag.answered = True
|
answer_flag.answered = True
|
||||||
answer_flag.save ()
|
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 _:
|
case _:
|
||||||
traced_af_ids.append (answer_flag.id)
|
traced_af_ids.append (answer_flag.id)
|
||||||
DB.commit ()
|
DB.commit ()
|
||||||
@@ -490,7 +505,7 @@ class Deerjika (Creature):
|
|||||||
|
|
||||||
def talk (
|
def talk (
|
||||||
self,
|
self,
|
||||||
query: str,
|
query: str | None,
|
||||||
answer: str,
|
answer: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.bell ()
|
self.bell ()
|
||||||
@@ -560,7 +575,7 @@ class Balloon (GameObject):
|
|||||||
answer (str): 回答テキスト
|
answer (str): 回答テキスト
|
||||||
image_url (str, None): 画像 URL
|
image_url (str, None): 画像 URL
|
||||||
length (int): 表示する時間 (frame)
|
length (int): 表示する時間 (frame)
|
||||||
query (str): 質問テキスト
|
query (str, None): 質問テキスト
|
||||||
surface (Surface): 吹出し Surface
|
surface (Surface): 吹出し Surface
|
||||||
x_flip (bool): 左右反転フラグ
|
x_flip (bool): 左右反転フラグ
|
||||||
y_flip (bool): 上下反転フラグ
|
y_flip (bool): 上下反転フラグ
|
||||||
@@ -569,7 +584,7 @@ class Balloon (GameObject):
|
|||||||
answer: str = ''
|
answer: str = ''
|
||||||
image_url: str | None = None
|
image_url: str | None = None
|
||||||
length: int = 300
|
length: int = 300
|
||||||
query: str = ''
|
query: str | None = None
|
||||||
surface: Surface
|
surface: Surface
|
||||||
x_flip: bool = False
|
x_flip: bool = False
|
||||||
y_flip: bool = False
|
y_flip: bool = False
|
||||||
@@ -595,8 +610,10 @@ class Balloon (GameObject):
|
|||||||
self.game.last_answered_at = self.game.now
|
self.game.last_answered_at = self.game.now
|
||||||
return
|
return
|
||||||
query = self.query
|
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) + '...'
|
query = CommonModule.mid_by_full (query, 0, 19.5) + '...'
|
||||||
|
if query is not None:
|
||||||
|
query = '>' + query
|
||||||
answer = Surface (
|
answer = Surface (
|
||||||
(375, int (((CommonModule.len_by_full (self.answer) - 1) // 16 + 1) * 23.4375)),
|
(375, int (((CommonModule.len_by_full (self.answer) - 1) // 16 + 1) * 23.4375)),
|
||||||
pygame.SRCALPHA)
|
pygame.SRCALPHA)
|
||||||
@@ -605,7 +622,7 @@ class Balloon (GameObject):
|
|||||||
CommonModule.mid_by_full (self.answer, 16 * i, 16), True, (192, 0, 0)),
|
CommonModule.mid_by_full (self.answer, 16 * i, 16), True, (192, 0, 0)),
|
||||||
(0, 23.4375 * i))
|
(0, 23.4375 * i))
|
||||||
surface = self.surface.copy ()
|
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
|
y: float
|
||||||
if self.frame < 30:
|
if self.frame < 30:
|
||||||
y = 0
|
y = 0
|
||||||
@@ -619,7 +636,7 @@ class Balloon (GameObject):
|
|||||||
|
|
||||||
def talk (
|
def talk (
|
||||||
self,
|
self,
|
||||||
query: str,
|
query: str | None,
|
||||||
answer: str,
|
answer: str,
|
||||||
image_url: str | None = None,
|
image_url: str | None = None,
|
||||||
length: int = 300,
|
length: int = 300,
|
||||||
@@ -815,7 +832,7 @@ class Broadcast:
|
|||||||
|
|
||||||
def __init__ (
|
def __init__ (
|
||||||
self,
|
self,
|
||||||
broadcast_code,
|
broadcast_code: str,
|
||||||
):
|
):
|
||||||
self.code = broadcast_code
|
self.code = broadcast_code
|
||||||
self.chat = pytchat.create (self.code)
|
self.chat = pytchat.create (self.code)
|
||||||
@@ -955,7 +972,13 @@ class Video (GameObject):
|
|||||||
|
|
||||||
|
|
||||||
class NicoVideo (Video):
|
class NicoVideo (Video):
|
||||||
...
|
def __init__ (
|
||||||
|
self,
|
||||||
|
game: Game,
|
||||||
|
video_code: str,
|
||||||
|
):
|
||||||
|
comments = fetch_comments (video_code)
|
||||||
|
#super ().__init__ (game, )
|
||||||
|
|
||||||
|
|
||||||
class SnackTime (Video):
|
class SnackTime (Video):
|
||||||
@@ -977,6 +1000,17 @@ def fetch_bytes_from_url (
|
|||||||
return res.content
|
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 (
|
def add_query (
|
||||||
broadcast: Broadcast,
|
broadcast: Broadcast,
|
||||||
) -> None:
|
) -> None:
|
||||||
@@ -1007,6 +1041,11 @@ def add_query (
|
|||||||
DB.commit ()
|
DB.commit ()
|
||||||
|
|
||||||
|
|
||||||
|
class CommentDict (TypedDict):
|
||||||
|
content: str
|
||||||
|
vpos_ms: int
|
||||||
|
|
||||||
|
|
||||||
def log (
|
def log (
|
||||||
msg: str,
|
msg: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|||||||
新しい課題から参照
ユーザをブロックする