| 
																	
																	
																		
																	
																	
																 | 
																@@ -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]] = [] | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    latest_fetched_at = cast (date, (VideoHistory | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                                     .where ('fetched_at', '<=', base_date) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																                                     .max ('fetched_at'))) | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    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 | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    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) | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    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) | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																
  | 
																 | 
																 | 
																
  | 
															
														
														
													
														
															
																 | 
																 | 
																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 () | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    if video is None: | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																        return [] | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																    return video.comments | 
																 | 
																 | 
																 | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																    result = subprocess.run ( | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																            ['python3', 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') | 
															
														
														
													
														
															
																 | 
																 | 
																 | 
																 | 
																 | 
																        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))) | 
															
														
														
													
												
													
														
															
																| 
																	
																		
																	
																	
																	
																 | 
																
  |