aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFulgen301 <tokmajigeorge@gmail.com>2017-03-18 11:53:23 +0100
committerFulgen301 <tokmajigeorge@gmail.com>2017-07-11 11:10:31 +0200
commit5cd0eccd91dbfcb344029606e83dfd0ce355dac2 (patch)
treeaa26ad6ee663d095dfa111a806a9041c381148e5
parent6f4e06c596f717ad91f69c9b7a7b18395e14d5b0 (diff)
downloadpycrctrl-5cd0eccd91dbfcb344029606e83dfd0ce355dac2.tar.gz
pycrctrl-5cd0eccd91dbfcb344029606e83dfd0ce355dac2.zip
Add basic plugin functionality; move pycrctrl into a folder
-rw-r--r--pycrctrl/plugins.py48
-rw-r--r--pycrctrl/pycrctrl.py (renamed from pycrctrl.py)15
2 files changed, 60 insertions, 3 deletions
diff --git a/pycrctrl/plugins.py b/pycrctrl/plugins.py
new file mode 100644
index 0000000..d6a43c2
--- /dev/null
+++ b/pycrctrl/plugins.py
@@ -0,0 +1,48 @@
+import sys
+import os
+import os.path
+import re
+
+import importlib.util
+
+if sys.version_info < (3,6):
+ class ModuleNotFoundError(ImportError):
+ pass
+
+class PluginError(Exception):
+ """There is an error when loading a PyCRCtrl plugin."""
+ pass
+
+def loadPlugin(name : str, directories : list):
+ """Loads a plugin."""
+
+ if not isinstance(directories, list):
+ directories = [directories]
+
+ found = None
+ for dir in directories:
+ if found == None:
+ if os.path.isdir(os.path.join(dir, name)) or os.path.isfile(os.path.join(dir, ("{}.py".format(name) if name[-3:] != ".py" else name))):
+ found = dir
+ else:
+ raise ImportError("Multiple modules named {} found!".format(name))
+
+ if found == None:
+ raise ModuleNotFoundError("Cannot find module {}".format(name)) from None
+
+ spec = importlib.util.spec_from_file_location(name, os.path.join(dir, name))
+
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+
+ sys.modules[module.__name__] = module
+ return module
+
+def loadPluginClass(module):
+ try:
+ c = module.Class()
+
+ except AttributeError:
+ raise PluginError("The plugin \"{}\" does not have a Class attribute".format(module.__name__)) from None
+
+ return c \ No newline at end of file
diff --git a/pycrctrl.py b/pycrctrl/pycrctrl.py
index 02e2595..1076323 100644
--- a/pycrctrl.py
+++ b/pycrctrl/pycrctrl.py
@@ -31,6 +31,7 @@ import json
import base64
import supybot.log
import supybot.ircmsgs as ircmsgs
+import pycrctrl.plugins
from pickle import Pickler, Unpickler
from PyQt5.QtCore import *
@@ -245,6 +246,7 @@ class PyCRCtrl(object):
_capa_old = {}
updater = None
+ plugins = QList()
def __init__(self, irc=None, path=None, config="pycrctrl.conf"):
if sys.platform == "win32":
@@ -260,6 +262,13 @@ class PyCRCtrl(object):
self.queue = queue.Queue(5)
if self.config.get("engine") == "openclonk-server":
self.updater = Updater(self)
+
+ for dir in self.config["General"]["Directories"]["plugins"]:
+ for p in os.listdir(dir):
+ try:
+ plugins.append(pycrctrl.plugins.loadPluginClass(pycrctrl.plugins.loadPlugin(p, dir)))
+ except Exception:
+ pass
def __ostream__(self, ostream):
return "PyCRCtrl: commandline: {}, channel: {}, scenario: {}".format(self.commandline, self.channels["ingame"], (self.scenario if self.scenario != "" else "None"))
@@ -310,12 +319,13 @@ class PyCRCtrl(object):
return False
config = os.path.join(self.path, config)
+ print(config)
if os.path.isdir(config):
return False
elif os.path.isfile(config):
- self.config = json.load(open(os.path.join(self.path, config),"r"))
+ self.config = json.load(open(config),"r")
return True
elif not os.path.exists(config):
@@ -354,8 +364,7 @@ class PyCRCtrl(object):
"Rights" : {
"admin" : True,
"moderator" : True
- }
- },
+ },
"Updater" : {
"enabled" : False,