update frontend

This commit is contained in:
felinae98 2021-11-19 14:22:04 +08:00
parent f8a7eda467
commit ff8803e89b
No known key found for this signature in database
GPG Key ID: 00C8B010587FF610
7 changed files with 293 additions and 49 deletions

View File

@ -26,3 +26,8 @@ export async function addSubscribe(groupNumber: string, req: CreateSubscribeReq)
const res = await axios.post(`${baseUrl}subs`, req, {params: {groupNumber}}) const res = await axios.post(`${baseUrl}subs`, req, {params: {groupNumber}})
return res.data; return res.data;
} }
export async function delSubscribe(groupNumber: string, platformName: string, target: string) {
const res = await axios.delete(`${baseUrl}subs`, {params: {groupNumber, platformName, target}});
return res.data;
}

View File

@ -107,7 +107,7 @@ export function InputTag(prop: InputTagProp) {
onPressEnter={handleInputConfirm} /> onPressEnter={handleInputConfirm} />
)} )}
{!inputVisible && ( {!inputVisible && (
<Tag className="site-tag-plus" onClick={showInput} style={{background: '#fff', border: 'dashed'}}> <Tag className="site-tag-plus" onClick={showInput} style={{background: '#fff', border: 'dashed thin', borderColor: '#bfbfbf' }}>
<PlusOutlined/> {prop.addText || "Add Tag"} <PlusOutlined/> {prop.addText || "Add Tag"}
</Tag> </Tag>
)} )}

View File

