2929plugin_customkey_title = []
3030plugin_filters = []
3131plugin_filters_name = []
32+ plugin_icon = {}
33+ plugin_path = {}
3234def load_plugins ():
3335 for i in os .listdir ("plugins" ):
3436 if not (os .path .exists ("plugins/%s/info.json" % i ) and os .path .exists ("plugins/%s/icon.png" % i ) and os .path .exists ("plugins/%s/main.py" % i )):
35- logger .warning ("目录%s没有有效插件" )
37+ logger .warning ("目录%s没有有效插件" % i )
38+ continue
39+ elif os .path .exists ("plugins/%s/DEL" % i ):
40+ os .remove ("plugins/%s" % i )
41+ logger .info ("插件被成功移除" )
3642 continue
3743 else :
3844 with open ("plugins/%s/info.json" % i ,"r" ,encoding = "utf-8" ) as f :
3945 ct = f .read ()
4046 js = json .loads (ct )
47+ if js ["api" ] > cfg .get (cfg .apiver ):
48+ logger .warning ("当前插件API版本过高,拒绝加载" )
49+ continue
4150 plugin_info [js ["id" ]] = js
4251 pgin = importlib .import_module ("plugins.%s.main" % i )
43- if hasattr (pgin ,"Settings" ):
52+ plugin_icon [js ["id" ]] = "plugins/%s/icon.png" % i
53+ plugin_path [js ["id" ]] = "plugins/%s" % i
54+ if hasattr (pgin ,"Settings" ) and not os .path .exists ("plugins/%s/DISABLED" % i ):
4455 plugin_settings [js ["id" ]] = pgin .Settings ()
4556 if hasattr (pgin ,"Plugin" ):
46- plugin [js ["id" ]] = pgin .Plugin ()
47- for i in plugin [js ["id" ]].customKey :
48- plugin_customkey .append (i )
49- for i in plugin [js ["id" ]].customKeyTitle :
50- plugin_customkey_title .append (i )
51- for i in plugin [js ["id" ]].filters :
52- plugin_filters .append (i )
53- for i in plugin [js ["id" ]].filtersName :
54- plugin_filters_name .append (i )
57+ if not os .path .exists ("plugins/%s/DISABLED" % i ):
58+ plugin [js ["id" ]] = pgin .Plugin ()
59+ for i in plugin [js ["id" ]].customKey :
60+ plugin_customkey .append (i )
61+ for i in plugin [js ["id" ]].customKeyTitle :
62+ plugin_customkey_title .append (i )
63+ for i in plugin [js ["id" ]].filters :
64+ plugin_filters .append (i )
65+ for i in plugin [js ["id" ]].filtersName :
66+ plugin_filters_name .append (i )
67+ else :
68+ logger .warning ("插件%s已被禁用" % js ["id" ])
69+ continue
5570 logger .info ("加载插件:%s成功" % js ["id" ])
5671
5772def apply_customkey ():
@@ -203,6 +218,107 @@ def closeEvent(self, event):
203218 self .hide ()
204219 self .deleteLater ()
205220
221+ class PluginCard (CardWidget ):
222+ def __init__ (self , icon , title , content , path , parent = None ):
223+ super ().__init__ (parent )
224+ self .path = path
225+ self .iconWidget = IconWidget (icon )
226+ self .titleLabel = BodyLabel (title , self )
227+ self .contentLabel = CaptionLabel (content , self )
228+ self .openSwitch = SwitchButton (self )
229+ self .deleteButton = TransparentToolButton (FluentIcon .DELETE , self )
230+
231+ if not os .path .exists ("%s/DISABLED" % self .path ):
232+ self .openSwitch .setChecked (True )
233+ self .openSwitch .checkedChanged .connect (self .disable )
234+ self .deleteButton .clicked .connect (self .delete )
235+
236+ self .hBoxLayout = QHBoxLayout (self )
237+ self .vBoxLayout = QVBoxLayout ()
238+
239+ self .setFixedHeight (73 )
240+ self .iconWidget .setFixedSize (48 , 48 )
241+ self .contentLabel .setTextColor ("#606060" , "#d2d2d2" )
242+
243+ self .hBoxLayout .setContentsMargins (20 , 11 , 11 , 11 )
244+ self .hBoxLayout .setSpacing (15 )
245+ self .hBoxLayout .addWidget (self .iconWidget )
246+
247+ self .vBoxLayout .setContentsMargins (0 , 0 , 0 , 0 )
248+ self .vBoxLayout .setSpacing (0 )
249+ self .vBoxLayout .addWidget (self .titleLabel , 0 , Qt .AlignVCenter )
250+ self .vBoxLayout .addWidget (self .contentLabel , 0 , Qt .AlignVCenter )
251+ self .vBoxLayout .setAlignment (Qt .AlignVCenter )
252+ self .hBoxLayout .addLayout (self .vBoxLayout )
253+
254+ self .hBoxLayout .addStretch (1 )
255+ self .hBoxLayout .addWidget (self .openSwitch , 0 , Qt .AlignRight )
256+ self .hBoxLayout .addWidget (self .deleteButton , 0 , Qt .AlignRight )
257+
258+ def disable (self ):
259+ if not self .openSwitch .isChecked ():
260+ with open ("%s/DISABLED" % self .path ,"w" ,encoding = "utf-8" ) as f :
261+ f .write ("disabled" )
262+ InfoBar .success (
263+ title = '禁用成功' ,
264+ content = "被禁用的插件在下次启动时不会被加载" ,
265+ orient = Qt .Horizontal ,
266+ isClosable = True ,
267+ position = InfoBarPosition .TOP ,
268+ duration = 3000 ,
269+ parent = self
270+ )
271+ else :
272+ if os .path .exists ("%s/DISABLED" % self .path ):
273+ os .remove ("%s/DISABLED" % self .path )
274+ InfoBar .success (
275+ title = '启用成功' ,
276+ content = "该插件在下次启动时会被加载" ,
277+ orient = Qt .Horizontal ,
278+ isClosable = True ,
279+ position = InfoBarPosition .TOP ,
280+ duration = 3000 ,
281+ parent = self
282+ )
283+
284+ def delete (self ):
285+ with open ("%s/DEL" , "w" , encoding = "utf-8" ) as f :
286+ f .write ("delete later" )
287+ InfoBar .success (
288+ title = '设置成功' ,
289+ content = "该插件在下次启动时会被删除" ,
290+ orient = Qt .Horizontal ,
291+ isClosable = True ,
292+ position = InfoBarPosition .TOP ,
293+ duration = 3000 ,
294+ parent = self
295+ )
296+
297+ class PluginSettings (QFrame ):
298+ def __init__ (self , text : str , parent = None ):
299+ global cfg
300+ super ().__init__ (parent = parent )
301+ self .setObjectName (text .replace (' ' , 'PluginSettings' ))
302+ self .df = QVBoxLayout (self )
303+ self .scrollArea = ScrollArea ()
304+ self .scrollArea .setWidgetResizable (True )
305+ self .scrollArea .setHorizontalScrollBarPolicy (Qt .ScrollBarAlwaysOff )
306+ self .optv = QWidget ()
307+ self .opts = QVBoxLayout (self .optv )
308+ self .sets = []
309+ for i in plugin_info .keys ():
310+ des = "%s - By %s - Version %s" % (plugin_info [i ]["description" ],plugin_info [i ]["author" ],plugin_info [i ]["version" ])
311+ self .sets .append (PluginCard (plugin_icon [i ],plugin_info [i ]["name" ],des ,plugin_path [i ]))
312+ for i in self .sets :
313+ self .opts .addWidget (i )
314+ self .scrollArea .setStyleSheet ("QScrollArea{background: transparent; border: none}" )
315+ self .scrollArea .setWidget (self .optv )
316+ self .optv .setStyleSheet ("QWidget{background: transparent}" )
317+ self .df .addWidget (TitleLabel ("插件管理" ))
318+ QScroller .grabGesture (self .scrollArea .viewport (), QScroller .LeftMouseButtonGesture )
319+ self .df .addWidget (self .optv )
320+ logger .info ("插件设置界面初始化完成" )
321+
206322class Choose (QFrame ):
207323
208324 def __init__ (self , text : str , parent = None ):
@@ -843,6 +959,7 @@ def __init__(self):
843959 self .Choose = Choose ("随机抽选" ,self )
844960 self .NameEdit = NameEdit ("名单编辑" , self )
845961 self .Settings = Settings ("设置" ,self )
962+ self .PluginSettings = PluginSettings ("插件管理" ,self )
846963 self .About = About ("关于" , self )
847964 self .initNavigation ()
848965 self .initWindow ()
@@ -868,6 +985,7 @@ def initNavigation(self):
868985 self .addSubInterface (self .Choose , FluentIcon .HOME , "随机抽选" )
869986 self .addSubInterface (self .NameEdit , FluentIcon .EDIT , "名单编辑" )
870987 self .addSubInterface (self .Settings , FluentIcon .SETTING , '设置' , NavigationItemPosition .BOTTOM )
988+ self .addSubInterface (self .PluginSettings , FluentIcon .APPLICATION , '插件管理' , NavigationItemPosition .BOTTOM )
871989 self .addSubInterface (self .About , FluentIcon .INFO , '关于' , NavigationItemPosition .BOTTOM )
872990
873991 def initWindow (self ):
0 commit comments