温泉追加とリファクタリング
このコミットが含まれているのは:
バイナリファイルは表示されません.
|
変更後 幅: | 高さ: | サイズ: 221 KiB |
@@ -1,8 +1,13 @@
|
||||
"""
|
||||
Bluesky のニジカがいろいろする.
|
||||
(近々機能ごとにファイル分けて systemd でイベント管理する予定)
|
||||
"""
|
||||
|
||||
import io
|
||||
import json
|
||||
import time
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
from typing import cast
|
||||
|
||||
import requests
|
||||
from atproto import Client, models
|
||||
@@ -22,7 +27,7 @@ def check_notifications (
|
||||
for notification in (client.app.bsky.notification.list_notifications ()
|
||||
.notifications):
|
||||
if not notification.is_read:
|
||||
if notification.reason in ['mention', 'reply']:
|
||||
if notification.reason in ['mention', 'reply', 'quote']:
|
||||
uris += [notification.uri]
|
||||
elif notification.reason == 'follow':
|
||||
client.follow (notification.author.did)
|
||||
@@ -62,6 +67,7 @@ def main (
|
||||
|
||||
last_posted_at = datetime.now () - timedelta (hours = 6)
|
||||
has_got_snack_time = False
|
||||
has_taken_hot_spring = False
|
||||
watched_videos = []
|
||||
while True:
|
||||
now = datetime.now ()
|
||||
@@ -111,7 +117,7 @@ def main (
|
||||
external = models.AppBskyEmbedExternal.External (
|
||||
title = title,
|
||||
description = description,
|
||||
thumb = upload.blob,
|
||||
thumb = thumb,
|
||||
uri = uri))
|
||||
client.post (Talk.main (f"""
|
||||
ニコニコに『{ datum['title'] }』という動画がアップされました。
|
||||
@@ -122,6 +128,7 @@ def main (
|
||||
```
|
||||
このことについて、みんなに告知するとともに、ニジカちゃんの感想を教えてください。 """),
|
||||
embed = embed_external)
|
||||
last_posted_at = now
|
||||
|
||||
if now.hour == 14 and has_got_snack_time:
|
||||
has_got_snack_time = False
|
||||
@@ -142,16 +149,40 @@ def main (
|
||||
'下部に「おやつタイムだ!!!!」という'
|
||||
'日本語のテキストが表示されている。'),
|
||||
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_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):
|
||||
client.post (Talk.main ('今どうしてる?'))
|
||||
last_posted_at = now
|
||||
@@ -161,7 +192,7 @@ def main (
|
||||
|
||||
def get_embed_info (
|
||||
url: str
|
||||
) -> (str, str, str):
|
||||
) -> tuple[str, str, str]:
|
||||
title: str = ''
|
||||
description: str = ''
|
||||
thumbnail: str = ''
|
||||
@@ -181,12 +212,18 @@ def get_embed_info (
|
||||
title = tmp.text
|
||||
|
||||
tmp = soup.find ('meta', attrs = { 'name': 'description' })
|
||||
if tmp is not None:
|
||||
description = tmp.get ('content')
|
||||
if tmp is not None and hasattr (tmp, 'get'):
|
||||
try:
|
||||
description = cast (str, tmp.get ('content'))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
tmp = soup.find ('meta', attrs = { 'name': 'thumbnail' })
|
||||
if tmp is not None:
|
||||
thumbnail = tmp.get ('content')
|
||||
if tmp is not None and hasattr (tmp, 'get'):
|
||||
try:
|
||||
thumbnail = cast (str, tmp.get ('content'))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return (title, description, thumbnail)
|
||||
|
||||
|
||||
@@ -16,48 +16,9 @@ class VideoInfo (TypedDict):
|
||||
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 (
|
||||
) -> VideoInfo | None:
|
||||
tag = '伊地知ニジカ'
|
||||
tag = '伊地知ニジカ OR ぼざろクリーチャーシリーズ'
|
||||
url = f"https://www.nicovideo.jp/tag/{ tag }"
|
||||
|
||||
params = { 'sort': 'f',
|
||||
|
||||
新しい課題から参照
ユーザをブロックする