Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔖 发布 1.6.0 #72

Merged
merged 15 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
if: ${{ matrix.group == 'full' }}
env:
PLAYWRIGHT_BROWSERS_PATH: "0"
run: pdm run playwright install firefox
run: pdm run playwright install chromium

- name: Install Pyinstaller
run: pdm add pyinstaller
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
if: ${{ matrix.group == 'full' }}
env:
PLAYWRIGHT_BROWSERS_PATH: "0"
run: pdm run playwright install firefox
run: pdm run playwright install chromium

- name: Replease Playwright Path
if: ${{ matrix.group == 'full' }}
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN --mount=type=tmpfs,target=/var/cache/apt/archives \
--mount=type=tmpfs,target=/var/lib/apt/lists \
--mount=type=tmpfs,target=/tmp \
sed -i 's/main/main non-free/g' /etc/apt/sources.list && \
python -m playwright install --with-deps firefox
python -m playwright install --with-deps chromium
COPY . .
VOLUME /bbot/data
EXPOSE 6080
Expand Down
2 changes: 1 addition & 1 deletion aunly_bbot/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@

app.launch_manager.add_service(
PlaywrightService(
browser_type="firefox",
browser_type="chromium",
user_data_dir=Path("data").joinpath("browser"),
device_scale_factor=1.5 if BotConfig.Bilibili.mobile_style else 1.25,
user_agent=(
Expand Down
2 changes: 1 addition & 1 deletion aunly_bbot/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def install_deps():
import sys
from playwright.__main__ import main as pw_main

sys.argv.append("firefox")
sys.argv.append("chromium")
pw_main()


Expand Down
6 changes: 3 additions & 3 deletions aunly_bbot/cli/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ async def init_playwright():
font_init()
logger.success("字体下载完成!")

await install_playwright(browser_type="firefox")
await install_playwright(browser_type="chromium")
pw = await async_playwright().start()
ff = await pw.firefox.launch_persistent_context(
chrome = await pw.chromium.launch_persistent_context(
Path("data").joinpath("browser"),
device_scale_factor=1.5,
user_agent=(
Expand All @@ -41,7 +41,7 @@ async def init_playwright():
),
# headless=False,
)
PLAYWRIGIT = ff
PLAYWRIGIT = chrome
logger.info("[Playwright] 正在获取浏览器版本")
if len(PLAYWRIGIT.pages) > 0:
page = PLAYWRIGIT.pages[0]
Expand Down
32 changes: 20 additions & 12 deletions aunly_bbot/function/command/up/get_subscribe.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
from graia.saya import Channel
from graia.ariadne.app import Ariadne
from graia.ariadne.model import Group
from graia.ariadne.message.element import At
from graia.ariadne.event.message import GroupMessage
from graia.ariadne.message.chain import MessageChain
from graia.saya.builtins.broadcast.schema import ListenerSchema
from graia.ariadne.message.element import At
from graia.ariadne.message.parser.twilight import (
Twilight,
RegexMatch,
ElementMatch,
ElementResult,
RegexMatch,
Twilight,
)

from graia.ariadne.model import Group
from graia.saya import Channel
from graia.saya.builtins.broadcast.schema import ListenerSchema
import time
from ....core import BOT_Status
from ....core.bot_config import BotConfig
from ....core.data import get_sub_by_group
from ....core.control import Interval, Permission
from ....core.data import get_sub_by_group
from ....utils.time_tools import calc_time_total

channel = Channel.current()

Expand All @@ -34,14 +36,20 @@ async def sub_list(app: Ariadne, group: Group, at: ElementResult):
if at_element.target != BotConfig.Mirai.account:
return
sublist = get_sub_by_group(group.id)

sublist_count = len(sublist)
if sublist_count == 0:
await app.send_group_message(group, MessageChain("本群未订阅任何 UP"))
else:
msg = [f"本群共订阅 {sublist_count} 个 UP\n注:带*号的表示该 UP 已被设定自定义昵称"]
msg.extend(
f"\n{i}. {f'*{data.nick}' if data.nick else data.uname}({data.uid})"
for i, data in enumerate(sublist, 1)
)
for i, sub in enumerate(sublist, 1):
live_time = BOT_Status.living.get(str(sub.uid), -1)
if live_time > 100000:
live = f" 🔴直播中: {calc_time_total(time.time() - live_time)}"
elif live_time >= 0:
live = " 🔴直播中"
else:
live = ""
msg.append(f"\n{i}. {f'*{sub.nick}' if sub.nick else sub.uname}({sub.uid}){live}")

await app.send_group_message(group, MessageChain(msg))
6 changes: 3 additions & 3 deletions aunly_bbot/function/command/up/subscribe.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ async def main(app: Ariadne, group: Group, at: ElementResult, anything: RegexRes
MessageChain("正在初始化,请稍后..."),
)
message = anything.result.display # type: ignore
uid = await uid_extract(message)
if uid:
uid = await uid_extract(message, show_error=True)
if uid and uid.isdigit():
if not BOT_Status.check_status(Status.DYNAMIC_IDLE):
await app.send_group_message(
group,
Expand All @@ -67,5 +67,5 @@ async def main(app: Ariadne, group: Group, at: ElementResult, anything: RegexRes
else:
await app.send_group_message(
group,
MessageChain("未找到该 UP,请输入正确的 UP 群内昵称、UP 名、UP UID或 UP 首页链接"),
MessageChain(uid or "未找到该 UP,请输入正确的 UP 群内昵称、UP 名、UP UID或 UP 首页链接"),
)
6 changes: 3 additions & 3 deletions aunly_bbot/function/command/vive_dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ async def main(
up: RegexResult,
offset: RegexResult,
):

if not (uid := await uid_extract(up.result.display, group.id)):
uid = await uid_extract(text=up.result.display, groupid=group.id, show_error=True)
if not uid or not uid.isdigit():
return await app.send_group_message(
group,
MessageChain("未找到该 UP,请输入正确的 UP 群内昵称、UP 名、UP UID或 UP 首页链接"),
MessageChain(uid or "未找到该 UP,请输入正确的 UP 群内昵称、UP 名、UP UID或 UP 首页链接"),
quote=source,
)

Expand Down
4 changes: 2 additions & 2 deletions aunly_bbot/function/pusher/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
channel = Channel.current()


@channel.use(SchedulerSchema(every_custom_seconds(3)))
@channel.use(SchedulerSchema(every_custom_seconds(BotConfig.Bilibili.dynamic_interval)))
async def main(app: Ariadne):
logger.debug("[Dynamic Pusher] Dynamic Pusher running now...")
subid_list = get_all_uid()
Expand Down Expand Up @@ -140,7 +140,7 @@ async def main(app: Ariadne):
BOT_Status.last_finish = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
BOT_Status.set_status(Status.DYNAMIC_IDLE, True)
logger.debug("[Dynamic] Updating finished")
await asyncio.sleep(0.5)
await asyncio.sleep(3)


async def push(app: Ariadne, dyn: DynamicItem):
Expand Down
2 changes: 1 addition & 1 deletion aunly_bbot/function/pusher/live.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
channel = Channel.current()


@channel.use(SchedulerSchema(every_custom_seconds(3)))
@channel.use(SchedulerSchema(every_custom_seconds(BotConfig.Bilibili.dynamic_interval)))
async def main(app: Ariadne):
if (
not BOT_Status.is_all_statuses_true(
Expand Down
7 changes: 4 additions & 3 deletions aunly_bbot/model/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ class _Bilibili(BaseModel, extra=Extra.ignore):
allow_fallback: bool = True
mobile_style: bool = True
render_style: Literal["bbot_default", "style_blue"] = "bbot_default"
concurrency: int = 5
concurrency: int = 1
dynamic_interval: int = 30
dynamic_font: str = "HarmonyOS_Sans_SC_Medium.ttf"
dynamic_font_source: Literal["local", "remote"] = "local"
openai_summarization: bool = False
Expand Down Expand Up @@ -121,8 +122,8 @@ def valid_openai_promot_version(cls, openai_promot_version):
# 验证 Bilibili gRPC 并发数
@validator("concurrency")
def limit_concurrency(cls, concurrency):
if concurrency > 50:
click.secho("gRPC 并发数超过 50,已自动调整为 50", fg="bright_yellow")
if concurrency > 5:
click.secho("gRPC 并发数超过 5,已自动调整为 5", fg="bright_yellow")
return 50
elif concurrency < 1:
click.secho("gRPC 并发数小于 1,已自动调整为 1", fg="bright_yellow")
Expand Down
12 changes: 6 additions & 6 deletions aunly_bbot/static/mobile_style.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
* @Author: KBD
* @Date: 2022-12-26 13:45:30
* @LastEditors: KBD
* @LastEditTime: 2023-01-13 01:35:34
* @LastEditTime: 2023-06-28 10:55:31
* @Description: 用于初始化手机动态页面的样式以及图片大小
*/
async function getMobileStyle() {
async function getMobileStyle(useImageBig = true) {
// 删除 dom 的对象, 可以自行添加 ( className 需要增加 '.' 为前缀, id 需要增加 '#' 为前缀)
const deleteDoms = {
// 关注 dom
Expand Down Expand Up @@ -51,7 +51,7 @@ async function getMobileStyle() {

// 获取图片容器的所有 dom 数组
const imageItemDoms = Array.from(document.querySelectorAll(".bm-pics-block__item"));

// 获取图片长宽比例
const getImageRatio = (url) => {
return new Promise((resolve, reject) => {
Expand Down Expand Up @@ -85,7 +85,7 @@ async function getMobileStyle() {
const isAllOneLength = ratioList.filter(item => item >= 0.9 && item <= 1.1).length;
const isAllOne = ratioList.length === 9 ? isAllOneLength > ratioList.length / 2 : isAllOneLength > 0 && isAllOneLength % 3 === 0 && ratioList.length > 3;
// 说明可能为组装的拼图, 如果不是则放大为大图
if (!isAllOne) {
if (!isAllOne && useImageBig) {
// 找到图标容器dom
const containerDom = document.querySelector(".bm-pics-block__container");
if (containerDom) {
Expand Down Expand Up @@ -138,7 +138,7 @@ async function getMobileStyle() {
item.firstChild.src = ratio > 3 ? imgSrc.slice(0, imgSrcAtIndex + 1) + "260w_260h_!header.webp" : imgSrc.slice(0, imgSrcAtIndex + 1) + "260w_260h_1e_1c.webp";
});
}
})
})
}


Expand Down Expand Up @@ -231,4 +231,4 @@ function fontsLoaded() {

window.onload = () => {
getMobileStyle();
}
}
9 changes: 5 additions & 4 deletions aunly_bbot/utils/bilibili_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,12 @@ async def search_user(keyword: str):
"""
搜索用户
"""
url = "https://api.bilibili.com/x/web-interface/search/type"
data = {"keyword": keyword, "search_type": "bili_user"}
resp = (await hc.get(url, params=data)).json()
url = "https://app.bilibili.com/x/v2/search/type"
data = {"build": "6840300", "keyword": keyword, "type": "2", "ps": 5}

resp = await get(url, params=data)
logger.debug(resp)
return resp["data"]
return resp


async def get_user_space_info(uid: int):
Expand Down
61 changes: 41 additions & 20 deletions aunly_bbot/utils/browser_shot.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,25 @@
import re
import time
import httpx
import asyncio
import contextlib

from yarl import URL
import re
import time
from pathlib import Path
from loguru import logger
import json

import httpx
from graia.ariadne import Ariadne
from sentry_sdk import capture_exception
from playwright._impl._api_types import TimeoutError
from graiax.playwright.interface import PlaywrightContext
from loguru import logger
from playwright._impl._api_structures import Position
from playwright.async_api._generated import (
Page,
Route,
Request,
Response,
BrowserContext,
)
from playwright._impl._api_types import TimeoutError
from playwright.async_api._generated import BrowserContext, Page, Request, Response, Route
from sentry_sdk import capture_exception
from yarl import URL

from ..core.bot_config import BotConfig
from ..model.captcha import CaptchaResponse

from .fonts_provider import get_font


browser_cookies_file = Path("data").joinpath("browser_cookies.json")
error_path = Path("data").joinpath("error")
error_path.mkdir(parents=True, exist_ok=True)
captcha_path = Path("data").joinpath("captcha")
Expand Down Expand Up @@ -64,9 +58,30 @@ async def resolve_select_captcha(page: Page):
async def browser_dynamic(dynid: str):
app = Ariadne.current()
browser_context = app.launch_manager.get_interface(PlaywrightContext).context
# add cookies
if browser_cookies_file.exists() and browser_cookies_file.is_file():
if browser_cookies := json.loads(browser_cookies_file.read_bytes()):
logger.debug(f"正在为浏览器添加cookies")
await browser_context.add_cookies(
[
{
"domain": cookie["domain"],
"name": cookie["name"],
"path": cookie["path"],
"value": cookie["value"],
}
for cookie in browser_cookies
]
)
return await screenshot(dynid, browser_context)


async def refresh_cookies(browser_context: BrowserContext):
storage_state = await browser_context.storage_state()
if cookies := storage_state.get("cookies"):
browser_cookies_file.write_text(json.dumps(cookies))


async def screenshot(dynid: str, browser_context: BrowserContext, log=True):
logger.info(f"正在截图动态:{dynid}")
st = int(time.time())
Expand All @@ -82,11 +97,16 @@ async def screenshot(dynid: str, browser_context: BrowserContext, log=True):
else:
page, clip = await get_pc_screenshot(page, dynid)
clip["height"] = min(clip["height"], 32766) # 限制高度
return await page.screenshot(clip=clip, full_page=True, type="jpeg", quality=98)
if picture := await page.screenshot(
clip=clip, full_page=True, type="jpeg", quality=98
):
await refresh_cookies(browser_context)
return picture
except TimeoutError:
logger.error(f"[BiliBili推送] {dynid} 动态截图超时,正在重试:")
except Notfound:
logger.error(f"[Bilibili推送] {dynid} 动态不存在")
logger.error(f"[Bilibili推送] {dynid} 动态不存在,等待 3 秒后重试...")
await asyncio.sleep(3)
except AssertionError:
logger.exception(f"[BiliBili推送] {dynid} 动态截图失败,正在重试:")
await page.screenshot(
Expand All @@ -98,6 +118,7 @@ async def screenshot(dynid: str, browser_context: BrowserContext, log=True):
except Exception as e: # noqa
if "bilibili.com/404" in page.url:
logger.error(f"[Bilibili推送] {dynid} 动态不存在")
await refresh_cookies(browser_context)
break
elif "waiting until" in str(e):
logger.error(f"[BiliBili推送] {dynid} 动态截图超时,正在重试:")
Expand Down Expand Up @@ -220,7 +241,6 @@ async def captcha_result_callback(response: Response):
}
await captcha_image.click(position=Position(**real_click_points))
await page.wait_for_timeout(800)
captcha_image_body = ""
await page.click("text=确认")
geetest_up = await page.wait_for_selector(".geetest_up", state="visible")
await page.screenshot(path=captcha_path.joinpath(f"{last_captcha_id}.jpg"))
Expand All @@ -232,6 +252,7 @@ async def captcha_result_callback(response: Response):
logger.debug(f"[Captcha] Geetest result: {geetest_result}")
if "验证成功" in geetest_result:
logger.success("[Captcha] 极验网页 Tip 验证成功")
captcha_image_body = ""
else:
logger.warning("[Captcha] 极验验证失败,正在重试")

Expand Down
Loading