コミットを比較
9 コミット
| 作成者 | SHA1 | 日付 | |
|---|---|---|---|
| ceebaace4d | |||
| d4faff4759 | |||
| ca250d507d | |||
| 11551b8abc | |||
| f56a278cf7 | |||
| 31ab0e93d0 | |||
| a73b07068f | |||
| 35f61f7286 | |||
| 0ed28387a5 |
バイナリファイルは表示されません.
@@ -11,11 +11,12 @@ import random
|
||||
import subprocess
|
||||
from asyncio import Lock
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from typing import Any, cast
|
||||
from typing import Any, Callable, TypedDict, cast
|
||||
|
||||
import nicolib
|
||||
import queries_to_answers as q2a
|
||||
from nicolib import VideoInfo
|
||||
from nizika_ai.config import DB
|
||||
from nizika_ai.consts import Character, GPTModel, QueryType
|
||||
from nizika_ai.models import Query
|
||||
|
||||
@@ -45,7 +46,8 @@ async def main (
|
||||
report_nico (),
|
||||
update_kiriban_list (),
|
||||
report_snack_time (),
|
||||
report_hot_spring_time ())
|
||||
report_hot_spring_time (),
|
||||
reconnect_db ())
|
||||
|
||||
|
||||
async def queries_to_answers (
|
||||
@@ -92,7 +94,7 @@ async def report_kiriban (
|
||||
if comments:
|
||||
prompt += f"人気のコメントは次の通りです:「{ '」、「'.join (c['content'] for c in popular_comments) }」\n"
|
||||
if latest_comments != popular_comments:
|
||||
prompt += f"最新のコメントは次の通りです:「{ '」、「'.join (c.content for c in latest_comments) }」\n"
|
||||
prompt += f"最新のコメントは次の通りです:「{ '」、「'.join (c['content'] for c in latest_comments) }」\n"
|
||||
prompt += f"""
|
||||
概要には次のように書かれています:
|
||||
```html
|
||||
@@ -156,16 +158,21 @@ def fetch_kiriban_list (
|
||||
"""
|
||||
|
||||
result = subprocess.run (
|
||||
['python3', str (base_date), *map (str, KIRABAN_VIEWS_COUNTS)],
|
||||
['python3', '/root/nizika_nico/get_kiriban_list.py',
|
||||
str (base_date), *map (str, KIRIBAN_VIEWS_COUNTS)],
|
||||
cwd = '/root/nizika_nico',
|
||||
env = os.environ,
|
||||
capture_output = True,
|
||||
text = True)
|
||||
kl: list[list[int | str]] = json.loads (result.stdout)
|
||||
kl: list[list[int | str]]
|
||||
try:
|
||||
kl = json.loads (result.stdout)
|
||||
except Exception:
|
||||
kl = []
|
||||
|
||||
return map (lambda k: (cast (int, k[0]),
|
||||
nicolib.fetch_video_info (cast (str, k[1])),
|
||||
datetime.strptime (cast (str, k[2]), '%Y-%m-%d %H:%M:%S.%f')), kl)
|
||||
return [(cast (int, k[0]), video_info, str_to_datetime (cast (str, k[2])))
|
||||
for k in kl
|
||||
if (video_info := nicolib.fetch_video_info (cast (str, k[1]))) is not None]
|
||||
|
||||
|
||||
def fetch_comments (
|
||||
@@ -186,15 +193,15 @@ def fetch_comments (
|
||||
"""
|
||||
|
||||
result = subprocess.run (
|
||||
['python3', video_code],
|
||||
['python3', 'get_comments_by_video_code.py', video_code],
|
||||
cwd = '/root/nizika_nico',
|
||||
env = os.environ,
|
||||
capture_output = True,
|
||||
text = True)
|
||||
rows: list[dict[str, Any]] = json.loads (result.stdout)
|
||||
comments: list[CommentDict] = []
|
||||
for row in comments:
|
||||
row['posted_at'] = datetime.strptime (row['posted_at'], '%Y-%m-%d %H:%M:%S.%f')
|
||||
for row in rows:
|
||||
row['posted_at'] = str_to_datetime (row['posted_at'])
|
||||
comments.append (cast (CommentDict, row))
|
||||
|
||||
return comments
|
||||
@@ -281,6 +288,55 @@ async def report_hot_spring_time (
|
||||
_add_query ('温泉に入ろう!!!', QueryType.HOT_SPRING)
|
||||
|
||||
|
||||
async def reconnect_db (
|
||||
) -> None:
|
||||
while True:
|
||||
await asyncio.sleep (600)
|
||||
try:
|
||||
ensure_mysql_alive ()
|
||||
except Exception as ex:
|
||||
if getattr (ex, 'args', [None])[0] not in (2006, 2013):
|
||||
raise
|
||||
print (f"[reconnect_db] { type (ex).__name__ }: { ex }")
|
||||
safe_reconnect ()
|
||||
|
||||
|
||||
def ensure_mysql_alive (
|
||||
) -> None:
|
||||
conn = DB.connection ('mysql').get_connection ()
|
||||
conn.ping ()
|
||||
|
||||
|
||||
def safe_reconnect (
|
||||
) -> None:
|
||||
try:
|
||||
DB.reconnect ('mysql')
|
||||
except Exception as ex:
|
||||
if getattr (ex, 'args', [None])[0] not in (2006, 2013):
|
||||
raise
|
||||
print (f"[safe_reconnect] { type (ex).__name__ }: { ex }")
|
||||
|
||||
|
||||
def run_with_mysql_retry (
|
||||
fn: Callable[..., Any],
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> Any:
|
||||
last = None
|
||||
for _ in range (2):
|
||||
try:
|
||||
ensure_mysql_alive ()
|
||||
return fn (*args, **kwargs)
|
||||
except Exception as ex:
|
||||
if getattr (ex, 'args', [None])[0] not in (2006, 2013):
|
||||
raise
|
||||
last = ex
|
||||
print (f"[run_with_mysql_retry] { type (ex).__name__ }: { ex }")
|
||||
safe_reconnect ()
|
||||
if last:
|
||||
raise last
|
||||
|
||||
|
||||
def _add_query (
|
||||
content: str,
|
||||
query_type: QueryType,
|
||||
@@ -291,11 +347,12 @@ def _add_query (
|
||||
query.target_character = Character.DEERJIKA.value
|
||||
query.content = content
|
||||
query.query_type = query_type.value
|
||||
query.model = GPTModel.GPT3_TURBO.value
|
||||
query.model = GPTModel.GPT4_O.value
|
||||
query.sent_at = datetime.now ()
|
||||
query.answered = False
|
||||
query.transfer_data = transfer_data
|
||||
query.save ()
|
||||
if transfer_data is not None:
|
||||
query.transfer_data = transfer_data
|
||||
run_with_mysql_retry (query.save)
|
||||
|
||||
|
||||
def _format_elapsed (
|
||||
@@ -324,6 +381,20 @@ def _format_elapsed (
|
||||
return f"{ days }日{ hours }時間{ mins }分{ seconds }秒"
|
||||
|
||||
|
||||
def str_to_datetime (
|
||||
s: str,
|
||||
) -> datetime:
|
||||
formats: list[str] = [
|
||||
'%Y-%m-%d %H:%M:%S.%f',
|
||||
'%Y-%m-%d %H:%M:%S']
|
||||
for f in formats:
|
||||
try:
|
||||
return datetime.strptime (s, f)
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError ('うんち!w')
|
||||
|
||||
|
||||
class CommentDict (TypedDict):
|
||||
id: int
|
||||
video_id: int
|
||||
|
||||
+1
-1
サブモジュール nicolib が更新されました: 32ecf2d00f...f290e64a4e
+1
-1
サブモジュール nizika_ai が更新されました: 3be6d9063c...1f75763038
+3
-2
@@ -84,6 +84,7 @@ def add_answer (
|
||||
answer.content = Talk.main (message, user_name, histories,
|
||||
goatoh_mode = character == Character.GOATOH)
|
||||
answer.sent_at = datetime.now ()
|
||||
answer.answer_type = query.query_type
|
||||
answer.save ()
|
||||
add_answered_flags (answer)
|
||||
|
||||
@@ -102,12 +103,12 @@ def add_answered_flags (
|
||||
|
||||
answer_type: QueryType
|
||||
try:
|
||||
answer_type = QueryType (answer.query.query_type)
|
||||
answer_type = QueryType (answer.query_rel.query_type)
|
||||
except (TypeError, ValueError):
|
||||
return
|
||||
|
||||
if answer_type in (QueryType.YOUTUBE_COMMENT,
|
||||
QueryType.YOUTUBE_COMMENT,
|
||||
QueryType.YOUTUBE_SYSTEM,
|
||||
QueryType.KIRIBAN,
|
||||
QueryType.NICO_REPORT,
|
||||
QueryType.SNACK_TIME,
|
||||
|
||||
新しい課題から参照
ユーザをブロックする