mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-04 02:26:11 +08:00
update
This commit is contained in:
parent
cdeea09522
commit
5d9872af29
@ -15,6 +15,7 @@
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"antd": "^4.16.13",
|
||||
"axios": "^0.21.4",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-router-dom": "^5.3.0",
|
||||
@ -24,7 +25,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build && mv build ../src/plugins/nonebot_hk_reporter/admin_page/dist",
|
||||
"build": "react-scripts build && mv -f build ../src/plugins/nonebot_hk_reporter/admin_page/dist",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
@ -47,6 +48,7 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash": "^4.14.175",
|
||||
"@types/react-router-dom": "^5.3.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { HashRouter as Router, Route, Switch } from 'react-router-dom';
|
||||
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
|
||||
import './App.css';
|
||||
import { LoginContext, loginContextDefault, GlobalConfContext } from './utils/context';
|
||||
import { LoginStatus, GlobalConf, AllPlatformConf } from './utils/type';
|
||||
@ -41,7 +41,7 @@ function App() {
|
||||
<LoginContext.Provider value={{login: loginStatus, save}}>
|
||||
<GlobalConfContext.Provider value={globalConf}>
|
||||
{ globalConf.loaded &&
|
||||
<Router>
|
||||
<Router basename="/hk_reporter">
|
||||
<Switch>
|
||||
<Route path="/auth/:code">
|
||||
<Auth />
|
||||
|
@ -1,5 +1,5 @@
|
||||
import axios from "axios";
|
||||
import { GlobalConf, TokenResp, SubscribeResp, TargetNameResp } from "../utils/type";
|
||||
import { GlobalConf, TokenResp, SubscribeResp, TargetNameResp, CreateSubscribeReq } from "../utils/type";
|
||||
import { baseUrl } from './utils';
|
||||
|
||||
export async function getGlobalConf(): Promise<GlobalConf> {
|
||||
@ -21,3 +21,8 @@ export async function getTargetName(platformName: string, target: string): Promi
|
||||
const res = await axios.get(`${baseUrl}target_name`, {params: {platformName, target}});
|
||||
return res.data;
|
||||
}
|
||||
|
||||
export async function addSubscribe(groupNumber: string, req: CreateSubscribeReq) {
|
||||
const res = await axios.post(`${baseUrl}subs`, req, {params: {groupNumber}})
|
||||
return res.data;
|
||||
}
|
||||
|
117
admin-frontend/src/component/inputTag.tsx
Normal file
117
admin-frontend/src/component/inputTag.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import {Input, Tag, Tooltip} from "antd";
|
||||
import {PresetColorType, PresetStatusColorType} from 'antd/lib/_util/colors'
|
||||
import {LiteralUnion} from 'antd/lib/_util/type'
|
||||
import React, {useRef, useState, useEffect} from "react";
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
|
||||
interface InputTagProp {
|
||||
value?: Array<string>,
|
||||
onChange?: (value: Array<string>) => void
|
||||
color?: LiteralUnion<PresetColorType | PresetStatusColorType, string>;
|
||||
addText?: string
|
||||
}
|
||||
export function InputTag(prop: InputTagProp) {
|
||||
const [ value, setValue ] = useState<Array<string>>(prop.value || []);
|
||||
const [ inputVisible, setInputVisible ] = useState(false);
|
||||
const [ inputValue, setInputValue ] = useState('');
|
||||
const [ editInputIndex, setEditInputIndex ] = useState(-1);
|
||||
const [ editInputValue, setEditInputValue ] = useState('');
|
||||
const inputRef = useRef(null as any);
|
||||
const editInputRef = useRef(null as any);
|
||||
useEffect(() => {
|
||||
if (inputVisible) {
|
||||
inputRef.current.focus()
|
||||
}
|
||||
}, [inputVisible]);
|
||||
useEffect(() => {
|
||||
if (editInputIndex !== -1) {
|
||||
editInputRef.current.focus();
|
||||
}
|
||||
}, [editInputIndex]);
|
||||
|
||||
const handleClose = (removedTag: string) => {
|
||||
const tags = value.filter(tag => tag !== removedTag);
|
||||
setValue(_ => tags);
|
||||
if (prop.onChange) {
|
||||
prop.onChange(tags);
|
||||
}
|
||||
}
|
||||
|
||||
const showInput = () => {
|
||||
setInputVisible(_ => true);
|
||||
}
|
||||
|
||||
const handleInputConfirm = () => {
|
||||
if (inputValue && value.indexOf(inputValue) === -1) {
|
||||
const newVal = [...value, inputValue];
|
||||
setValue(_ => newVal);
|
||||
if (prop.onChange) {
|
||||
prop.onChange(newVal);
|
||||
}
|
||||
}
|
||||
setInputVisible(_ => false);
|
||||
setInputValue(_ => '');
|
||||
}
|
||||
|
||||
const handleEditInputChange = (e: any) => {
|
||||
setEditInputValue(_ => e.target.value);
|
||||
}
|
||||
|
||||
const handleEditInputConfirm = () => {
|
||||
const newTags = value.slice();
|
||||
newTags[editInputIndex] = editInputValue;
|
||||
setValue(_ => newTags);
|
||||
if (prop.onChange) {
|
||||
prop.onChange(newTags);
|
||||
}
|
||||
setEditInputIndex(_ => -1);
|
||||
setEditInputValue(_ => '');
|
||||
}
|
||||
|
||||
const handleInputChange = (e: any) => {
|
||||
setInputValue(e.target.value);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{ value.map((tag, index) => {
|
||||
if (editInputIndex === index) {
|
||||
return (
|
||||
<Input ref={editInputRef} key={tag} size="small"
|
||||
value={editInputValue} onChange={handleEditInputChange}
|
||||
onBlur={handleEditInputConfirm} onPressEnter={handleInputConfirm} />
|
||||
);
|
||||
}
|
||||
const isLongTag = tag.length > 20;
|
||||
const tagElem = (
|
||||
<Tag color={prop.color || "default"} style={{userSelect: 'none'}} key={tag} closable onClose={() => handleClose(tag)}>
|
||||
<span onDoubleClick={e => {
|
||||
setEditInputIndex(_ => index);
|
||||
setEditInputValue(_ => tag);
|
||||
e.preventDefault();
|
||||
}}>
|
||||
{isLongTag ? `${tag.slice(0, 20)}...` : tag}
|
||||
</span>
|
||||
</Tag>
|
||||
);
|
||||
return isLongTag ? (
|
||||
<Tooltip title={tag} key={tag}>
|
||||
{tagElem}
|
||||
</Tooltip>
|
||||
) : ( tagElem );
|
||||
})}
|
||||
{inputVisible && (
|
||||
<Input ref={inputRef} type="text" size="small"
|
||||
style={{width: '78px', marginRight: '8px', verticalAlign: 'top'}} value={inputValue}
|
||||
onChange={handleInputChange} onBlur={handleInputConfirm}
|
||||
onPressEnter={handleInputConfirm} />
|
||||
)}
|
||||
{!inputVisible && (
|
||||
<Tag className="site-tag-plus" onClick={showInput} style={{background: '#fff', border: 'dashed'}}>
|
||||
<PlusOutlined/> {prop.addText || "Add Tag"}
|
||||
</Tag>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
}
|
@ -2,9 +2,11 @@ import React, { ReactElement, useContext, useEffect, useState } from "react";
|
||||
import { LoginContext, GlobalConfContext } from "../utils/context";
|
||||
import { Layout, Menu, Empty, Collapse, Card, Tag, Row, Col, Form, Tooltip, Button, Modal, Select,
|
||||
Input} from 'antd';
|
||||
import { SubscribeConfig, SubscribeResp, PlatformConfig } from '../utils/type';
|
||||
import { SubscribeConfig, SubscribeResp, PlatformConfig, CategoryConfig } from '../utils/type';
|
||||
import { SettingOutlined, BugOutlined, DeleteOutlined, CopyOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { getSubscribe, getTargetName } from '../api/config';
|
||||
import { InputTag } from '../component/inputTag';
|
||||
import _ from "lodash";
|
||||
import './admin.css';
|
||||
|
||||
export function Admin() {
|
||||
@ -63,7 +65,7 @@ function ConfigPage(prop: ConfigPageProp) {
|
||||
<Tooltip title="删除"><DeleteOutlined /></Tooltip>,
|
||||
<Tooltip title="添加到其他群"><CopyOutlined /></Tooltip>
|
||||
]}>
|
||||
<Form labelCol={{ span: 4 }}>
|
||||
<Form labelCol={{ span: 6 }}>
|
||||
<Form.Item label="订阅类型">
|
||||
{Object.keys(platformConf.categories).length > 0 ?
|
||||
config.cats.map((catKey: number) => (<Tag color="green" key={catKey}>{platformConf.categories[catKey]}</Tag>)) :
|
||||
@ -103,6 +105,28 @@ function ConfigPage(prop: ConfigPageProp) {
|
||||
}
|
||||
}
|
||||
|
||||
interface InputTagCustomProp {
|
||||
value?: Array<string>,
|
||||
onChange?: (value: Array<string>) => void
|
||||
}
|
||||
function InputTagCustom(prop: InputTagCustomProp) {
|
||||
const [value, setValue] = useState(prop.value || []);
|
||||
const handleSetValue = (newVal: Array<string>) => {
|
||||
setValue(() => newVal);
|
||||
if (prop.onChange) {
|
||||
prop.onChange(newVal);
|
||||
}
|
||||
}
|
||||
return (
|
||||
<>
|
||||
{value.length === 0 &&
|
||||
<Tag color="green">全部标签</Tag>
|
||||
}
|
||||
<InputTag color="blue" addText="添加标签" value={value} onChange={handleSetValue} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
interface AddModalProp {
|
||||
showModal: boolean,
|
||||
setShowModal: (s: boolean) => void
|
||||
@ -111,26 +135,39 @@ function AddModal(prop: AddModalProp) {
|
||||
const [ confirmLoading, setConfirmLoading ] = useState<boolean>(false);
|
||||
const { platformConf } = useContext(GlobalConfContext);
|
||||
const [ hasTarget, setHasTarget ] = useState(false);
|
||||
const [ categories, setCategories ] = useState({} as CategoryConfig);
|
||||
const [ form ] = Form.useForm();
|
||||
const changePlatformSelect = (platform: string) => {
|
||||
setHasTarget(_ => platformConf[platform].hasTarget);
|
||||
setCategories(_ => platformConf[platform].categories);
|
||||
if (! platformConf[platform].hasTarget) {
|
||||
getTargetName(platform, 'default')
|
||||
.then(res => {
|
||||
console.log(res)
|
||||
form.setFieldsValue(() => { return {
|
||||
targetName: res.targetName
|
||||
}})
|
||||
form.setFieldsValue({
|
||||
targetName: res.targetName,
|
||||
target: ''
|
||||
})
|
||||
})
|
||||
} else {
|
||||
form.setFieldsValue({
|
||||
targetName: '',
|
||||
target: ''
|
||||
})
|
||||
}
|
||||
}
|
||||
const handleSubmit = (value: any) => {
|
||||
console.log(value);
|
||||
}
|
||||
const handleModleFinish = () => {
|
||||
form.submit();
|
||||
setConfirmLoading(() => true);
|
||||
}
|
||||
|
||||
return <Modal title="添加订阅" visible={prop.showModal}
|
||||
confirmLoading={confirmLoading} onCancel={() => prop.setShowModal(false)}>
|
||||
<Form form={form} labelCol={{ span: 6 }} name="b">
|
||||
confirmLoading={confirmLoading} onCancel={() => prop.setShowModal(false)}
|
||||
onOk={handleModleFinish}>
|
||||
<Form form={form} labelCol={{ span: 6 }} name="b" onFinish={handleSubmit}>
|
||||
<Form.Item label="平台" name="platformType" rules={[]}>
|
||||
<Select style={{ width: '80%' }} onChange={changePlatformSelect}>
|
||||
{Object.keys(platformConf).map(platformName =>
|
||||
@ -138,11 +175,50 @@ function AddModal(prop: AddModalProp) {
|
||||
)}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item label="账号" name="target" rules={[]}>
|
||||
<Input placeholder={hasTarget ? "获取方式见文档" : "此平台不需要账号"} disabled={! hasTarget} style={{ width: "80%" }} />
|
||||
<Form.Item label="账号" name="target" rules={[
|
||||
{required: hasTarget, message: "请输入账号"},
|
||||
{validator: async (_, value) => {
|
||||
try {
|
||||
const res = await getTargetName(form.getFieldValue('platformType'), value);
|
||||
if (res.targetName) {
|
||||
form.setFieldsValue({
|
||||
targetName: res.targetName
|
||||
})
|
||||
return Promise.resolve()
|
||||
} else {
|
||||
form.setFieldsValue({
|
||||
targetName: ''
|
||||
})
|
||||
return Promise.reject("账号不正确,请重新检查账号")
|
||||
}
|
||||
} catch {
|
||||
return Promise.reject('服务器错误,请稍后再试')
|
||||
}
|
||||
}
|
||||
}
|
||||
]}>
|
||||
<Input placeholder={hasTarget ? "获取方式见文档" : "此平台不需要账号"}
|
||||
disabled={! hasTarget} style={{ width: "80%" }}/>
|
||||
</Form.Item>
|
||||
<Form.Item label="账号名称" name="targetName">
|
||||
<Input style={{ width: "80%" }} />
|
||||
<Input style={{ width: "80%" }} disabled />
|
||||
</Form.Item>
|
||||
<Form.Item label="订阅分类" name="categories">
|
||||
<Select style={{ width: '80%' }} mode="multiple"
|
||||
disabled={Object.keys(categories).length === 0}
|
||||
placeholder={Object.keys(categories).length > 0 ?
|
||||
"请选择要订阅的分类" : "本平台不支持分类"}>
|
||||
{Object.keys(categories).length > 0 &&
|
||||
Object.keys(categories).map((indexStr) =>
|
||||
<Select.Option key={indexStr} value={parseInt(indexStr)}>
|
||||
{categories[parseInt(indexStr)]}
|
||||
</Select.Option>
|
||||
)
|
||||
}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
<Form.Item label="订阅Tag" name="tags">
|
||||
<InputTagCustom/>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
|
@ -34,7 +34,7 @@ export interface AllPlatformConf {
|
||||
[idx: string]: PlatformConfig;
|
||||
}
|
||||
|
||||
interface CategoryConfig {
|
||||
export interface CategoryConfig {
|
||||
[idx: number]: string
|
||||
}
|
||||
|
||||
@ -66,3 +66,11 @@ export interface SubscribeResp {
|
||||
export interface TargetNameResp {
|
||||
targetName: string
|
||||
}
|
||||
|
||||
export interface CreateSubscribeReq {
|
||||
platformName: string,
|
||||
targetName: string,
|
||||
target: string,
|
||||
categories: Array<string>,
|
||||
tags: Array<string>
|
||||
}
|
||||
|
@ -1899,6 +1899,11 @@
|
||||
resolved "https://registry.npm.taobao.org/@types/json5/download/@types/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
|
||||
integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4=
|
||||
|
||||
"@types/lodash@^4.14.175":
|
||||
version "4.14.175"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash/download/@types/lodash-4.14.175.tgz#b78dfa959192b01fae0ad90e166478769b215f45"
|
||||
integrity sha1-t436lZGSsB+uCtkOFmR4dpshX0U=
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.nlark.com/@types/minimatch/download/@types/minimatch-3.0.5.tgz?cache=0&sync_timestamp=1629708375365&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fminimatch%2Fdownload%2F%40types%2Fminimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
|
||||
|
78
poetry.lock
generated
78
poetry.lock
generated
@ -565,6 +565,25 @@ type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "aliyun"
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "3.0.1"
|
||||
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.source]
|
||||
type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "aliyun"
|
||||
|
||||
[[package]]
|
||||
name = "loguru"
|
||||
version = "0.5.3"
|
||||
@ -585,6 +604,19 @@ type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "aliyun"
|
||||
|
||||
[[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.source]
|
||||
type = "legacy"
|
||||
url = "https://mirrors.aliyun.com/pypi/simple"
|
||||
reference = "aliyun"
|
||||
|
||||
[[package]]
|
||||
name = "matplotlib-inline"
|
||||
version = "0.1.2"
|
||||
@ -1365,7 +1397,7 @@ reference = "aliyun"
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.9"
|
||||
content-hash = "2094fead0b3c31a3d27536045ff4bdf6e26ab874ec9f79a6460db14f90bf8140"
|
||||
content-hash = "f953dbdde807df6c88dcd1cb962dcaff43dda3d45f5f4e27ef76e3bec3786d8b"
|
||||
|
||||
[metadata.files]
|
||||
aiofiles = [
|
||||
@ -1414,7 +1446,7 @@ bidict = [
|
||||
{file = "bidict-0.21.3.tar.gz", hash = "sha256:d50bd81fae75e34198ffc94979a0eb0939ff9adb3ef32bcc93a913d8b3e3ed1d"},
|
||||
]
|
||||
bs4 = [
|
||||
{file = "bs4-0.0.1.tar.gz", hash = "sha256:36ecea1fd7cc5c0c6e4a1ff075df26d50da647b75376626cc186e2212886dd3a"},
|
||||
{file = "bs4-0.0.1.tar.gz", hash = "md5:fe7e51587ac3b174608f3c4f8bd893ac"},
|
||||
]
|
||||
certifi = [
|
||||
{file = "certifi-2021.5.30-py2.py3-none-any.whl", hash = "sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8"},
|
||||
@ -1561,10 +1593,50 @@ jedi = [
|
||||
{file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"},
|
||||
{file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"},
|
||||
]
|
||||
jinja2 = [
|
||||
{file = "Jinja2-3.0.1-py3-none-any.whl", hash = "sha256:1f06f2da51e7b56b8f238affdd6b4e2c61e39598a378cc49345bc1bd42a978a4"},
|
||||
{file = "Jinja2-3.0.1.tar.gz", hash = "sha256:703f484b47a6af502e743c9122595cc812b0271f661722403114f71a79d0f5a4"},
|
||||
]
|
||||
loguru = [
|
||||
{file = "loguru-0.5.3-py3-none-any.whl", hash = "sha256:f8087ac396b5ee5f67c963b495d615ebbceac2796379599820e324419d53667c"},
|
||||
{file = "loguru-0.5.3.tar.gz", hash = "sha256:b28e72ac7a98be3d28ad28570299a393dfcd32e5e3f6a353dec94675767b6319"},
|
||||
]
|
||||
markupsafe = [
|
||||
{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-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-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_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-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-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 = [
|
||||
{file = "matplotlib-inline-0.1.2.tar.gz", hash = "sha256:f41d5ff73c9f5385775d5c0bc13b424535c8402fe70ea8210f93e11f3683993e"},
|
||||
{file = "matplotlib_inline-0.1.2-py3-none-any.whl", hash = "sha256:5cf1176f554abb4fa98cb362aa2b55c500147e4bdbb07e3fda359143e1da0811"},
|
||||
@ -1775,7 +1847,7 @@ rfc3986 = [
|
||||
{file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"},
|
||||
]
|
||||
sgmllib3k = [
|
||||
{file = "sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"},
|
||||
{file = "sgmllib3k-1.0.0.tar.gz", hash = "md5:d70efde06e40797f37e867123aa080ec"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
|
||||
|
@ -33,6 +33,7 @@ expiringdict = "^1.2.1"
|
||||
pyjwt = "^2.1.0"
|
||||
aiofiles = "^0.7.0"
|
||||
python-socketio = "^5.4.0"
|
||||
jinja2 = "^3.0.1"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
ipdb = "^0.13.4"
|
||||
|
@ -1,8 +1,10 @@
|
||||
from dataclasses import dataclass
|
||||
import importlib
|
||||
from pathlib import Path
|
||||
from typing import Callable
|
||||
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from nonebot import get_driver, on_command
|
||||
import nonebot
|
||||
from nonebot.adapters.cqhttp.bot import Bot
|
||||
@ -14,7 +16,9 @@ from nonebot.typing import T_State
|
||||
import socketio
|
||||
import functools
|
||||
|
||||
from .api import test, get_global_conf, auth, get_subs_info, get_target_name
|
||||
from starlette.requests import Request
|
||||
|
||||
from .api import test, get_global_conf, auth, get_subs_info, get_target_name, add_group_sub
|
||||
from .token_manager import token_manager as tm
|
||||
from .jwt import load_jwt
|
||||
from ..plugin_config import plugin_config
|
||||
@ -43,6 +47,19 @@ def register_router_fastapi(driver: Driver, socketio):
|
||||
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
|
||||
return obj
|
||||
|
||||
async def check_group_permission(groupNumber: str, token_obj: dict = Depends(get_jwt_obj)):
|
||||
groups = token_obj['groups']
|
||||
if groupNumber not in groups:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
@dataclass
|
||||
class AddSubscribeReq:
|
||||
platformName: str
|
||||
target: str
|
||||
targetName: str
|
||||
categories: list[str]
|
||||
tags: list[str]
|
||||
|
||||
app = driver.server_app
|
||||
static_path = str((Path(__file__).parent / "dist").resolve())
|
||||
app.get(TEST_URL)(test)
|
||||
@ -55,7 +72,17 @@ def register_router_fastapi(driver: Driver, socketio):
|
||||
@app.get(GET_TARGET_NAME_URL)
|
||||
async def _get_target_name(platformName: str, target: str, jwt_obj: dict = Depends(get_jwt_obj)):
|
||||
return await get_target_name(platformName, target, jwt_obj)
|
||||
@app.post(SUBSCRIBE_URL, dependencies=[Depends(check_group_permission)])
|
||||
async def _add_group_subs(groupNumber: str, req: AddSubscribeReq):
|
||||
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)
|
||||
app.mount(URL_BASE, StaticFiles(directory=static_path, html=True), name="hk_reporter")
|
||||
templates = Jinja2Templates(directory=static_path)
|
||||
|
||||
@app.get(f'{URL_BASE}{{rest_path:path}}')
|
||||
async def serve_sap(request: Request, rest_path: str):
|
||||
return templates.TemplateResponse("index.html", {"request": request})
|
||||
|
||||
|
||||
def init():
|
||||
driver = get_driver()
|
||||
|
@ -63,3 +63,10 @@ async def get_subs_info(jwt_obj: dict):
|
||||
|
||||
async def get_target_name(platform_name: str, target: str, jwt_obj: dict):
|
||||
return {'targetName': await check_sub_target(platform_name, target)}
|
||||
|
||||
async def add_group_sub(group_number: str, platform_name: str, target: str,
|
||||
target_name: str, cats: list[str], tags: list[str]):
|
||||
config = Config()
|
||||
config.add_subscribe(group_number, 'group', target, target_name, platform_name, cats, tags)
|
||||
return { 'status': 200, 'msg': '' }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user