Skip to content

Commit

Permalink
增加了几组转推 & code cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
Ice9Coffee committed Apr 12, 2023
1 parent e047445 commit 4b825c1
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 107 deletions.
15 changes: 11 additions & 4 deletions hoshino/config_example/twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,25 @@
"kc-twitter": ["KanColle_STAFF", "C2_STAFF", "ywwuyi", "FlatIsNice"],
"pcr-twitter": ["priconne_redive", "priconne_anime"],
"uma-twitter": ["uma_musu", "uma_musu_anime"],
"ba-twitter": ["Blue_ArchiveJP"],
# "genshin-twitter": ["Genshin_7"],
"sr-twitter": ["houkaistarrail"],
"zzz-twitter": ["ZZZ_JP"],
"pripri-twitter": ["pripri_anime"],
"coffee-favorite-twitter": ["shiratamacaron", "k_yuizaki", "suzukitoto0323", "usagicandy_taku", "usagi_takumichi"],
"depress-artist-twitter": ["tkmiz"],
"moe-artist-twitter": [
"koma_momozu", "santamatsuri", "panno_mimi", "suimya", "Anmi_", "mamgon",
"kazukiadumi", "Setmen_uU", "bakuPA", "kantoku_5th", "done_kanda", "hoshi_u3",
"shiratamacaron", "k_yuizaki", "suzukitoto0323", "usagicandy_taku", "usagi_takumichi",
"koma_momozu", "koma_momozu_", "santamatsuri", "panno_mimi", "suimya", "Anmi_", "mamgon",
"kazukiadumi", "kazukiadumi_sub", "Setmen_uU", "bakuPA", "kantoku_5th", "done_kanda", "hoshi_u3",
"siragagaga", "fuzichoco", "miyu_miyasaka", "naco_miyasaka", "tsukimi08",
"tsubakinoniwa", "_Dan_ball", "ominaeshin", "gomalio_y", "izumiyuhina",
"1kurusk", "amsrntk3", "kani_biimu", "nahaki_401", "tukinose_miri",
"tsubakinoniwa", "ominaeshin", "gomalio_y", "izumiyuhina",
"1kurusk", "amsrntk3", "kani_biimu", "nahaki_401", "nahaki11", "sakura_oriko",
"ukiukisoda", "yukkieeeeeen", "t_takahashi0830", "riko0202", "amedamacon",
"Zoirun", "rulu_py", "zo3mie", "kurororo_rororo", "_namori_", "rasra25",
"mignon", "yyish", "tsukiyopoke", "halu_1113", "HenreaderH_", "SiErACitrus",
"heripiro", "tukiman02", "kakusatou_3333", "wasabilabel", "akakura1341",
"warabimoti_yoz", "koudasuzu", "roro046", "nimono_", "ma_sakasama",
],
}

