From 1ad87e666ff98bd76056578e6c80f13f55152df1 Mon Sep 17 00:00:00 2001
From: ictye
Date: Tue, 20 Aug 2024 02:45:39 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A7=84=E8=8C=83=E6=8F=92=E4=BB=B6?=
=?UTF-8?q?=E8=A1=8C=E4=B8=BA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 14 ++----
.../src/ictye_live_dm/GUI/Ui_MainWindow.py | 48 ++++++++++---------
ictye-live-dm/src/ictye_live_dm/GUI_main.py | 13 +++--
.../src/ictye_live_dm/QT-GUI/main.ui | 24 +++++++---
.../ictye_live_dm/depends/config_registrar.py | 9 ++--
.../src/ictye_live_dm/depends/pluginmain.py | 35 ++++++++++++--
.../src/ictye_live_dm/http_server.py | 3 +-
.../src/ictye_live_dm/pluginsystem.py | 12 ++++-
ictye-live-dm/tests/Config_schema_test.py | 2 +-
9 files changed, 105 insertions(+), 55 deletions(-)
diff --git a/README.md b/README.md
index bd85772..780d11a 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,8 @@
-

-
+
Ictye Live Danmku(ictye-live-dm)
-

-
-

-
+

+
一个简单而又全能的弹幕姬框架(其实就是一个web服务器加上websocket服务器),通过插件来实现弹幕功能
@@ -16,7 +13,6 @@
3. 如果是Windows用户则可以直接运行其中的启动脚本,Linux和mac用户可以根据requirements.txt配置环境后运行,建议是运行在venv环境中。
## 开始使用它
-
1. 部署ictye live Danmku:你只需要简单的解压它就好,默认情况的启动脚本是为Windows用户提供的,不过在非Windows操作系统上,你仍旧可以使用`requirement.txt`来配置环境并且使用`python -m ictye-live-dm`来启动项目
2. 配置项目:
1. 这个软件是通过插件的形式来实现弹幕的获取,弹幕的分析和处理
@@ -24,7 +20,3 @@
3. `/web/`里都是前端的资源,其中`/web/api`和`/web/cgi`是一个占位用的文件夹(方便开发。。。。。。。。。),`/web/js/`中是存放的前端的脚本,此外,你可以编辑style内的文件来定义你自己的样式
这个项目目前完全是我一个人开发(属实有点离谱),如果有想参加开发的可以联系我。。。。。。
-
-剩余的工作:
-- 找bug和打补丁。。。。。。。。。
-- 稳定性校验
\ No newline at end of file
diff --git a/ictye-live-dm/src/ictye_live_dm/GUI/Ui_MainWindow.py b/ictye-live-dm/src/ictye_live_dm/GUI/Ui_MainWindow.py
index 1e86467..6c6a1d6 100644
--- a/ictye-live-dm/src/ictye_live_dm/GUI/Ui_MainWindow.py
+++ b/ictye-live-dm/src/ictye_live_dm/GUI/Ui_MainWindow.py
@@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
-
-# Form implementation generated from reading ui file './main.ui'
+# Form implementation generated from reading ui file '.\main.ui'
#
-# Created by: PyQt5 UI code generator 5.15.11
+# Created by: PyQt5 UI code generator 5.15.10
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@@ -25,10 +24,10 @@ def setupUi(self, Form):
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
- self.label = QtWidgets.QLabel(Form)
- self.label.setMinimumSize(QtCore.QSize(223, 28))
- self.label.setObjectName("label")
- self.horizontalLayout.addWidget(self.label)
+ self.shangdiyagou = QtWidgets.QLabel(Form)
+ self.shangdiyagou.setMinimumSize(QtCore.QSize(223, 28))
+ self.shangdiyagou.setObjectName("shangdiyagou")
+ self.horizontalLayout.addWidget(self.shangdiyagou)
self.startButtoen = QtWidgets.QPushButton(Form)
self.startButtoen.setMaximumSize(QtCore.QSize(317, 28))
self.startButtoen.setObjectName("startButtoen")
@@ -72,19 +71,19 @@ def setupUi(self, Form):
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_7.addItem(spacerItem1)
self.verticalLayout_6.addLayout(self.horizontalLayout_7)
- self.adress_content_list = QtWidgets.QListWidget(self.tab_2)
- self.adress_content_list.setObjectName("adress_content_list")
- self.verticalLayout_6.addWidget(self.adress_content_list)
+ self.treeWidget = QtWidgets.QTreeWidget(self.tab_2)
+ self.treeWidget.setObjectName("treeWidget")
+ self.verticalLayout_6.addWidget(self.treeWidget)
self.horizontalLayout_8 = QtWidgets.QHBoxLayout()
self.horizontalLayout_8.setObjectName("horizontalLayout_8")
- self.label_5 = QtWidgets.QLabel(self.tab_2)
- self.label_5.setObjectName("label_5")
- self.horizontalLayout_8.addWidget(self.label_5)
+ self.location = QtWidgets.QLabel(self.tab_2)
+ self.location.setObjectName("location")
+ self.horizontalLayout_8.addWidget(self.location)
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_8.addItem(spacerItem2)
- self.pushButton_4 = QtWidgets.QPushButton(self.tab_2)
- self.pushButton_4.setObjectName("pushButton_4")
- self.horizontalLayout_8.addWidget(self.pushButton_4)
+ self.openInBlsower = QtWidgets.QPushButton(self.tab_2)
+ self.openInBlsower.setObjectName("openInBlsower")
+ self.horizontalLayout_8.addWidget(self.openInBlsower)
self.verticalLayout_6.addLayout(self.horizontalLayout_8)
self.tabWidget.addTab(self.tab_2, "")
self.log_Tab = QtWidgets.QWidget()
@@ -144,7 +143,7 @@ def setupUi(self, Form):
self.pluginListTable.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.pluginListTable.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.pluginListTable.setObjectName("pluginListTable")
- self.pluginListTable.setColumnCount(4)
+ self.pluginListTable.setColumnCount(5)
self.pluginListTable.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.pluginListTable.setHorizontalHeaderItem(0, item)
@@ -154,6 +153,8 @@ def setupUi(self, Form):
self.pluginListTable.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.pluginListTable.setHorizontalHeaderItem(3, item)
+ item = QtWidgets.QTableWidgetItem()
+ self.pluginListTable.setHorizontalHeaderItem(4, item)
self.pluginListTable.horizontalHeader().setCascadingSectionResizes(False)
self.pluginListTable.horizontalHeader().setSortIndicatorShown(False)
self.pluginListTable.horizontalHeader().setStretchLastSection(True)
@@ -290,22 +291,23 @@ def setupUi(self, Form):
self.verticalLayout_3.addWidget(self.settingScrollArea)
self.tabWidget.addTab(self.setting_Tab, "")
self.verticalLayout.addWidget(self.tabWidget)
+
self.retranslateUi(Form)
- self.tabWidget.setCurrentIndex(3)
+ self.tabWidget.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Ictye Live Danmmku"))
- self.label.setText(_translate("Form", "本項目由美國聖地亞哥(American Sangdiyagou)獨家贊助研發(x)"))
+ self.shangdiyagou.setText(_translate("Form", "本項目由美國聖地亞哥(American Sangdiyagou)獨家贊助研發(x)"))
self.startButtoen.setText(_translate("Form", "Start"))
self.stopButton.setText(_translate("Form", "Stop"))
self.label_2.setText(_translate("Form", "Home
"))
self.StatusLable.setText(_translate("Form", "Status:"))
self.status_display_lable.setText(_translate("Form", "%1"))
self.label_3.setText(_translate("Form", "Address Contents
"))
- self.label_5.setText(_translate("Form", "
Location http://127.0.0.1:8082
"))
- self.pushButton_4.setText(_translate("Form", "open in blsower"))
+ self.location.setText(_translate("Form", "Location http://127.0.0.1:8082
"))
+ self.openInBlsower.setText(_translate("Form", "open in blsower"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("Form", "Hone"))
self.totalLogLable.setText(_translate("Form", "Total"))
self.followCheckBox.setText(_translate("Form", "Follow newest log"))
@@ -320,12 +322,14 @@ def retranslateUi(self, Form):
self.pluginTotalLable.setText(_translate("Form", "Total:"))
self.pushButton.setText(_translate("Form", "Submit"))
item = self.pluginListTable.horizontalHeaderItem(0)
- item.setText(_translate("Form", "Plugin name"))
+ item.setText(_translate("Form", "Plugin Name"))
item = self.pluginListTable.horizontalHeaderItem(1)
item.setText(_translate("Form", "Author"))
item = self.pluginListTable.horizontalHeaderItem(2)
item.setText(_translate("Form", "Version"))
item = self.pluginListTable.horizontalHeaderItem(3)
+ item.setText(_translate("Form", "Plugin Type"))
+ item = self.pluginListTable.horizontalHeaderItem(4)
item.setText(_translate("Form", "Description"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.pluginListPage), _translate("Form", "Plugins"))
self.label_4.setText(_translate("Form", "Port"))
diff --git a/ictye-live-dm/src/ictye_live_dm/GUI_main.py b/ictye-live-dm/src/ictye_live_dm/GUI_main.py
index 63044e1..31b77b2 100644
--- a/ictye-live-dm/src/ictye_live_dm/GUI_main.py
+++ b/ictye-live-dm/src/ictye_live_dm/GUI_main.py
@@ -82,11 +82,13 @@ def __init__(self, parent=None):
self.init_setting_tab()
self.retranslateUi(self)
self._server = ServerClass()
+
self.startButtoen.clicked.connect(self.start_series)
self.stopButton.clicked.connect(self.stop_series)
+
self.settingTreeWidget.expandAll()
- self.status_display_lable.setText("Stopped")
+ self.status_display_lable.setText("Stopped") # set default status
def init_setting_tab(self):
config = configs.ConfigManager()
@@ -129,12 +131,15 @@ def table_follow(self):
self.logTable.scrollToBottom()
def show_plugin_list(self):
- plugins = pluginsystem.Plugin().list_plugin()
+ plugins = pluginsystem.Plugin().list_plugin_desc()
for i in plugins:
row = self.pluginListTable.rowCount()
self.pluginListTable.insertRow(row)
- self.pluginListTable.setItem(row, 0, QtWidgets.QTableWidgetItem(i[0]))
- self.pluginListTable.setItem(row, 1, QtWidgets.QTableWidgetItem(i[1]))
+ self.pluginListTable.setItem(row, 0, QtWidgets.QTableWidgetItem(i["name"]))
+ self.pluginListTable.setItem(row, 1, QtWidgets.QTableWidgetItem(i["author"]))
+ self.pluginListTable.setItem(row, 2, QtWidgets.QTableWidgetItem(i["version"]))
+ self.pluginListTable.setItem(row, 3, QtWidgets.QTableWidgetItem(i["type"]))
+ self.pluginListTable.setItem(row, 4, QtWidgets.QTableWidgetItem(i["description"]))
class ServerClass:
diff --git a/ictye-live-dm/src/ictye_live_dm/QT-GUI/main.ui b/ictye-live-dm/src/ictye_live_dm/QT-GUI/main.ui
index 6cbf0a3..50c9ffd 100644
--- a/ictye-live-dm/src/ictye_live_dm/QT-GUI/main.ui
+++ b/ictye-live-dm/src/ictye_live_dm/QT-GUI/main.ui
@@ -27,7 +27,7 @@
-
-
-
+
223
@@ -79,7 +79,7 @@
QTabWidget::Rounded
- 3
+ 0
Qt::ElideNone
@@ -158,12 +158,18 @@
-
-
+
+
+
+
+
+
+
-
-
-
+
<html><head/><body><p><span style=" font-size:x-large; font-weight:600;">Location </span><a href="http://127.0.0.1:8082"><span style=" text-decoration: underline; color:#0000ff;">http://127.0.0.1:8082</span></a></p></body></html>
@@ -183,7 +189,7 @@
-
-
+
open in blsower
@@ -313,7 +319,6 @@
QAbstractItemView::NoSelection
-
false
@@ -325,7 +330,7 @@
- Plugin name
+ Plugin Name
@@ -338,6 +343,11 @@
Version
+
+
+ Plugin Type
+
+
Description
diff --git a/ictye-live-dm/src/ictye_live_dm/depends/config_registrar.py b/ictye-live-dm/src/ictye_live_dm/depends/config_registrar.py
index 59a94d6..34b0a06 100644
--- a/ictye-live-dm/src/ictye_live_dm/depends/config_registrar.py
+++ b/ictye-live-dm/src/ictye_live_dm/depends/config_registrar.py
@@ -619,6 +619,7 @@ def __len__(self):
# config schemas
ic_cfg_type = ConfigTree | ConfigKey
+"""ictye 配置類型"""
class ABConfigSchema(metaclass=ABCMeta):
@@ -1025,12 +1026,12 @@ def __init__(self,
self.type_ = s_dict
self.properties = properties
- def __find_additional_properties(self, other: ConfigTree) -> dict:
+ def __find_additional_properties(self, other: ConfigTree, additional: bool = True) -> dict:
k_set: dict = {}
for k, v in other.items():
- if k in self.properties.keys():
+ if (k in self.properties.keys()) and additional:
k_set[k] = v
- if any([re.match(dk, k) for dk, dv in self.pattern_properties]):
+ if any([re.match(dk, k) for dk, dv in self.pattern_properties]) and additional:
k_set[k] = v
return k_set
@@ -1101,7 +1102,7 @@ def __init__(self,
title: str = "",
description: str = "",
_comment: str = "",
- const: ConfigTree | ConfigKey = None,
+ const: ic_cfg_type = None,
all_of: list["ABConfigSchema"] = None,
any_of: list["ABConfigSchema"] = None,
one_of: list["ABConfigSchema"] = None,
diff --git a/ictye-live-dm/src/ictye_live_dm/depends/pluginmain.py b/ictye-live-dm/src/ictye_live_dm/depends/pluginmain.py
index 503a870..853122b 100644
--- a/ictye-live-dm/src/ictye_live_dm/depends/pluginmain.py
+++ b/ictye-live-dm/src/ictye_live_dm/depends/pluginmain.py
@@ -12,11 +12,34 @@ class PluginConfig:
def __init__(self, plugin_name: str):
self.__config = config_registrar.ConfigTree()
- def __get__(self, instance, owner: "PluginMain"):
+ def __get__(self, instance, owner: "PluginMain") -> config_registrar.ConfigTree:
return self.__config
- def register(self, value, name: str, default: typing.Any = None, schema: config_registrar.ConfigSchema = None):
- ...
+ def register(self, value: config_registrar.ConfigKey | dict | config_registrar.ConfigTree, name: str,
+ default: typing.Any = None, schema: config_registrar.ConfigSchema = None):
+ if isinstance(value, dict):
+ self.__config.set(name, config_registrar.ConfigTree(build_dict=value, default=default, schema=schema))
+ elif isinstance(value, list):
+ self.__config.set(name, config_registrar.ConfigTree(build_list=value, default=default, schema=schema))
+ elif isinstance(value, config_registrar.ConfigKey):
+ self.__config.set(name, value)
+ elif isinstance(value, config_registrar.ConfigTree):
+ self.__config.set(name, value)
+ else:
+ self.__config.set(name, config_registrar.ConfigKey(value=value, default=default))
+
+
+class PluginDesc:
+
+ def __get__(self, instance: "PluginMain", owner: "PluginMain") -> dict:
+ return {
+ "name" : instance.plugin_name,
+ "version" : instance.plugin_version,
+ "author" : instance.plugin_author,
+ "description": instance.plugin_desc,
+ "type" : instance.type,
+ "dev_branch" : instance.plugin_dev_beach,
+ }
class PluginMain(metaclass=ABCMeta):
@@ -57,6 +80,7 @@ class PluginMain(metaclass=ABCMeta):
"""cgi列表"""
plugin_config = PluginConfig(plugin_name)
+ plugin_descriptor = PluginDesc()
def __new__(cls, *args, **kwargs):
if not cls._instance:
@@ -142,6 +166,11 @@ def read_config(self):
assert self.plugin_name != ""
self.config = configs.read_config(self.plugin_name)
+ @typing.final
+ def get_description(self) -> str:
+ # TODO: 完善插件描述
+ ...
+
def __aiter__(self):
if self.plugin_type() == "message":
return self
diff --git a/ictye-live-dm/src/ictye_live_dm/http_server.py b/ictye-live-dm/src/ictye_live_dm/http_server.py
index 0ab25cb..8ac9658 100644
--- a/ictye-live-dm/src/ictye_live_dm/http_server.py
+++ b/ictye-live-dm/src/ictye_live_dm/http_server.py
@@ -15,6 +15,7 @@
log = logging.getLogger(__name__)
runner: Optional[web.AppRunner] = None
+
def return_file(file: str):
async def header(request):
nonlocal file
@@ -91,7 +92,7 @@ async def http_cgi(request: web.Request):
if request.match_info["name"] in plugin_system.plugin_cgi_support:
if request.match_info["page"] in plugin_system.plugin_cgi_support[request.match_info["name"]]:
req = await plugin_system.plugin_cgi_support[request.match_info["name"]][request.match_info["page"]](
- request)
+ request)
else:
req = web.Response(status=404, text="no such path")
else:
diff --git a/ictye-live-dm/src/ictye_live_dm/pluginsystem.py b/ictye-live-dm/src/ictye_live_dm/pluginsystem.py
index 47bd711..3369cfa 100644
--- a/ictye-live-dm/src/ictye_live_dm/pluginsystem.py
+++ b/ictye-live-dm/src/ictye_live_dm/pluginsystem.py
@@ -6,7 +6,7 @@
import aiohttp.web as web
-from .depends import pluginmain, plugin_errors, configs,config_registrar
+from .depends import pluginmain, plugin_errors, configs, config_registrar
config: configs.ConfigManager = configs.ConfigManager() # 配置
@@ -87,13 +87,21 @@ def __lod_init_plugin__(self):
self.logger.error(f"failed to import plugin :\n{plugin_name} {str(e)}")
def list_plugin(self) -> list:
- plugins = []
+ plugins: list = []
for plugin in self.message_plugin_list:
plugins.append((plugin.plugin_name, plugin.plugin_desc))
for plugin in self.analyzer_plugin_list:
plugins.append((plugin.plugin_name, plugin.plugin_desc))
return plugins
+ def list_plugin_desc(self) -> list:
+ plugins: list = []
+ for plugin in self.message_plugin_list:
+ plugins.append(plugin.plugin_descriptor)
+ for plugin in self.analyzer_plugin_list:
+ plugins.append(plugin.plugin_descriptor)
+ return plugins
+
async def remove_connect_in_id_dict_aiohttp(self, id):
"""
当连接关闭时,移除连接
diff --git a/ictye-live-dm/tests/Config_schema_test.py b/ictye-live-dm/tests/Config_schema_test.py
index bc29b83..5a3ed0f 100644
--- a/ictye-live-dm/tests/Config_schema_test.py
+++ b/ictye-live-dm/tests/Config_schema_test.py
@@ -76,7 +76,7 @@ def test_bool_schema(config_key_bool):
def test_dict_schema(config_tree_dict):
properties = {
'name': StringSchema(),
- 'age': IntSchema()
+ 'age' : IntSchema()
}
schema = DictSchema(properties)
assert schema.verify(config_tree_dict) == True