@ -1,18 +1,16 @@
import React, { ReactElement, useContext, useEffect, useState } from "react"; import React, { ReactElement, useContext, useEffect, useState } from "react";
import { LoginContext, GlobalConfContext } from "../utils/context"; import { LoginContext, GlobalConfContext } from "../utils/context";
import { Layout, Menu, Empty, Collapse, Card, Tag, Row, Col, Form, Tooltip, Button, Modal, Select, import { Layout, Menu, Empty, Collapse, Card, Tag, Row, Col, Form, Tooltip, Button, Modal, Select,
Input} from 'antd'; Input, Popconfirm} from 'antd';
import { SubscribeConfig, SubscribeResp, PlatformConfig, CategoryConfig } from '../utils/type'; import { SubscribeConfig, SubscribeResp, PlatformConfig, CategoryConfig } from '../utils/type';
import { SettingOutlined, BugOutlined, DeleteOutlined, CopyOutlined, PlusOutlined } from '@ant-design/icons'; import { SettingOutlined, BugOutlined, DeleteOutlined, CopyOutlined } from '@ant-design/icons';
import { getSubscribe, getTargetName } from '../api/config'; import { getSubscribe, getTargetName, addSubscribe, delSubscribe } from '../api/config';
import { InputTag } from '../component/inputTag'; import { InputTag } from '../component/inputTag';
import _ from "lodash";
import './admin.css'; import './admin.css';
export function Admin() { export function Admin() {
const { login } = useContext(LoginContext); const { login } = useContext(LoginContext);
const [ tab, changeTab ] = useState("manage"); const [ tab, changeTab ] = useState("manage");
const globalConfContext = useContext(GlobalConfContext);
return ( return (
<Layout style={{ minHeight: '100vh' }}> <Layout style={{ minHeight: '100vh' }}>
<Layout.Sider className="layout-side"> <Layout.Sider className="layout-side">
@ -21,7 +19,7 @@ export function Admin() {
<Menu mode="inline" theme="dark" defaultSelectedKeys={[tab]} <Menu mode="inline" theme="dark" defaultSelectedKeys={[tab]}
onClick={({key}) => changeTab(key)}> onClick={({key}) => changeTab(key)}>
<Menu.Item key="manage" icon={<SettingOutlined />}></Menu.Item> <Menu.Item key="manage" icon={<SettingOutlined />}></Menu.Item>
{ login.type == 'admin' && { login.type === 'admin' &&
<Menu.Item key="log" icon={<BugOutlined />}></Menu.Item> <Menu.Item key="log" icon={<BugOutlined />}></Menu.Item>
} }
</Menu> </Menu>
@ -29,7 +27,7 @@ export function Admin() {
<Layout.Content> <Layout.Content>
<div style={{margin: '24px', background: '#fff', minHeight: '640px'}}> <div style={{margin: '24px', background: '#fff', minHeight: '640px'}}>
{ {
tab == 'manage' ? tab === 'manage' ?
<ConfigPage tab={tab}/> <ConfigPage tab={tab}/>
: null : null
} }
@ -45,24 +43,37 @@ interface ConfigPageProp {
function ConfigPage(prop: ConfigPageProp) { function ConfigPage(prop: ConfigPageProp) {
const [ configData, setConfigData ] = useState<SubscribeResp>({}); const [ configData, setConfigData ] = useState<SubscribeResp>({});
const [ showModal, setShowModal ] = useState<boolean>(false); const [ showModal, setShowModal ] = useState<boolean>(false);
const [ currentAddingGroupNumber, setCurrentAddingGroupNumber ] = useState('');
const globalConf = useContext(GlobalConfContext); const globalConf = useContext(GlobalConfContext);
useEffect(() => { const loadData = () => {
getSubscribe() getSubscribe()
.then(res => { .then(res => {
setConfigData(_ => res); setConfigData(_ => res);
}); });
}
useEffect(() => {
loadData()
}, [prop.tab]); }, [prop.tab]);
const clickNew = (e: React.MouseEvent<HTMLButtonElement>) => { const clickNew = (groupNumber: string) => (e: React.MouseEvent<HTMLButtonElement>) => {
setShowModal(_ => true); setShowModal(_ => true);
setCurrentAddingGroupNumber(groupNumber);
e.stopPropagation(); e.stopPropagation();
} }
const genCard = (config: SubscribeConfig) => { const handleDelete = (groupNumber: string, platformName: string, target: string) => () => {
const platformConf = globalConf.platformConf[config.targetType] as PlatformConfig; delSubscribe(groupNumber, platformName, target).then(() => {
loadData()
})
}
const genCard = (groupNumber: string) => (config: SubscribeConfig) => {
const platformConf = globalConf.platformConf[config.platformName] as PlatformConfig;
return ( return (
<Col span={6} key={`${config.targetType}-${config.target}`}> <Col span={6} key={`${config.platformName}-${config.target}`}>
<Card title={`${platformConf.name} - ${config.targetName}`} <Card title={`${platformConf.name} - ${config.targetName}`}
actions={[ actions={[
<Tooltip title="删除"><DeleteOutlined /></Tooltip>, <Popconfirm title={`确定要删除 ${platformConf.name} - ${config.targetName}`}
onConfirm={handleDelete(groupNumber, config.platformName, config.target || 'default')}>
<Tooltip title="删除" ><DeleteOutlined /></Tooltip>
</Popconfirm>,
<Tooltip title="添加到其他群"><CopyOutlined /></Tooltip> <Tooltip title="添加到其他群"><CopyOutlined /></Tooltip>
]}> ]}>
<Form labelCol={{ span: 6 }}> <Form labelCol={{ span: 6 }}>
@ -87,9 +98,11 @@ function ConfigPage(prop: ConfigPageProp) {
for (let key of Object.keys(configData)) { for (let key of Object.keys(configData)) {
let value = configData[key]; let value = configData[key];
groups.push( groups.push(
<Collapse.Panel header={<span>{`${key} - ${value.name}`}<Button style={{float: "right"}} onClick={clickNew}></Button></span>} key={key}> <Collapse.Panel header={
<span>{`${key} - ${value.name}`}<Button style={{float: "right"}} onClick={clickNew(key)}></Button></span>
} key={key}>
<Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }} align="middle"> <Row gutter={{ xs: 8, sm: 16, md: 24, lg: 32 }} align="middle">
{value.subscribes.map(genCard)} {value.subscribes.map(genCard(key))}
</Row> </Row>
</Collapse.Panel> </Collapse.Panel>
) )
@ -99,7 +112,8 @@ function ConfigPage(prop: ConfigPageProp) {
<Collapse> <Collapse>
{groups} {groups}
</Collapse> </Collapse>
<AddModal showModal={showModal} setShowModal={(s: boolean) => setShowModal(_ => s)} /> <AddModal groupNumber={currentAddingGroupNumber} showModal={showModal}
refresh={loadData} setShowModal={(s: boolean) => setShowModal(_ => s)} />
</div> </div>
) )
} }
@ -107,7 +121,8 @@ function ConfigPage(prop: ConfigPageProp) {
interface InputTagCustomProp { interface InputTagCustomProp {
value?: Array<string>, value?: Array<string>,
onChange?: (value: Array<string>) => void onChange?: (value: Array<string>) => void,
disabled?: boolean
} }
function InputTagCustom(prop: InputTagCustomProp) { function InputTagCustom(prop: InputTagCustomProp) {
const [value, setValue] = useState(prop.value || []); const [value, setValue] = useState(prop.value || []);
@ -119,27 +134,36 @@ function InputTagCustom(prop: InputTagCustomProp) {
} }
return ( return (
<> <>
{value.length === 0 && {
<Tag color="green"></Tag> prop.disabled ? <Tag color="red"></Tag>:
} <>
<InputTag color="blue" addText="添加标签" value={value} onChange={handleSetValue} /> {value.length === 0 &&
<Tag color="green"></Tag>
}
<InputTag color="blue" addText="添加标签" value={value} onChange={handleSetValue} />
</>
}
</> </>
) )
} }
interface AddModalProp { interface AddModalProp {
showModal: boolean, showModal: boolean,
setShowModal: (s: boolean) => void groupNumber: string,
setShowModal: (s: boolean) => void,
refresh: () => void
} }
function AddModal(prop: AddModalProp) { function AddModal(prop: AddModalProp) {
const [ confirmLoading, setConfirmLoading ] = useState<boolean>(false); const [ confirmLoading, setConfirmLoading ] = useState<boolean>(false);
const { platformConf } = useContext(GlobalConfContext); const { platformConf } = useContext(GlobalConfContext);
const [ hasTarget, setHasTarget ] = useState(false); const [ hasTarget, setHasTarget ] = useState(false);
const [ categories, setCategories ] = useState({} as CategoryConfig); const [ categories, setCategories ] = useState({} as CategoryConfig);
const [ enabledTag, setEnableTag ] = useState(false);
const [ form ] = Form.useForm(); const [ form ] = Form.useForm();
const changePlatformSelect = (platform: string) => { const changePlatformSelect = (platform: string) => {
setHasTarget(_ => platformConf[platform].hasTarget); setHasTarget(_ => platformConf[platform].hasTarget);
setCategories(_ => platformConf[platform].categories); setCategories(_ => platformConf[platform].categories);
setEnableTag(platformConf[platform].enabledTag)
if (! platformConf[platform].hasTarget) { if (! platformConf[platform].hasTarget) {
getTargetName(platform, 'default') getTargetName(platform, 'default')
.then(res => { .then(res => {
@ -157,7 +181,19 @@ function AddModal(prop: AddModalProp) {
} }
} }
const handleSubmit = (value: any) => { const handleSubmit = (value: any) => {
console.log(value); let newVal = Object.assign({}, value)
if (typeof newVal.tags != 'object') {
newVal.tags = []
}
if (newVal.target === '') {
newVal.target = 'default'
}
addSubscribe(prop.groupNumber, newVal)
.then(() => {
setConfirmLoading(false);
prop.setShowModal(false);
prop.refresh();
});
} }
const handleModleFinish = () => { const handleModleFinish = () => {
form.submit(); form.submit();
@ -167,8 +203,9 @@ function AddModal(prop: AddModalProp) {
return <Modal title="添加订阅" visible={prop.showModal} return <Modal title="添加订阅" visible={prop.showModal}
confirmLoading={confirmLoading} onCancel={() => prop.setShowModal(false)} confirmLoading={confirmLoading} onCancel={() => prop.setShowModal(false)}
onOk={handleModleFinish}> onOk={handleModleFinish}>
<Form form={form} labelCol={{ span: 6 }} name="b" onFinish={handleSubmit}> <Form form={form} labelCol={{ span: 6 }} name="b" onFinish={handleSubmit}
<Form.Item label="平台" name="platformType" rules={[]}> initialValues={{tags: [], categories: []}}>
<Form.Item label="平台" name="platformName" rules={[]}>
<Select style={{ width: '80%' }} onChange={changePlatformSelect}> <Select style={{ width: '80%' }} onChange={changePlatformSelect}>
{Object.keys(platformConf).map(platformName => {Object.keys(platformConf).map(platformName =>
<Select.Option key={platformName} value={platformName}>{platformConf[platformName].name}</Select.Option> <Select.Option key={platformName} value={platformName}>{platformConf[platformName].name}</Select.Option>
@ -179,7 +216,7 @@ function AddModal(prop: AddModalProp) {
{required: hasTarget, message: "请输入账号"}, {required: hasTarget, message: "请输入账号"},
{validator: async (_, value) => { {validator: async (_, value) => {
try { try {
const res = await getTargetName(form.getFieldValue('platformType'), value); const res = await getTargetName(form.getFieldValue('platformName'), value);
if (res.targetName) { if (res.targetName) {
form.setFieldsValue({ form.setFieldsValue({
targetName: res.targetName targetName: res.targetName
@ -218,7 +255,7 @@ function AddModal(prop: AddModalProp) {
</Select> </Select>
</Form.Item> </Form.Item>
<Form.Item label="订阅Tag" name="tags"> <Form.Item label="订阅Tag" name="tags">
<InputTagCustom/> <InputTagCustom disabled={!enabledTag}/>
</Form.Item> </Form.Item>
</Form> </Form>
</Modal> </Modal>

View File

@ -18,7 +18,7 @@ export type LoginContextType = {
} }
export interface SubscribeConfig { export interface SubscribeConfig {
targetType: string platformName: string
target?: string target?: string
targetName: string targetName: string
cats: Array<number> cats: Array<number>

216
poetry.lock generated
View File

@ -1,3 +1,11 @@
[[package]]
name = "aiofiles"
version = "0.7.0"
description = "File support for asyncio."
category = "main"
optional = false
python-versions = ">=3.6,<4.0"
[[package]] [[package]]
name = "anyio" name = "anyio"
version = "3.3.4" version = "3.3.4"
@ -113,6 +121,14 @@ soupsieve = ">1.2"
html5lib = ["html5lib"] html5lib = ["html5lib"]
lxml = ["lxml"] lxml = ["lxml"]
[[package]]
name = "bidict"
version = "0.21.4"
description = "The bidirectional mapping library for Python."
category = "main"
optional = false
python-versions = ">=3.6"
[[package]] [[package]]
name = "bs4" name = "bs4"
version = "0.0.1" version = "0.0.1"
@ -181,6 +197,17 @@ category = "dev"
optional = false optional = false
python-versions = ">=3.5" python-versions = ">=3.5"
[[package]]
name = "expiringdict"
version = "1.2.1"
description = "Dictionary with auto-expiring values for caching purposes"
category = "main"
optional = false
python-versions = "*"
[package.extras]
tests = ["dill", "coverage", "coveralls", "mock", "nose"]
[[package]] [[package]]
name = "fastapi" name = "fastapi"
version = "0.68.2" version = "0.68.2"
@ -240,7 +267,7 @@ python-versions = ">=3.6.1"
[[package]] [[package]]
name = "httpcore" name = "httpcore"
version = "0.14.2" version = "0.14.3"
description = "A minimal low-level HTTP client." description = "A minimal low-level HTTP client."
category = "main" category = "main"
optional = false optional = false
@ -387,6 +414,20 @@ parso = ">=0.8.0,<0.9.0"
qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
[[package]]
name = "jinja2"
version = "3.0.3"
description = "A very fast and expressive template engine."
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
MarkupSafe = ">=2.0"
[package.extras]
i18n = ["Babel (>=2.7)"]
[[package]] [[package]]
name = "loguru" name = "loguru"
version = "0.5.3" version = "0.5.3"
@ -402,6 +443,14 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""}
[package.extras] [package.extras]
dev = ["codecov (>=2.0.15)", "colorama (>=0.3.4)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "tox-travis (>=0.12)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "Sphinx (>=2.2.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "black (>=19.10b0)", "isort (>=5.1.1)"] dev = ["codecov (>=2.0.15)", "colorama (>=0.3.4)", "flake8 (>=3.7.7)", "tox (>=3.9.0)", "tox-travis (>=0.12)", "pytest (>=4.6.2)", "pytest-cov (>=2.7.1)", "Sphinx (>=2.2.1)", "sphinx-autobuild (>=0.7.1)", "sphinx-rtd-theme (>=0.4.3)", "black (>=19.10b0)", "isort (>=5.1.1)"]
[[package]]
name = "markupsafe"
version = "2.0.1"
description = "Safely add untrusted strings to HTML/XML markup."
category = "main"
optional = false
python-versions = ">=3.6"
[[package]] [[package]]
name = "matplotlib-inline" name = "matplotlib-inline"
version = "0.1.3" version = "0.1.3"
@ -450,14 +499,14 @@ aiohttp = ["aiohttp[speedups] (>=3.7.4,<4.0.0)"]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "21.2" version = "21.3"
description = "Core utilities for Python packages" description = "Core utilities for Python packages"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
[package.dependencies] [package.dependencies]
pyparsing = ">=2.0.2,<3" pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]] [[package]]
name = "parso" name = "parso"
@ -577,13 +626,30 @@ category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "pyjwt"
version = "2.3.0"
description = "JSON Web Token implementation in Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
crypto = ["cryptography (>=3.3.1)"]
dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"]
docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"]
tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"]
[[package]] [[package]]
name = "pyparsing" name = "pyparsing"
version = "2.4.7" version = "3.0.6"
description = "Python parsing module" description = "Python parsing module"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" python-versions = ">=3.6"
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]] [[package]]
name = "pyppeteer" name = "pyppeteer"
@ -647,6 +713,34 @@ python-versions = ">=3.5"
[package.extras] [package.extras]
cli = ["click (>=5.0)"] cli = ["click (>=5.0)"]
[[package]]
name = "python-engineio"
version = "4.3.0"
description = "Engine.IO server and client for Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
asyncio_client = ["aiohttp (>=3.4)"]
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
[[package]]
name = "python-socketio"
version = "5.5.0"
description = "Socket.IO server and client for Python"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
bidict = ">=0.21.0"
python-engineio = ">=4.3.0"
[package.extras]
asyncio_client = ["aiohttp (>=3.4)"]
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
[[package]] [[package]]
name = "pytz" name = "pytz"
version = "2021.3" version = "2021.3"
@ -924,9 +1018,13 @@ testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytes
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "5e71b794d68042efbfb810bfd56d652cf5439fe02f6bb02ed31142ecb0e5adc7" content-hash = "77b95ff5c357cba44f6102ef29a07e59fa5b6a2abc814e6f97c41c9531f597ab"
[metadata.files] [metadata.files]
aiofiles = [
{file = "aiofiles-0.7.0-py3-none-any.whl", hash = "sha256:c67a6823b5f23fcab0a2595a289cec7d8c863ffcb4322fb8cd6b90400aedfdbc"},
{file = "aiofiles-0.7.0.tar.gz", hash = "sha256:a1c4fc9b2ff81568c83e21392a82f344ea9d23da906e4f6a52662764545e19d4"},
]
anyio = [ anyio = [
{file = "anyio-3.3.4-py3-none-any.whl", hash = "sha256:4fd09a25ab7fa01d34512b7249e366cd10358cdafc95022c7ff8c8f8a5026d66"}, {file = "anyio-3.3.4-py3-none-any.whl", hash = "sha256:4fd09a25ab7fa01d34512b7249e366cd10358cdafc95022c7ff8c8f8a5026d66"},
{file = "anyio-3.3.4.tar.gz", hash = "sha256:67da67b5b21f96b9d3d65daa6ea99f5d5282cb09f50eb4456f8fb51dffefc3ff"}, {file = "anyio-3.3.4.tar.gz", hash = "sha256:67da67b5b21f96b9d3d65daa6ea99f5d5282cb09f50eb4456f8fb51dffefc3ff"},
@ -963,6 +1061,10 @@ beautifulsoup4 = [
{file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"}, {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"},
{file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"}, {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"},
] ]
bidict = [
{file = "bidict-0.21.4-py3-none-any.whl", hash = "sha256:3ac67daa353ecf853a1df9d3e924f005e729227a60a8dbada31a4c31aba7f654"},
{file = "bidict-0.21.4.tar.gz", hash = "sha256:42c84ffbe6f8de898af6073b4be9ea7ccedcd78d3474aa844c54e49d5a079f6f"},
]
bs4 = [ bs4 = [
{file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"}, {file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"},
] ]
@ -1040,6 +1142,9 @@ decorator = [
{file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"}, {file = "decorator-5.1.0-py3-none-any.whl", hash = "sha256:7b12e7c3c6ab203a29e157335e9122cb03de9ab7264b137594103fd4a683b374"},
{file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"}, {file = "decorator-5.1.0.tar.gz", hash = "sha256:e59913af105b9860aa2c8d3272d9de5a56a4e608db9a2f167a8480b323d529a7"},
] ]
expiringdict = [
{file = "expiringdict-1.2.1.tar.gz", hash = "sha256:fe2ba427220425c3c8a3d29f6d2e2985bcee323f8bcd4021e68ebefbd90d8250"},
]
fastapi = [ fastapi = [
{file = "fastapi-0.68.2-py3-none-any.whl", hash = "sha256:36bcdd3dbea87c586061005e4a40b9bd0145afd766655b4e0ec1d8870b32555c"}, {file = "fastapi-0.68.2-py3-none-any.whl", hash = "sha256:36bcdd3dbea87c586061005e4a40b9bd0145afd766655b4e0ec1d8870b32555c"},
{file = "fastapi-0.68.2.tar.gz", hash = "sha256:38526fc46bda73f7ec92033952677323c16061e70a91d15c95f18b11895da494"}, {file = "fastapi-0.68.2.tar.gz", hash = "sha256:38526fc46bda73f7ec92033952677323c16061e70a91d15c95f18b11895da494"},
@ -1061,8 +1166,8 @@ hpack = [
{file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"}, {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
] ]
httpcore = [ httpcore = [
{file = "httpcore-0.14.2-py3-none-any.whl", hash = "sha256:47d7c8f755719d4a57be0b6e022897e9e963bf9ce4b15b9cc006a38a1cfa2932"}, {file = "httpcore-0.14.3-py3-none-any.whl", hash = "sha256:9a98d2416b78976fc5396ff1f6b26ae9885efbb3105d24eed490f20ab4c95ec1"},
{file = "httpcore-0.14.2.tar.gz", hash = "sha256:ff8f8b9434ec4823f95a30596fbe78039913e706d3e598b0b8955b1e1828e093"}, {file = "httpcore-0.14.3.tar.gz", hash = "sha256:d10162a63265a0228d5807964bd964478cbdb5178f9a2eedfebb2faba27eef5d"},
] ]
httptools = [ httptools = [
{file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"}, {file = "httptools-0.2.0-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5"},
@ -1112,10 +1217,85 @@ jedi = [
{file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
{file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
] ]
jinja2 = [
{file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"},
{file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"},
]
loguru = [ loguru = [
{file = "loguru-0.5.3-py3-none-any.whl", hash = "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c"}, {file = "loguru-0.5.3-py3-none-any.whl", hash = "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c"},
{file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"}, {file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"},
] ]
markupsafe = [
{file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"},
{file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"},
{file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"},
{file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"},
{file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"},
{file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"},
{file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"},
{file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"},
{file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"},
{file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"},
{file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"},
{file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"},
{file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"},
{file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"},
{file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"},
{file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"},
{file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"},
{file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"},
{file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"},
{file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"},
{file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"},
{file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"},
{file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"},
{file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"},
{file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"},
{file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"},
{file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"},
{file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"},
{file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"},
]
matplotlib-inline = [ matplotlib-inline = [
{file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
{file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
@ -1129,8 +1309,8 @@ nonebot2 = [
{file = "nonebot2-2.0.0a16.tar.gz", hash = "sha256:f70475e0a9525ed22cc082e35b06145b005412f919880a862e72059a84b0d2d0"}, {file = "nonebot2-2.0.0a16.tar.gz", hash = "sha256:f70475e0a9525ed22cc082e35b06145b005412f919880a862e72059a84b0d2d0"},
] ]
packaging = [ packaging = [
{file = "packaging-21.2-py3-none-any.whl", hash = "sha256:14317396d1e8cdb122989b916fa2c7e9ca8e2be9e8060a6eff75b6b7b4d8a7e0"}, {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.2.tar.gz", hash = "sha256:096d689d78ca690e4cd8a89568ba06d07ca097e3306a4381635073ca91479966"}, {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
] ]
parso = [ parso = [
{file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"},
@ -1238,9 +1418,13 @@ pygments = [
pygtrie = [ pygtrie = [
{file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"}, {file = "pygtrie-2.4.2.tar.gz", hash = "sha256:43205559d28863358dbbf25045029f58e2ab357317a59b11f11ade278ac64692"},
] ]
pyjwt = [
{file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"},
{file = "PyJWT-2.3.0.tar.gz", hash = "sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41"},
]
pyparsing = [ pyparsing = [
{file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
] ]
pyppeteer = [ pyppeteer = [
{file = "pyppeteer-0.2.6-py3-none-any.whl", hash = "sha256:85adde940cc96820725db59cbdb13384aefd0dd043858cfa4f1c086c0f9e4137"}, {file = "pyppeteer-0.2.6-py3-none-any.whl", hash = "sha256:85adde940cc96820725db59cbdb13384aefd0dd043858cfa4f1c086c0f9e4137"},
@ -1258,6 +1442,14 @@ python-dotenv = [
{file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"},
{file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"},
] ]
python-engineio = [
{file = "python-engineio-4.3.0.tar.gz", hash = "sha256:fed35eeacfa21f53f1fc05ef0cadd65a50780364da3a2be7650eb92f928fdb11"},
{file = "python_engineio-4.3.0-py3-none-any.whl", hash = "sha256:ad06a975f7e14cb3bb7137cbf70fd883804484d29acd58004d1db1e2a7fc0ad3"},
]
python-socketio = [
{file = "python-socketio-5.5.0.tar.gz", hash = "sha256:ce972ea1b82aa1811fa10d30cf0d5c251b9a1558c3d66829b6fe70854bcccf0b"},
{file = "python_socketio-5.5.0-py3-none-any.whl", hash = "sha256:ca28a0ff0ca5dd05ec5ba4ee2572fe06b96d6f0bc7df384d8b50fbbc06986134"},
]
pytz = [ pytz = [
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},

View File

@ -1,7 +1,5 @@
from dataclasses import dataclass from dataclasses import dataclass
import importlib
from pathlib import Path from pathlib import Path
from typing import Callable
from fastapi.staticfiles import StaticFiles from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates from fastapi.templating import Jinja2Templates
@ -18,7 +16,7 @@ import functools
from starlette.requests import Request from starlette.requests import Request
from .api import test, get_global_conf, auth, get_subs_info, get_target_name, add_group_sub from .api import del_group_sub, test, get_global_conf, auth, get_subs_info, get_target_name, add_group_sub
from .token_manager import token_manager as tm from .token_manager import token_manager as tm
from .jwt import load_jwt from .jwt import load_jwt
from ..plugin_config import plugin_config from ..plugin_config import plugin_config
@ -49,8 +47,10 @@ def register_router_fastapi(driver: Driver, socketio):
async def check_group_permission(groupNumber: str, token_obj: dict = Depends(get_jwt_obj)): async def check_group_permission(groupNumber: str, token_obj: dict = Depends(get_jwt_obj)):
groups = token_obj['groups'] groups = token_obj['groups']
if groupNumber not in groups: for group in groups:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN) if int(groupNumber) == group['id']:
return
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
@dataclass @dataclass
class AddSubscribeReq: class AddSubscribeReq:
@ -76,6 +76,9 @@ def register_router_fastapi(driver: Driver, socketio):
async def _add_group_subs(groupNumber: str, req: AddSubscribeReq): async def _add_group_subs(groupNumber: str, req: AddSubscribeReq):
return await add_group_sub(group_number=groupNumber, platform_name=req.platformName, return await add_group_sub(group_number=groupNumber, platform_name=req.platformName,
target=req.target, target_name=req.targetName, cats=req.categories, tags=req.tags) target=req.target, target_name=req.targetName, cats=req.categories, tags=req.tags)
@app.delete(SUBSCRIBE_URL, dependencies=[Depends(check_group_permission)])
async def _del_group_subs(groupNumber: str, target: str, platformName: str):
return await del_group_sub(groupNumber, platformName, target)
app.mount(URL_BASE, StaticFiles(directory=static_path, html=True), name="bison") app.mount(URL_BASE, StaticFiles(directory=static_path, html=True), name="bison")
templates = Jinja2Templates(directory=static_path) templates = Jinja2Templates(directory=static_path)

View File

@ -1,7 +1,7 @@
from ..platform import platform_manager, check_sub_target from ..platform import platform_manager, check_sub_target
from .token_manager import token_manager from .token_manager import token_manager
from .jwt import pack_jwt from .jwt import pack_jwt
from ..config import Config from ..config import Config, NoSuchSubscribeException, NoSuchUserException
import nonebot import nonebot
from nonebot.adapters.cqhttp.bot import Bot from nonebot.adapters.cqhttp.bot import Bot
@ -53,7 +53,7 @@ async def get_subs_info(jwt_obj: dict):
group_id = group['id'] group_id = group['id']
config = Config() config = Config()
subs = list(map(lambda sub: { subs = list(map(lambda sub: {
'targetType': sub['target_type'], 'target': sub['target'], 'targetName': sub['target_name'], 'cats': sub['cats'], 'tags': sub['tags'] 'platformName': sub['target_type'], 'target': sub['target'], 'targetName': sub['target_name'], 'cats': sub['cats'], 'tags': sub['tags']
}, config.list_subscribe(group_id, 'group'))) }, config.list_subscribe(group_id, 'group')))
res[group_id] = { res[group_id] = {
'name': group['name'], 'name': group['name'],
@ -67,6 +67,13 @@ async def get_target_name(platform_name: str, target: str, jwt_obj: dict):
async def add_group_sub(group_number: str, platform_name: str, target: str, async def add_group_sub(group_number: str, platform_name: str, target: str,
target_name: str, cats: list[str], tags: list[str]): target_name: str, cats: list[str], tags: list[str]):
config = Config() config = Config()
config.add_subscribe(group_number, 'group', target, target_name, platform_name, cats, tags) config.add_subscribe(int(group_number), 'group', target, target_name, platform_name, cats, tags)
return { 'status': 200, 'msg': '' } return { 'status': 200, 'msg': '' }
async def del_group_sub(group_number: str, platform_name: str, target: str):
config = Config()
try:
config.del_subscribe(int(group_number), 'group', target, platform_name)
except (NoSuchUserException, NoSuchSubscribeException):
return { 'status': 400, 'msg': '删除错误' }
return { 'status': 200, 'msg': '' }