ぼちぼち
このコミットが含まれているのは:
@@ -1,9 +1,6 @@
|
|||||||
[submodule "nizika_ai"]
|
[submodule "nizika_ai"]
|
||||||
path = nizika_ai
|
path = nizika_ai
|
||||||
url = https://git.miteruzo.com/miteruzo/nizika_ai
|
url = https://git.miteruzo.com/miteruzo/nizika_ai
|
||||||
[submodule "nizika_nico"]
|
|
||||||
path = nizika_nico
|
|
||||||
url = https://git.miteruzo.com/miteruzo/nizika_nico.git
|
|
||||||
[submodule "nicolib"]
|
[submodule "nicolib"]
|
||||||
path = nicolib
|
path = nicolib
|
||||||
url = https://git.miteruzo.com/miteruzo/nicolib.git
|
url = https://git.miteruzo.com/miteruzo/nicolib.git
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
import os
|
|
||||||
from typing import TypedDict
|
|
||||||
|
|
||||||
from eloquent import DatabaseManager, Model # type: ignore
|
|
||||||
|
|
||||||
CONFIG: DBConfig = { 'default': 'nico', 'connections': {
|
|
||||||
'ai': { 'driver': 'mysql',
|
|
||||||
'host': 'localhost',
|
|
||||||
'database': 'nizika_ai',
|
|
||||||
'user': os.environ['MYSQL_USER'],
|
|
||||||
'password': os.environ['MYSQL_PASS'],
|
|
||||||
'prefix': '' },
|
|
||||||
|
|
||||||
'nico': { 'driver': 'mysql',
|
|
||||||
'host': 'localhost',
|
|
||||||
'database': 'nizika_nico',
|
|
||||||
'user': os.environ['MYSQL_USER'],
|
|
||||||
'password': os.environ['MYSQL_PASS'],
|
|
||||||
'prefix': '' } } }
|
|
||||||
|
|
||||||
DB = DatabaseManager (CONFIG)
|
|
||||||
Model.set_connection_resolver (DB)
|
|
||||||
|
|
||||||
|
|
||||||
class DBConfig (TypedDict):
|
|
||||||
default: str
|
|
||||||
connections: dict[str, DBConnection]
|
|
||||||
|
|
||||||
|
|
||||||
class DBConnection (TypedDict):
|
|
||||||
driver: str
|
|
||||||
host: str
|
|
||||||
database: str
|
|
||||||
user: str
|
|
||||||
password: str
|
|
||||||
prefix: str
|
|
||||||
@@ -5,25 +5,20 @@ AI ニジカ常時稼動バッチ
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import json
|
||||||
|
import os
|
||||||
import random
|
import random
|
||||||
|
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 cast
|
from typing import Any, cast
|
||||||
|
|
||||||
import nicolib
|
import nicolib
|
||||||
import queries_to_answers as q2a
|
import queries_to_answers as q2a
|
||||||
from config import DB
|
|
||||||
from db.models import Comment, Video, VideoHistory
|
|
||||||
from nicolib import VideoInfo
|
from nicolib import VideoInfo
|
||||||
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
|
||||||
|
|
||||||
# DB 設定
|
|
||||||
DB
|
|
||||||
for m in (Comment, Video, VideoHistory):
|
|
||||||
m.__connection__ = 'nico'
|
|
||||||
Query.__connection__ = 'ai'
|
|
||||||
|
|
||||||
KIRIBAN_VIEWS_COUNTS: list[int] = sorted ({ *range (1_000, 10_000, 1_000),
|
KIRIBAN_VIEWS_COUNTS: list[int] = sorted ({ *range (1_000, 10_000, 1_000),
|
||||||
*range (10_000, 1_000_001, 10_000),
|
*range (10_000, 1_000_001, 10_000),
|
||||||
114_514, 1_940, 2_450, 5_100,
|
114_514, 1_940, 2_450, 5_100,
|
||||||
@@ -84,10 +79,10 @@ async def report_kiriban (
|
|||||||
video_code = video_info['contentId']
|
video_code = video_info['contentId']
|
||||||
comments = fetch_comments (video_code)
|
comments = fetch_comments (video_code)
|
||||||
popular_comments = sorted (comments,
|
popular_comments = sorted (comments,
|
||||||
key = lambda c: c.nico_count,
|
key = lambda c: c['nico_count'],
|
||||||
reverse = True)[:10]
|
reverse = True)[:10]
|
||||||
latest_comments = sorted (comments,
|
latest_comments = sorted (comments,
|
||||||
key = lambda c: c.posted_at,
|
key = lambda c: c['posted_at'],
|
||||||
reverse = True)[:10]
|
reverse = True)[:10]
|
||||||
prompt = (f"{ _format_elapsed (uploaded_at) }前にニコニコに投稿された"
|
prompt = (f"{ _format_elapsed (uploaded_at) }前にニコニコに投稿された"
|
||||||
f"『{ video_info['title'] }』という動画が{ views_count }再生を突破しました。\n"
|
f"『{ video_info['title'] }』という動画が{ views_count }再生を突破しました。\n"
|
||||||
@@ -95,7 +90,7 @@ async def report_kiriban (
|
|||||||
if video_info['tags']:
|
if video_info['tags']:
|
||||||
prompt += f"つけられたタグは「{ '」、「'.join (video_info['tags']) }」です。\n"
|
prompt += f"つけられたタグは「{ '」、「'.join (video_info['tags']) }」です。\n"
|
||||||
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"""
|
||||||
@@ -160,41 +155,22 @@ def fetch_kiriban_list (
|
|||||||
動画リスト(キリ番基準再生数、対象動画情報、投稿日時のタプル)
|
動画リスト(キリ番基準再生数、対象動画情報、投稿日時のタプル)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_kiriban_list: list[tuple[int, VideoInfo, datetime]] = []
|
result = subprocess.run (
|
||||||
|
['python3', str (base_date), *map (str, KIRABAN_VIEWS_COUNTS)],
|
||||||
|
cwd = '/root/nizika_nico',
|
||||||
|
env = os.environ,
|
||||||
|
capture_output = True,
|
||||||
|
text = True)
|
||||||
|
kl: list[list[int | str]] = json.loads (result.stdout)
|
||||||
|
|
||||||
latest_fetched_at = cast (date, (VideoHistory
|
return map (lambda k: (cast (int, k[0]),
|
||||||
.where ('fetched_at', '<=', base_date)
|
nicolib.fetch_video_info (cast (str, k[1])),
|
||||||
.max ('fetched_at')))
|
datetime.strptime (cast (str, k[2]), '%Y-%m-%d %H:%M:%S.%f')), kl)
|
||||||
|
|
||||||
for kiriban_views_count in KIRIBAN_VIEWS_COUNTS:
|
|
||||||
targets = { vh.video.code for vh in (VideoHistory
|
|
||||||
.where ('fetched_at', latest_fetched_at)
|
|
||||||
.where ('views_count', '>=', kiriban_views_count)
|
|
||||||
.get ()) }
|
|
||||||
for code in targets:
|
|
||||||
if code in [kiriban[1]['contentId'] for kiriban in _kiriban_list]:
|
|
||||||
continue
|
|
||||||
previous_views_count: int | None = (
|
|
||||||
VideoHistory
|
|
||||||
.where_has ('video', lambda q, code = code: q.where ('code', code))
|
|
||||||
.where ('fetched_at', '<', latest_fetched_at)
|
|
||||||
.max ('views_count'))
|
|
||||||
if previous_views_count is None:
|
|
||||||
previous_views_count = 0
|
|
||||||
if previous_views_count >= kiriban_views_count:
|
|
||||||
continue
|
|
||||||
video_info = nicolib.fetch_video_info (code)
|
|
||||||
if video_info is not None:
|
|
||||||
_kiriban_list.append ((kiriban_views_count, video_info,
|
|
||||||
(cast (Video, Video.where ('code', code).first ())
|
|
||||||
.uploaded_at)))
|
|
||||||
|
|
||||||
return _kiriban_list
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_comments (
|
def fetch_comments (
|
||||||
video_code: str,
|
video_code: str,
|
||||||
) -> list[Comment]:
|
) -> list[CommentDict]:
|
||||||
"""
|
"""
|
||||||
動画のコメント・リストを取得する.
|
動画のコメント・リストを取得する.
|
||||||
|
|
||||||
@@ -205,14 +181,23 @@ def fetch_comments (
|
|||||||
|
|
||||||
Return
|
Return
|
||||||
------
|
------
|
||||||
list[Comment]
|
list[CommentDict]
|
||||||
コメント・リスト
|
コメント・リスト
|
||||||
"""
|
"""
|
||||||
|
|
||||||
video = Video.where ('code', video_code).first ()
|
result = subprocess.run (
|
||||||
if video is None:
|
['python3', video_code],
|
||||||
return []
|
cwd = '/root/nizika_nico',
|
||||||
return video.comments
|
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')
|
||||||
|
comments.append (cast (CommentDict, row))
|
||||||
|
|
||||||
|
return comments
|
||||||
|
|
||||||
|
|
||||||
def fetch_latest_deerjika (
|
def fetch_latest_deerjika (
|
||||||
@@ -339,6 +324,17 @@ def _format_elapsed (
|
|||||||
return f"{ days }日{ hours }時間{ mins }分{ seconds }秒"
|
return f"{ days }日{ hours }時間{ mins }分{ seconds }秒"
|
||||||
|
|
||||||
|
|
||||||
|
class CommentDict (TypedDict):
|
||||||
|
id: int
|
||||||
|
video_id: int
|
||||||
|
comment_no: int
|
||||||
|
user_id: int
|
||||||
|
content: str
|
||||||
|
posted_at: datetime
|
||||||
|
nico_count: int
|
||||||
|
vpos_ms: int
|
||||||
|
|
||||||
|
|
||||||
kiriban_list = (
|
kiriban_list = (
|
||||||
fetch_kiriban_list ((now := datetime.now ()).date ()
|
fetch_kiriban_list ((now := datetime.now ()).date ()
|
||||||
- timedelta (days = 1 if now.hour < 15 else 0)))
|
- timedelta (days = 1 if now.hour < 15 else 0)))
|
||||||
|
|||||||
+1
-1
サブモジュール nicolib が更新されました: 85670982f0...32ecf2d00f
+1
-1
サブモジュール nizika_ai が更新されました: ff695263ec...3be6d9063c
-1
サブモジュール nizika_nico が 463e8bbec7 から削除されました
新しい課題から参照
ユーザをブロックする