Browse Source

#11

ai-migration
みてるぞ 3 weeks ago
parent
commit
47dc881537
4 changed files with 179 additions and 4 deletions
  1. +3
    -3
      .gitmodules
  2. +0
    -1
      ai
  3. +1
    -0
      nizika_ai
  4. +175
    -0
      test.py

+ 3
- 3
.gitmodules View File

@@ -1,6 +1,6 @@
[submodule "nizika_nico"]
path = nizika_nico
url = https://git.miteruzo.com/miteruzo/nizika_nico
[submodule "ai"]
path = ai
url = https://git.miteruzo.com/miteruzo/nizika_broadcast
[submodule "nizika_ai"]
path = nizika_ai
url = https://git.miteruzo.com/miteruzo/nizika_ai.git

+ 0
- 1
ai

@@ -1 +0,0 @@
Subproject commit 299a3acdff6312f4ea7188f3606bf66e751669c1

+ 1
- 0
nizika_ai

@@ -0,0 +1 @@
Subproject commit 4e5bd13ab45ec024bda6746db4959d32fced56da

+ 175
- 0
test.py View File

@@ -0,0 +1,175 @@
from __future__ import annotations

import asyncio
import time
from typing import TypedDict

import atproto
from atproto import Client
from atproto_client.models.app.bsky.feed.get_timeline import Response
from atproto_client.models.com.atproto.repo.strong_ref import Main

import account
from nizika_ai.consts import QueryType
from nizika_ai.models import Answer, AnsweredFlag, Query, User

TARGET_WORDS = ['deerjika', 'ニジカ', 'ぼっち', '虹夏', '郁代', 'バーカ',
'kfif', 'kita-flatten-ikuyo-flatten', 'ラマ田', 'ゴートう',
'ぼざクリ', 'オオミソカ', '伊地知', '喜多ちゃん',
'喜タイ', '洗澡鹿', 'シーザオ', '今日は本当に',
'ダイソーで', '変なチンチン', 'daisoで', 'だね~(笑)',
'おやつタイム', 'わさしが', 'わさび県', 'たぬマ', 'にくまる',
'ルイズマリー', '餅', 'ニジゴ', 'ゴニジ', 'ニジニジ',
'新年だよね', 'うんこじゃん', 'ほくほくのジャガイモ']

time.sleep (60)

client = Client (base_url = 'https://bsky.social')
client.login (account.USER_ID, account.PASSWORD)


async def main (
) -> None:
"""
メーン処理
"""

await asyncio.gather (like_posts (),
reply ())


async def like_posts (
) -> None:
while True:
for post in fetch_target_posts ():
client.like (**post)

await asyncio.sleep (60)


async def check_mentions (
) -> None:
while True:
for uri in check_notifications ():
records = fetch_thread_contents (uri, 20)
if records:
record = records[0]
content = record['text']
image_url: str | None = None
if record['embed'] and hasattr (record['embed'], 'images'):
image_url = ('https://cdn.bsky.app/img/feed_fullsize/plain'
f"/{ record['did'] }"
f"/{ record['embed'].images[0].image.ref.link }")
user = _fetch_user (record['did'], record['name'])
_add_query (user, record['text'], image_url)

await asyncio.sleep (60)


def check_notifications (
) -> list[str]:
uris: list[str] = []
last_seen_at = client.get_current_time_iso ()

notifications = client.app.bsky.notification.list_notifications()
for notification in notifications.notifications:
if not notification.is_read:
match notification.reason:
case 'mention' | 'reply' | 'quote':
uris.append (notification.uri)
case 'follow':
client.follow (notification.author.did)

client.app.bsky.notification.update_seen ({ 'seen_at': last_seen_at })

return uris


def fetch_thread_contents (
uri: str,
parent_height: int,
) -> list[Record]:
post_thread = client.get_post_thread (uri = uri, parent_height = parent_height)
if not post_thread:
return []

res = post_thread.thread

records: list[Record] = []
while res:
records.append ({ 'strong_ref': atproto.models.create_strong_ref (res.post),
'did': res.post.author.did,
'handle': response.post.author.handle,
'name': response.post.author.display_name,
'datetime': response.post.record.created_at,
'text': response.post.record.text,
'embed': response.post.record.embed })
res = res.parent

return records


def fetch_target_posts (
) -> list[LikeParams]:
posts: list[LikeParams] = []

timeline: Response = client.get_timeline ()
for feed in timeline.feed:
if (feed.post.author.did != client.me.did
and (feed.post.viewer.like is None)
and any (target_word in feed.post.record.text.lower ()
for target_word in TARGET_WORDS)):
posts.append (LikeParams ({ 'uri': feed.post.uri, 'cid': feed.post.cid }))

return posts


def _add_query (
user: User,
content: str,
image_url: str | None = None,
) -> None:
query = Query ()
query.user_id = user.id
query.target_character = Character.DEERJIKA.value
query.content = content
query.image_url = image_url or None
query.query_type = QueryType.BLUESKY_COMMENT.value
query.model = GPTModel.GPT3_TURBO.value
query.sent_at = datetime.now ()
query.answered = False
query.save ()
# TODO: 履歴情報の追加


def _fetch_user (
did: str,
name: str,
) -> User:
user = User.where ('platform', Platform.BLUESKY).where ('code', did).first ()
if user is None:
user = User ()
user.platform = Platfrom.BLUESKY
user.code = did
user.name = name
user.save ()
return user


class LikeParams (TypedDict):
uri: str
cid: str


class Record (TypedDict):
strong_ref: Main
did: str
handle: str
name: str
datetime: str
text: str
embed: object


if __name__ == '__main__':
asyncio.run (main ())

Loading…
Cancel
Save