Expand Down
2 changes: 1 addition & 1 deletion hoshino/modules/pcrclanbattle/clanbattle/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def deco(func) -> Callable:
@on_command('!帮助', aliases=('!帮助', '!幫助', '!幫助', '!help', '!help'), only_to_me=False)
async def cb_help(session:CommandSession):
await session.send(QUICK_START, at_sender=True)
msg = MessageSegment.share(url='https://github.com/Ice-Cirno/HoshinoBot/wiki/%E4%BC%9A%E6%88%98%E7%AE%A1%E7%90%86v2',
msg = MessageSegment.share(url='https://github.com/Ice9Coffee/HoshinoBot/wiki/%E4%BC%9A%E6%88%98%E7%AE%A1%E7%90%86v2',
title='Hoshino会战管理v2',
content='完整命令一览表')
await session.send(msg)
2 changes: 1 addition & 1 deletion hoshino/modules/priconne/games/avatar_guess.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ref: https://github.com/GWYOG/GWYOG-Hoshino-plugins/blob/master/pcravatarguess
# Originally written by @GWYOG
# Reflacted by @Ice-Cirno
# Reflacted by @Ice9Coffee
# GPL-3.0 Licensed
# Thanks to @GWYOG for his great contribution!

Expand Down
2 changes: 1 addition & 1 deletion hoshino/modules/priconne/games/desc_guess.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ref: https://github.com/GWYOG/GWYOG-Hoshino-plugins/blob/master/pcrdescguess
# Originally written by @GWYOG
# Reflacted by @Ice-Cirno
# Reflacted by @Ice9Coffee
# GPL-3.0 Licensed
# Thanks to @GWYOG for his great contribution!

Expand Down
2 changes: 1 addition & 1 deletion hoshino/modules/priconne/query/whois.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ async def whois(bot, ev: CQEvent):
lmt.start_cd(uid, 120 if guess else 0)
if guess:
name = filt_message(name)
msg = f'兰德索尔似乎没有叫"{name}"的人...\n角色别称补全计划: github.com/Ice-Cirno/LandosolRoster'
msg = f'兰德索尔似乎没有叫"{name}"的人...\n角色别称补全计划: github.com/Ice9Coffee/LandosolRoster'
await bot.send(ev, msg)
msg = f'您有{confi}%的可能在找{guess_name} {await c.get_icon_cqcode()} {c.name}'
await bot.send(ev, msg)
Expand Down
149 changes: 50 additions & 99 deletions hoshino/modules/twitter-v2/stream/follow.py
Original file line number Diff line number Diff line change
@@ -1,92 +1,35 @@
# 订阅推主

import asyncio
import itertools
import json
import os
import re
from collections import defaultdict
from dataclasses import dataclass, field
from typing import Dict, Iterable, Set

import peony
from peony import PeonyClient
from peony.exceptions import PeonyException

from hoshino import Service, priv
from hoshino.config import twitter as cfg
from hoshino.typing import MessageSegment as ms

from . import sv
from .util import format_tweet, cut_list
from .util import cut_list, format_tweet

# import logging
# sv.logger.setLevel(logging.DEBUG)

service_collection = [
Service("twitter-stream-test", enable_on_default=False, manage_priv=priv.SUPERUSER, visible=False),
Service("twitter-stream-test", enable_on_default=False, manage_priv=priv.SU, visible=False),
Service("kc-twitter", help_="艦これ推特转发", enable_on_default=False, bundle="kancolle"),
Service("pcr-twitter", help_="日服Twitter转发", enable_on_default=True, bundle="pcr订阅"),
# Service("uma-twitter", help_="ウマ娘推特转发", enable_on_default=False, bundle="umamusume"),
Service("ba-twitter", help_="蔚蓝档案日服推特转发", enable_on_default=False, bundle="ba"),
Service("sr-twitter", help_="崩坏星穹铁道日服推特转发", enable_on_default=False, bundle="mihoyo"),
Service("zzz-twitter", help_="绝区零日服推特转发", enable_on_default=False, bundle="mihoyo"),
# Service("pripri-twitter", help_="番剧《公主代理人》官推转发", enable_on_default=False),
# Service("coffee-favorite-twitter", help_="咖啡精选画师推特转发", enable_on_default=False, bundle="artist"),
Service("moe-artist-twitter", help_="萌系画师推特转发", enable_on_default=False, bundle="artist"),
# Service("depress-artist-twitter", help_="致郁系画师推特转发", enable_on_default=False, bundle="artist"),
]

'''
class UserIdCache:
_cache_file = os.path.expanduser("~/.hoshino/twitter_uid_cache.json")
def __init__(self) -> None:
self.cache = {}
if os.path.isfile(self._cache_file):
try:
with open(self._cache_file, "r", encoding="utf8") as f:
self.cache = json.load(f)
except Exception as e:
sv.logger.exception(e)
sv.logger.error(f"{type(e)} occured when loading `~/.hoshino/twitter_uid_cache.json`, using empty cache.")
def get(self, screen_name):
return self.cache.get(screen_name)
async def convert(self, client: PeonyClient, screen_names: Iterable[str], cached=True):
if not cached:
self.cache = {}
ids = []
for x in screen_names:
if x not in self.cache:
client = peony.BasePeonyClient(
consumer_key=cfg.consumer_key,
consumer_secret=cfg.consumer_secret,
access_token=cfg.access_token_key,
access_token_secret=cfg.access_token_secret,
auth=peony.oauth.OAuth2Headers,
api_version="2",
proxy=cfg.proxy,
suffix="")
async with client:
try:
user = await client.api.users.by.username[x].get()
self.cache[x] = user.id
except PeonyException as e:
sv.logger.error(f"{e} occurred when getting id of `{x}`")
id_ = self.cache.get(x)
if id_:
ids.append(id_)
with open(self._cache_file, "w", encoding="utf8") as f:
json.dump(self.cache, f)
return ids
_id_cache = UserIdCache()
'''

@dataclass
class FollowEntry:
Expand Down Expand Up @@ -126,6 +69,10 @@ def load(self, service_follow_dict, media_only_users, forward_retweet_users):


async def follow_stream():
follow_names = set()
for s in service_collection:
follow_names.update(cfg.follows.get(s.name, []))

client = peony.BasePeonyClient(
consumer_key=cfg.consumer_key,
consumer_secret=cfg.consumer_secret,
Expand All @@ -137,30 +84,28 @@ async def follow_stream():
suffix="",
)
async with client:
follow_screen_names = set(itertools.chain(*cfg.follows.values()))
# follow_ids = await _id_cache.convert(client, follow_screen_names)

router = TweetRouter()
router.load(cfg.follows, cfg.media_only_users, cfg.forward_retweet_users)

sv.logger.info(f"订阅推主{len(follow_screen_names)}个帐号: {follow_screen_names}")
sv.logger.info(f"订阅推主{len(follow_names)}个帐号: {follow_names}")

resp = await client.api.tweets.search.stream.rules.get() #先获取上一次的规则
data = resp.get('data')
if resp.get('data'): #然后删除上一次的规则
# 删除上一次的规则
resp = await client.api.tweets.search.stream.rules.get() # 先获取上一次的规则
data = resp.get("data")
if resp.get("data"):
ids = list(map(lambda rule: rule["id"], data))
payload = {"delete": {"ids": ids}}
resp = await client.api.tweets.search.stream.rules.post(_json=payload)
users = cut_list(follow_screen_names) #处理数据,准备将config里follow所有人写入规则
userqueue=""
for user in users:
user = " OR from:".join(user)
user = f'"from:{user}"'
userqueue += "{{'value': {},}},".format(user)
data = eval("{{'add': [{}]}}".format(userqueue))
resp = await client.api.tweets.search.stream.rules.post(_json=data) #写入新规则
#sv.logger.info(resp) #如果stream流启动失败请查看规则是否已经写入

# 写入新规则
follow_name_chunks = cut_list(follow_names) # 处理数据,准备将config里follow所有人写入规则
rules = [] # 规则最多10个,所以要分批写入
for chunk in follow_name_chunks:
rule = {"value": f'"from:{" OR from:".join(chunk)}"'}
rules.append(rule)
data = {"add": rules}
resp = await client.api.tweets.search.stream.rules.post(_json=data)
# sv.logger.info(resp) # 如果stream流启动失败请查看规则是否已经写入
fields = {
"tweet.fields": [
"created_at",
Expand All @@ -170,36 +115,42 @@ async def follow_stream():
"author_id",
"in_reply_to_user_id",
"attachments",

],
"expansions":["author_id", "attachments.media_keys"], #不要删media_keys,否则下行不生效
"media.fields":["url", "preview_image_url"],
"expansions": [
"author_id",
"attachments.media_keys", # 不要删media_keys,否则下行不生效
],
"media.fields": ["url", "preview_image_url"],
}
stream = client.api.tweets.search.stream.get.stream(**fields) #启动stream流
async for tweet in stream: #当stream流收到信息:

stream = client.api.tweets.search.stream.get.stream(**fields) # 启动stream流
async for tweet in stream: # 当stream流收到信息:
sv.logger.info("Got twitter event.")
if tweet.get('data'):

if tweet.get("data"):
sv.logger.debug(tweet)
username = tweet.get('includes')['users'][0]['username']
username = tweet.get("includes")["users"][0]["username"]
entry = router.follows[username]

sv.logger.debug(entry)

if username not in router.follows: # 推主不在订阅列表
if username not in router.follows: # 推主不在订阅列表
sv.logger.debug(f"推主{username}不在订阅列表")
continue
if "referenced_tweets" in tweet.get('data'):
if 'retweeted' in tweet.get('data').referenced_tweets[0].type and not entry.forward_retweet:
continue

if "referenced_tweets" in tweet.get("data"):
if ("retweeted" in tweet.get("data").referenced_tweets[0].type and not entry.forward_retweet):
sv.logger.debug("纯转推,已忽略")
continue # 除非配置制定,忽略纯转推
if 'in_reply_to_user_id'in tweet.get('data'):
if tweet.get('data').in_reply_to_user_id != username:
sv.logger.debug("回复他人,已忽略")
continue # 忽略对他人的评论,保留自评论
if 'media' not in tweet.get('includes') and entry.media_only:
continue # 除非配置制定,忽略纯转推

if "in_reply_to_user_id" in tweet.get("data"):
if tweet.get("data").in_reply_to_user_id != username:
sv.logger.debug("回复他人,已忽略")
continue # 忽略对他人的评论,保留自评论

if "media" not in tweet.get("includes") and entry.media_only:
sv.logger.debug("无附带媒体,订阅选项media_only=True,已忽略")
continue # 无附带媒体,订阅选项media_only=True时忽略
continue # 无附带媒体,订阅选项media_only=True时忽略

msg = await format_tweet(tweet, client)
sv.logger.info(f"推送推文:\n{msg}")
for s in entry.services:
Expand Down

0 comments on commit 4b825c1

Please sign in to comment.