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