温泉追加とリファクタリング

このコミットが含まれているのは:
2024-10-04 02:58:20 +09:00
コミット 55049cdc2d
3個のファイルの変更48行の追加50行の削除
バイナリ
ファイルの表示
バイナリファイルは表示されません.

変更後

幅:  |  高さ:  |  サイズ: 221 KiB

+47 -10
ファイルの表示
@@ -1,8 +1,13 @@
"""
Bluesky のニジカがいろいろする.
(近々機能ごとにファイル分けて systemd でイベント管理する予定)
"""
import io import io
import json
import time import time
import sys import sys
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import cast
import requests import requests
from atproto import Client, models from atproto import Client, models
@@ -22,7 +27,7 @@ def check_notifications (
for notification in (client.app.bsky.notification.list_notifications () for notification in (client.app.bsky.notification.list_notifications ()
.notifications): .notifications):
if not notification.is_read: if not notification.is_read:
if notification.reason in ['mention', 'reply']: if notification.reason in ['mention', 'reply', 'quote']:
uris += [notification.uri] uris += [notification.uri]
elif notification.reason == 'follow': elif notification.reason == 'follow':
client.follow (notification.author.did) client.follow (notification.author.did)
@@ -62,6 +67,7 @@ def main (
last_posted_at = datetime.now () - timedelta (hours = 6) last_posted_at = datetime.now () - timedelta (hours = 6)
has_got_snack_time = False has_got_snack_time = False
has_taken_hot_spring = False
watched_videos = [] watched_videos = []
while True: while True:
now = datetime.now () now = datetime.now ()
@@ -111,7 +117,7 @@ def main (
external = models.AppBskyEmbedExternal.External ( external = models.AppBskyEmbedExternal.External (
title = title, title = title,
description = description, description = description,
thumb = upload.blob, thumb = thumb,
uri = uri)) uri = uri))
client.post (Talk.main (f""" client.post (Talk.main (f"""
ニコニコに『{ datum['title'] }』という動画がアップされました。 ニコニコに『{ datum['title'] }』という動画がアップされました。
@@ -122,6 +128,7 @@ def main (
``` ```
このことについて、みんなに告知するとともに、ニジカちゃんの感想を教えてください。 """), このことについて、みんなに告知するとともに、ニジカちゃんの感想を教えてください。 """),
embed = embed_external) embed = embed_external)
last_posted_at = now
if now.hour == 14 and has_got_snack_time: if now.hour == 14 and has_got_snack_time:
has_got_snack_time = False has_got_snack_time = False
@@ -142,16 +149,40 @@ def main (
'下部に「おやつタイムだ!!!!」という' '下部に「おやつタイムだ!!!!」という'
'日本語のテキストが表示されている。'), '日本語のテキストが表示されている。'),
image = client.com.atproto.repo.upload_blob (f).blob) image = client.com.atproto.repo.upload_blob (f).blob)
client.post (Talk.main ('おやつタイムだ!!!!'), client.post (Talk.main ('おやつタイムだ!!!!'),
embed = models.app.bsky.embed.images.Main ( embed = models.app.bsky.embed.images.Main (
images = [image])) images = [image]))
last_posted_at = now last_posted_at = now
except Exception: except Exception:
pass pass
has_got_snack_time = True has_got_snack_time = True
if now.hour == 20 and has_got_snack_time:
has_taken_hot_spring = False
if now.hour == 21 and not has_taken_hot_spring:
try:
with open ('./assets/hot-spring.jpg', 'rb') as f:
image = models.AppBskyEmbedImages.Image (
alt = ('左に喜多ちゃん、右にわさび県産滋賀県が'
'V字に並んでいる。'
'喜多ちゃんは右手でピースサインをして'
'片目をウインクしている。'
'わさび県産滋賀県はただ茫然と'
'立ち尽くしている。'
'背景には'
'血と空の色をした放射線状の模様が広がり、'
'下部に「温泉に入ろう!!!」という'
'日本語のテキストが表示されている。'),
image = client.com.atproto.repo.upload_blob (f).blob)
client.post (Talk.main ('温泉に入ろう!!!'),
embed = models.app.bsky.embed.images.Main (
images = [image]))
last_posted_at = now
except Exception:
pass
has_taken_hot_spring = True
if now - last_posted_at >= timedelta (hours = 6): if now - last_posted_at >= timedelta (hours = 6):
client.post (Talk.main ('今どうしてる?')) client.post (Talk.main ('今どうしてる?'))
last_posted_at = now last_posted_at = now
@@ -161,7 +192,7 @@ def main (
def get_embed_info ( def get_embed_info (
url: str url: str
) -> (str, str, str): ) -> tuple[str, str, str]:
title: str = '' title: str = ''
description: str = '' description: str = ''
thumbnail: str = '' thumbnail: str = ''
@@ -181,12 +212,18 @@ def get_embed_info (
title = tmp.text title = tmp.text
tmp = soup.find ('meta', attrs = { 'name': 'description' }) tmp = soup.find ('meta', attrs = { 'name': 'description' })
if tmp is not None: if tmp is not None and hasattr (tmp, 'get'):
description = tmp.get ('content') try:
description = cast (str, tmp.get ('content'))
except Exception:
pass
tmp = soup.find ('meta', attrs = { 'name': 'thumbnail' }) tmp = soup.find ('meta', attrs = { 'name': 'thumbnail' })
if tmp is not None: if tmp is not None and hasattr (tmp, 'get'):
thumbnail = tmp.get ('content') try:
thumbnail = cast (str, tmp.get ('content'))
except Exception:
pass
return (title, description, thumbnail) return (title, description, thumbnail)
+1 -40
ファイルの表示
@@ -16,48 +16,9 @@ class VideoInfo (TypedDict):
description: str description: str
def get_nico_deerjika (
) -> list:
URL = ('https://snapshot.search.nicovideo.jp/api/v2/snapshot/video'
'/contents/search')
now = datetime.now ()
base = now - timedelta (hours = 24)
params = { 'q': '伊地知ニジカ OR ぼざろクリーチャーシリーズ',
'targets': 'tags',
'_sort': '-startTime',
'fields': 'contentId,title,description,tags,startTime',
'_limit': 20,
'jsonFilter': json.dumps ({ 'type': 'or',
'filters': [{
'type': 'range',
'field': 'startTime',
'from': ('%04d-%02d-%02dT05:00:00+09:00'
% (base.year, base.month, base.day,
base.hour, base.minute)),
'to': ('%04d-%02d-%02dT05:00:00+09:00'
% (now.year, now.month, now.day)),
'include_lower': True }] }) }
try:
res = requests.get (URL, params = params, timeout = 60).json ()
except Timeout:
return []
data = []
for datum in res['data']:
datum['tags'] = datum['tags'].split ()
data.append (datum)
return data
pass
def get_latest_deerjika ( def get_latest_deerjika (
) -> VideoInfo | None: ) -> VideoInfo | None:
tag = '伊地知ニジカ' tag = '伊地知ニジカ OR ぼざろクリーチャーシリーズ'
url = f"https://www.nicovideo.jp/tag/{ tag }" url = f"https://www.nicovideo.jp/tag/{ tag }"
params = { 'sort': 'f', params = { 'sort': 'f',