mirror of
https://github.com/znc/znc.git
synced 2026-03-28 17:42:41 +01:00
Merge branch 'py' of https://github.com/kylef/znc into kylef-py
Conflicts: modules/modpython/znc.py
This commit is contained in:
@@ -123,6 +123,9 @@ public:
|
||||
};
|
||||
|
||||
%extend CModule {
|
||||
CString __str__() {
|
||||
return $self->GetModName();
|
||||
}
|
||||
MCString_iter BeginNV_() {
|
||||
return MCString_iter($self->BeginNV());
|
||||
}
|
||||
@@ -146,6 +149,33 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
%extend CUser {
|
||||
CString __str__() {
|
||||
return $self->GetUserName();
|
||||
}
|
||||
CString __repr__() {
|
||||
return "<CUser " + $self->GetUserName() + ">";
|
||||
}
|
||||
};
|
||||
|
||||
%extend CChan {
|
||||
CString __str__() {
|
||||
return $self->GetName();
|
||||
}
|
||||
CString __repr__() {
|
||||
return "<CChan " + $self->GetName() + ">";
|
||||
}
|
||||
};
|
||||
|
||||
%extend CNick {
|
||||
CString __str__() {
|
||||
return $self->GetNick();
|
||||
}
|
||||
CString __repr__() {
|
||||
return "<CNick " + $self->GetHostMask() + ">";
|
||||
}
|
||||
};
|
||||
|
||||
/* Web */
|
||||
|
||||
%template(StrPair) pair<CString, CString>;
|
||||
|
||||
@@ -6,343 +6,533 @@
|
||||
# by the Free Software Foundation.
|
||||
#
|
||||
|
||||
from znc_core import *
|
||||
import imp
|
||||
import re
|
||||
import traceback
|
||||
import collections
|
||||
|
||||
from znc_core import *
|
||||
|
||||
|
||||
class Socket:
|
||||
def _Accepted(self, host, port):
|
||||
psock = self.OnAccepted(host, port)
|
||||
print(psock)
|
||||
try:
|
||||
return psock._csock
|
||||
except AttributeError:
|
||||
return None
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._csock.GetModule()).GetNewPyObj()
|
||||
def Listen(self, addrtype='all', port=None, bindhost='', ssl=False, maxconns=GetSOMAXCONN(), timeout=0):
|
||||
addr = ADDR_ALL
|
||||
addrtype = addrtype.lower()
|
||||
if addrtype == 'ipv4':
|
||||
addr = ADDR_IPV4ONLY
|
||||
elif addrtype == 'ipv6':
|
||||
addr = ADDR_IPV6ONLY
|
||||
elif addrtype != 'all':
|
||||
raise ValueError("Specified addrtype [{0}] isn't supported".format(addrtype))
|
||||
if port is None:
|
||||
return self.GetModule().GetManager().ListenRand(
|
||||
"python socket for {0}".format(self.GetModule().GetModName()),
|
||||
bindhost,
|
||||
ssl,
|
||||
maxconns,
|
||||
self._csock,
|
||||
timeout,
|
||||
addr
|
||||
)
|
||||
if self.GetModule().GetManager().ListenHost(
|
||||
port,
|
||||
'python socket for {0}'.format(self.GetModule().GetModName()),
|
||||
bindhost,
|
||||
ssl,
|
||||
maxconns,
|
||||
self._csock,
|
||||
timeout,
|
||||
addr):
|
||||
return port
|
||||
return 0
|
||||
def Connect(self, host, port, timeout=60, ssl=False, bindhost=''):
|
||||
return self.GetModule().GetManager().Connect(
|
||||
host,
|
||||
port,
|
||||
'python conn socket for {0}'.format(self.GetModule().GetModName()),
|
||||
timeout,
|
||||
ssl,
|
||||
bindhost,
|
||||
self._csock)
|
||||
def Write(self, data):
|
||||
if (isinstance(data, str)):
|
||||
return self._csock.Write(data)
|
||||
raise TypeError('socket.Write needs str. If you want binary data, use WriteBytes')
|
||||
|
||||
def Init(self, *a, **b): pass
|
||||
def OnConnected(self): pass
|
||||
def OnDisconnected(self): pass
|
||||
def OnTimeout(self): pass
|
||||
def OnConnectionRefused(self): pass
|
||||
def OnReadData(self, bytess): pass
|
||||
def OnReadLine(self, line): pass
|
||||
def OnAccepted(self, host, port): pass
|
||||
def OnShutdown(self): pass
|
||||
ADDR_MAP = {
|
||||
'ipv4': ADDR_IPV4ONLY,
|
||||
'ipv6': ADDR_IPV6ONLY,
|
||||
'all': ADDR_ALL
|
||||
}
|
||||
|
||||
def _Accepted(self, host, port):
|
||||
return getattr(self.OnAccepted(host, port), '_csock', None)
|
||||
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._csock.GetModule()).GetNewPyObj()
|
||||
|
||||
def Listen(self, addrtype='all', port=None, bindhost='', ssl=False,
|
||||
maxconns=GetSOMAXCONN(), timeout=0):
|
||||
try:
|
||||
addr = self.ADDR_MAP[addrtype.lower()]
|
||||
except KeyError:
|
||||
raise ValueError(
|
||||
"Specified addrtype [{0}] isn't supported".format(addrtype))
|
||||
|
||||
args = (
|
||||
"python socket for {0}".format(self.GetModule()),
|
||||
bindhost,
|
||||
ssl,
|
||||
maxconns,
|
||||
self._csock,
|
||||
timeout,
|
||||
addr
|
||||
)
|
||||
|
||||
if port is None:
|
||||
return self.GetModule().GetManager().ListenRand(*args)
|
||||
|
||||
if self.GetModule().GetManager().ListenHost(port, *args):
|
||||
return port
|
||||
|
||||
return 0
|
||||
|
||||
def Connect(self, host, port, timeout=60, ssl=False, bindhost=''):
|
||||
return self.GetModule().GetManager().Connect(
|
||||
host,
|
||||
port,
|
||||
'python conn socket for {0}'.format(self.GetModule()),
|
||||
timeout,
|
||||
ssl,
|
||||
bindhost,
|
||||
self._csock
|
||||
)
|
||||
|
||||
def Write(self, data):
|
||||
if (isinstance(data, str)):
|
||||
return self._csock.Write(data)
|
||||
raise TypeError(
|
||||
'socket.Write needs str. If you want binary data, use WriteBytes')
|
||||
|
||||
def Init(self, *a, **b):
|
||||
pass
|
||||
|
||||
def OnConnected(self):
|
||||
pass
|
||||
|
||||
def OnDisconnected(self):
|
||||
pass
|
||||
|
||||
def OnTimeout(self):
|
||||
pass
|
||||
|
||||
def OnConnectionRefused(self):
|
||||
pass
|
||||
|
||||
def OnReadData(self, bytess):
|
||||
pass
|
||||
|
||||
def OnReadLine(self, line):
|
||||
pass
|
||||
|
||||
def OnAccepted(self, host, port):
|
||||
pass
|
||||
|
||||
def OnShutdown(self):
|
||||
pass
|
||||
|
||||
|
||||
class Timer:
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._ctimer.GetModule()).GetNewPyObj()
|
||||
def RunJob(self): pass
|
||||
def OnShutdown(self): pass
|
||||
def GetModule(self):
|
||||
return AsPyModule(self._ctimer.GetModule()).GetNewPyObj()
|
||||
|
||||
def RunJob(self):
|
||||
pass
|
||||
|
||||
def OnShutdown(self):
|
||||
pass
|
||||
|
||||
|
||||
class ModuleNVIter(collections.Iterator):
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
self.it = cmod.BeginNV_()
|
||||
def __next__(self):
|
||||
if self.it.is_end(self._cmod):
|
||||
raise StopIteration
|
||||
res = self.it.get()
|
||||
self.it.plusplus()
|
||||
return res
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
self.it = cmod.BeginNV_()
|
||||
|
||||
def __next__(self):
|
||||
if self.it.is_end(self._cmod):
|
||||
raise StopIteration
|
||||
res = self.it.get()
|
||||
self.it.plusplus()
|
||||
return res
|
||||
|
||||
|
||||
class ModuleNV(collections.MutableMapping):
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
def __setitem__(self, key, value):
|
||||
self._cmod.SetNV(key, value)
|
||||
def __getitem__(self, key):
|
||||
if not self._cmod.ExistsNV(key):
|
||||
raise KeyError
|
||||
return self._cmod.GetNV(key)
|
||||
def __contains__(self, key):
|
||||
return self._cmod.ExistsNV(key)
|
||||
def __delitem__(self, key):
|
||||
self._cmod.DelNV(key)
|
||||
def keys(self):
|
||||
return ModuleNVIter(self._cmod)
|
||||
__iter__ = keys
|
||||
def __len__(self):
|
||||
raise NotImplemented
|
||||
def __init__(self, cmod):
|
||||
self._cmod = cmod
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._cmod.SetNV(key, value)
|
||||
|
||||
def __getitem__(self, key):
|
||||
if not self._cmod.ExistsNV(key):
|
||||
raise KeyError
|
||||
return self._cmod.GetNV(key)
|
||||
|
||||
def __contains__(self, key):
|
||||
return self._cmod.ExistsNV(key)
|
||||
|
||||
def __delitem__(self, key):
|
||||
self._cmod.DelNV(key)
|
||||
|
||||
def keys(self):
|
||||
return ModuleNVIter(self._cmod)
|
||||
__iter__ = keys
|
||||
|
||||
def __len__(self):
|
||||
raise NotImplemented
|
||||
|
||||
|
||||
class Module:
|
||||
def OnLoad(self, sArgs, sMessage):
|
||||
return True
|
||||
def _GetSubPages(self):
|
||||
return self.GetSubPages()
|
||||
def CreateSocket(self, socketclass, *the, **rest):
|
||||
socket = socketclass()
|
||||
socket._csock = CreatePySocket(self._cmod, socket)
|
||||
socket.Init(*the, **rest)
|
||||
return socket
|
||||
def CreateTimer(self, timer, interval=10, cycles=1, label='pytimer', description='Some python timer'):
|
||||
t = timer()
|
||||
t._ctimer = CreatePyTimer(self._cmod, interval, cycles, label, description, t)
|
||||
return t
|
||||
def GetSubPages(self): pass
|
||||
def OnShutdown(self): pass
|
||||
def OnBoot(self): pass
|
||||
def WebRequiresLogin(self): pass
|
||||
def WebRequiresAdmin(self): pass
|
||||
def GetWebMenuTitle(self): pass
|
||||
def OnWebPreRequest(self, WebSock, sPageName): pass
|
||||
def OnWebRequest(self, WebSock, sPageName, Tmpl): pass
|
||||
def OnPreRehash(self): pass
|
||||
def OnPostRehash(self): pass
|
||||
def OnIRCDisconnected(self): pass
|
||||
def OnIRCConnected(self): pass
|
||||
def OnIRCConnecting(self, IRCSock): pass
|
||||
def OnIRCConnectionError(self, IRCSock): pass
|
||||
def OnIRCRegistration(self, sPass, sNick, sIdent, sRealName): pass
|
||||
def OnBroadcast(self, sMessage): pass
|
||||
def OnDCCUserSend(self, RemoteNick, uLongIP, uPort, sFile, uFileSize): pass
|
||||
def OnChanPermission(self, OpNick, Nick, Channel, uMode, bAdded, bNoChange): pass
|
||||
def OnOp(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnDeop(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnVoice(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnDevoice(self, OpNick, Nick, Channel, bNoChange): pass
|
||||
def OnMode(self, OpNick, Channel, uMode, sArg, bAdded, bNoChange): pass
|
||||
def OnRawMode(self, OpNick, Channel, sModes, sArgs): pass
|
||||
def OnRaw(self, sLine): pass
|
||||
def OnStatusCommand(self, sCommand): pass
|
||||
def OnModCommand(self, sCommand): pass
|
||||
def OnModNotice(self, sMessage): pass
|
||||
def OnModCTCP(self, sMessage): pass
|
||||
def OnQuit(self, Nick, sMessage, vChans): pass
|
||||
def OnNick(self, Nick, sNewNick, vChans): pass
|
||||
def OnKick(self, OpNick, sKickedNick, Channel, sMessage): pass
|
||||
def OnJoin(self, Nick, Channel): pass
|
||||
def OnPart(self, Nick, Channel, sMessage=None): pass
|
||||
def OnChanBufferStarting(self, Chan, Client): pass
|
||||
def OnChanBufferEnding(self, Chan, Client): pass
|
||||
def OnChanBufferPlayLine(self, Chan, Client, sLine): pass
|
||||
def OnPrivBufferPlayLine(self, Client, sLine): pass
|
||||
def OnClientLogin(self): pass
|
||||
def OnClientDisconnect(self): pass
|
||||
def OnUserRaw(self, sLine): pass
|
||||
def OnUserCTCPReply(self, sTarget, sMessage): pass
|
||||
def OnUserCTCP(self, sTarget, sMessage): pass
|
||||
def OnUserAction(self, sTarget, sMessage): pass
|
||||
def OnUserMsg(self, sTarget, sMessage): pass
|
||||
def OnUserNotice(self, sTarget, sMessage): pass
|
||||
def OnUserJoin(self, sChannel, sKey): pass
|
||||
def OnUserPart(self, sChannel, sMessage): pass
|
||||
def OnUserTopic(self, sChannel, sTopic): pass
|
||||
def OnUserTopicRequest(self, sChannel): pass
|
||||
def OnCTCPReply(self, Nick, sMessage): pass
|
||||
def OnPrivCTCP(self, Nick, sMessage): pass
|
||||
def OnChanCTCP(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivAction(self, Nick, sMessage): pass
|
||||
def OnChanAction(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivMsg(self, Nick, sMessage): pass
|
||||
def OnChanMsg(self, Nick, Channel, sMessage): pass
|
||||
def OnPrivNotice(self, Nick, sMessage): pass
|
||||
def OnChanNotice(self, Nick, Channel, sMessage): pass
|
||||
def OnTopic(self, Nick, Channel, sTopic): pass
|
||||
def OnServerCapAvailable(self, sCap): pass
|
||||
def OnServerCapResult(self, sCap, bSuccess): pass
|
||||
def OnTimerAutoJoin(self, Channel): pass
|
||||
def OnEmbeddedWebRequest(self, WebSock, sPageName, Tmpl): pass
|
||||
description = '< Placeholder for a description >'
|
||||
|
||||
def __str__(self):
|
||||
return self.GetModName()
|
||||
|
||||
def OnLoad(self, sArgs, sMessage):
|
||||
return True
|
||||
|
||||
def _GetSubPages(self):
|
||||
return self.GetSubPages()
|
||||
|
||||
def CreateSocket(self, socketclass, *the, **rest):
|
||||
socket = socketclass()
|
||||
socket._csock = CreatePySocket(self._cmod, socket)
|
||||
socket.Init(*the, **rest)
|
||||
return socket
|
||||
|
||||
def CreateTimer(self, timer, interval=10, cycles=1, label='pytimer',
|
||||
description='Some python timer'):
|
||||
t = timer()
|
||||
t._ctimer = CreatePyTimer(self._cmod, interval, cycles, label,
|
||||
description, t)
|
||||
return t
|
||||
|
||||
def GetSubPages(self):
|
||||
pass
|
||||
|
||||
def OnShutdown(self):
|
||||
pass
|
||||
|
||||
def OnBoot(self):
|
||||
pass
|
||||
|
||||
def WebRequiresLogin(self):
|
||||
pass
|
||||
|
||||
def WebRequiresAdmin(self):
|
||||
pass
|
||||
|
||||
def GetWebMenuTitle(self):
|
||||
pass
|
||||
|
||||
def OnWebPreRequest(self, WebSock, sPageName):
|
||||
pass
|
||||
|
||||
def OnWebRequest(self, WebSock, sPageName, Tmpl):
|
||||
pass
|
||||
|
||||
def OnPreRehash(self):
|
||||
pass
|
||||
|
||||
def OnPostRehash(self):
|
||||
pass
|
||||
|
||||
def OnIRCDisconnected(self):
|
||||
pass
|
||||
|
||||
def OnIRCConnected(self):
|
||||
pass
|
||||
|
||||
def OnIRCConnecting(self, IRCSock):
|
||||
pass
|
||||
|
||||
def OnIRCConnectionError(self, IRCSock):
|
||||
pass
|
||||
|
||||
def OnIRCRegistration(self, sPass, sNick, sIdent, sRealName):
|
||||
pass
|
||||
|
||||
def OnBroadcast(self, sMessage):
|
||||
pass
|
||||
|
||||
def OnDCCUserSend(self, RemoteNick, uLongIP, uPort, sFile, uFileSize):
|
||||
pass
|
||||
|
||||
def OnChanPermission(self, OpNick, Nick, Channel, uMode, bAdded,
|
||||
bNoChange):
|
||||
pass
|
||||
|
||||
def OnOp(self, OpNick, Nick, Channel, bNoChange):
|
||||
pass
|
||||
|
||||
def OnDeop(self, OpNick, Nick, Channel, bNoChange):
|
||||
pass
|
||||
|
||||
def OnVoice(self, OpNick, Nick, Channel, bNoChange):
|
||||
pass
|
||||
|
||||
def OnDevoice(self, OpNick, Nick, Channel, bNoChange):
|
||||
pass
|
||||
|
||||
def OnMode(self, OpNick, Channel, uMode, sArg, bAdded, bNoChange):
|
||||
pass
|
||||
|
||||
def OnRawMode(self, OpNick, Channel, sModes, sArgs):
|
||||
pass
|
||||
|
||||
def OnRaw(self, sLine):
|
||||
pass
|
||||
|
||||
def OnStatusCommand(self, sCommand):
|
||||
pass
|
||||
|
||||
def OnModCommand(self, sCommand):
|
||||
pass
|
||||
|
||||
def OnModNotice(self, sMessage):
|
||||
pass
|
||||
|
||||
def OnModCTCP(self, sMessage):
|
||||
pass
|
||||
|
||||
def OnQuit(self, Nick, sMessage, vChans):
|
||||
pass
|
||||
|
||||
def OnNick(self, Nick, sNewNick, vChans):
|
||||
pass
|
||||
|
||||
def OnKick(self, OpNick, sKickedNick, Channel, sMessage):
|
||||
pass
|
||||
|
||||
def OnJoin(self, Nick, Channel):
|
||||
pass
|
||||
|
||||
def OnPart(self, Nick, Channel, sMessage=None):
|
||||
pass
|
||||
|
||||
def OnChanBufferStarting(self, Chan, Client):
|
||||
pass
|
||||
|
||||
def OnChanBufferEnding(self, Chan, Client):
|
||||
pass
|
||||
|
||||
def OnChanBufferPlayLine(self, Chan, Client, sLine):
|
||||
pass
|
||||
|
||||
def OnPrivBufferPlayLine(self, Client, sLine):
|
||||
pass
|
||||
|
||||
def OnClientLogin(self):
|
||||
pass
|
||||
|
||||
def OnClientDisconnect(self):
|
||||
pass
|
||||
|
||||
def OnUserRaw(self, sLine):
|
||||
pass
|
||||
|
||||
def OnUserCTCPReply(self, sTarget, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserCTCP(self, sTarget, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserAction(self, sTarget, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserMsg(self, sTarget, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserNotice(self, sTarget, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserJoin(self, sChannel, sKey):
|
||||
pass
|
||||
|
||||
def OnUserPart(self, sChannel, sMessage):
|
||||
pass
|
||||
|
||||
def OnUserTopic(self, sChannel, sTopic):
|
||||
pass
|
||||
|
||||
def OnUserTopicRequest(self, sChannel):
|
||||
pass
|
||||
|
||||
def OnCTCPReply(self, Nick, sMessage):
|
||||
pass
|
||||
|
||||
def OnPrivCTCP(self, Nick, sMessage):
|
||||
pass
|
||||
|
||||
def OnChanCTCP(self, Nick, Channel, sMessage):
|
||||
pass
|
||||
|
||||
def OnPrivAction(self, Nick, sMessage):
|
||||
pass
|
||||
|
||||
def OnChanAction(self, Nick, Channel, sMessage):
|
||||
pass
|
||||
|
||||
def OnPrivMsg(self, Nick, sMessage):
|
||||
pass
|
||||
|
||||
def OnChanMsg(self, Nick, Channel, sMessage):
|
||||
pass
|
||||
|
||||
def OnPrivNotice(self, Nick, sMessage):
|
||||
pass
|
||||
|
||||
def OnChanNotice(self, Nick, Channel, sMessage):
|
||||
pass
|
||||
|
||||
def OnTopic(self, Nick, Channel, sTopic):
|
||||
pass
|
||||
|
||||
def OnServerCapAvailable(self, sCap):
|
||||
pass
|
||||
|
||||
def OnServerCapResult(self, sCap, bSuccess):
|
||||
pass
|
||||
|
||||
def OnTimerAutoJoin(self, Channel):
|
||||
pass
|
||||
|
||||
def OnEmbeddedWebRequest(self, WebSock, sPageName, Tmpl):
|
||||
pass
|
||||
|
||||
|
||||
def make_inherit(cl, parent, attr):
|
||||
def make_caller(parent, name, attr):
|
||||
return lambda self, *a: parent.__dict__[name](self.__dict__[attr], *a)
|
||||
while True:
|
||||
for x in parent.__dict__:
|
||||
if x[:1] != '_' and x not in cl.__dict__:
|
||||
setattr(cl, x, make_caller(parent, x, attr))
|
||||
if '_s' in parent.__dict__:
|
||||
parent = parent._s
|
||||
else:
|
||||
break
|
||||
def make_caller(parent, name, attr):
|
||||
return lambda self, *a: parent.__dict__[name](self.__dict__[attr], *a)
|
||||
while True:
|
||||
for x in parent.__dict__:
|
||||
if not x.startswith('_') and x not in cl.__dict__:
|
||||
setattr(cl, x, make_caller(parent, x, attr))
|
||||
if '_s' in parent.__dict__:
|
||||
parent = parent._s
|
||||
else:
|
||||
break
|
||||
|
||||
make_inherit(Socket, CPySocket, '_csock')
|
||||
make_inherit(Module, CPyModule, '_cmod')
|
||||
make_inherit(Timer, CPyTimer, '_ctimer')
|
||||
|
||||
def find_open(modname):
|
||||
'''Returns (pymodule, datapath)'''
|
||||
for d in CModules.GetModDirs():
|
||||
# d == (libdir, datadir)
|
||||
try:
|
||||
x = imp.find_module(modname, [d[0]])
|
||||
except ImportError:
|
||||
# no such file in dir d
|
||||
continue
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
# the same
|
||||
continue
|
||||
if x[2][0] == '.so':
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
# found needed .so but can't load it...
|
||||
# maybe it's normal (non-python) znc module?
|
||||
# another option here could be to "continue"
|
||||
# search of python module in other moddirs.
|
||||
# but... we respect C++ modules ;)
|
||||
return (None, None)
|
||||
finally:
|
||||
x[0].close()
|
||||
else:
|
||||
# this is not .so, so it can be only python module .py or .pyc
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
finally:
|
||||
x[0].close()
|
||||
return (pymodule, d[1])
|
||||
else:
|
||||
# nothing found
|
||||
return (None, None)
|
||||
|
||||
def get_descr(cls):
|
||||
return getattr(cls, 'description', '< Placeholder for a description >')
|
||||
def find_open(modname):
|
||||
'''Returns (pymodule, datapath)'''
|
||||
for d in CModules.GetModDirs():
|
||||
# d == (libdir, datadir)
|
||||
try:
|
||||
x = imp.find_module(modname, [d[0]])
|
||||
except ImportError:
|
||||
# no such file in dir d
|
||||
continue
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>,
|
||||
# './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at
|
||||
# 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
# the same
|
||||
continue
|
||||
if x[2][0] == '.so':
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
# found needed .so but can't load it...
|
||||
# maybe it's normal (non-python) znc module?
|
||||
# another option here could be to "continue"
|
||||
# search of python module in other moddirs.
|
||||
# but... we respect C++ modules ;)
|
||||
return (None, None)
|
||||
finally:
|
||||
x[0].close()
|
||||
else:
|
||||
# this is not .so, so it can be only python module .py or .pyc
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
finally:
|
||||
x[0].close()
|
||||
return (pymodule, d[1])
|
||||
else:
|
||||
# nothing found
|
||||
return (None, None)
|
||||
|
||||
|
||||
def load_module(modname, args, user, retmsg, modpython):
|
||||
'''Returns 0 if not found, 1 on loading error, 2 on success'''
|
||||
if re.search(r'[^a-zA-Z0-9_]', modname) is not None:
|
||||
retmsg.s = 'Module names can only contain letters, numbers and underscores, [{0}] is invalid.'.format(modname)
|
||||
return 1
|
||||
pymodule, datapath = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
module = cl()
|
||||
module._cmod = CreatePyModule(user, modname, datapath, module, modpython)
|
||||
module.nv = ModuleNV(module._cmod)
|
||||
module.SetDescription(get_descr(cl))
|
||||
module.SetArgs(args)
|
||||
module.SetModPath(pymodule.__file__)
|
||||
user.GetModules().push_back(module._cmod)
|
||||
try:
|
||||
loaded = True
|
||||
if not module.OnLoad(args, retmsg):
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Module [{0}] aborted.'.format(modname)
|
||||
else:
|
||||
retmsg.s = 'Module [{0}] aborted: {1}'.format(modname, retmsg.s)
|
||||
loaded = False
|
||||
except BaseException:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception: {0}'.format(traceback.format_exc())
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception: {1}'.format(retmsg.s, traceback.format_exc())
|
||||
loaded = False
|
||||
except:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception.'
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception.'.format(retmsg.s)
|
||||
loaded = False
|
||||
'''Returns 0 if not found, 1 on loading error, 2 on success'''
|
||||
if re.search(r'[^a-zA-Z0-9_]', modname) is not None:
|
||||
retmsg.s = 'Module names can only contain letters, numbers and ' \
|
||||
'underscores, [{0}] is invalid.'.format(modname)
|
||||
return 1
|
||||
pymodule, datapath = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(
|
||||
pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
module = cl()
|
||||
module._cmod = CreatePyModule(user, modname, datapath, module, modpython)
|
||||
module.nv = ModuleNV(module._cmod)
|
||||
module.SetDescription(cl.description)
|
||||
module.SetArgs(args)
|
||||
module.SetModPath(pymodule.__file__)
|
||||
user.GetModules().push_back(module._cmod)
|
||||
try:
|
||||
loaded = True
|
||||
if not module.OnLoad(args, retmsg):
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Module [{0}] aborted.'.format(modname)
|
||||
else:
|
||||
retmsg.s = 'Module [{0}] aborted: {1}'.format(modname,
|
||||
retmsg.s)
|
||||
loaded = False
|
||||
except BaseException:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception: {0}'.format(traceback.format_exc())
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception: {1}'.format(retmsg.s,
|
||||
traceback.format_exc())
|
||||
loaded = False
|
||||
except:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = 'Got exception.'
|
||||
else:
|
||||
retmsg.s = '{0}; Got exception.'.format(retmsg.s)
|
||||
loaded = False
|
||||
|
||||
if loaded:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = "[{0}]".format(pymodule.__file__)
|
||||
else:
|
||||
retmsg.s = "[{1}] [{0}]".format(pymodule.__file__, retmsg.s)
|
||||
return 2
|
||||
print(retmsg.s)
|
||||
if loaded:
|
||||
if retmsg.s == '':
|
||||
retmsg.s = "[{0}]".format(pymodule.__file__)
|
||||
else:
|
||||
retmsg.s = "[{1}] [{0}]".format(pymodule.__file__,
|
||||
retmsg.s)
|
||||
return 2
|
||||
print(retmsg.s)
|
||||
|
||||
unload_module(module)
|
||||
return 1
|
||||
|
||||
unload_module(module)
|
||||
return 1
|
||||
|
||||
def unload_module(module):
|
||||
module.OnShutdown()
|
||||
cmod = module._cmod
|
||||
del module._cmod
|
||||
cmod.GetUser().GetModules().removeModule(cmod)
|
||||
cmod.DeletePyModule()
|
||||
del cmod
|
||||
module.OnShutdown()
|
||||
cmod = module._cmod
|
||||
del module._cmod
|
||||
cmod.GetUser().GetModules().removeModule(cmod)
|
||||
cmod.DeletePyModule()
|
||||
del cmod
|
||||
|
||||
|
||||
def get_mod_info(modname, retmsg, modinfo):
|
||||
'''0-not found, 1-error, 2-success'''
|
||||
pymodule, datadir = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(get_descr(cl))
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 2
|
||||
'''0-not found, 1-error, 2-success'''
|
||||
pymodule, datadir = find_open(modname)
|
||||
if pymodule is None:
|
||||
return 0
|
||||
if modname not in pymodule.__dict__:
|
||||
retmsg.s = "Python module [{0}] doesn't have class named [{1}]".format(
|
||||
pymodule.__file__, modname)
|
||||
return 1
|
||||
cl = pymodule.__dict__[modname]
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(cl.description)
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 2
|
||||
|
||||
|
||||
def get_mod_info_path(path, modname, modinfo):
|
||||
try:
|
||||
x = imp.find_module(modname, [path])
|
||||
except ImportError:
|
||||
return 0
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>, './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>, './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
return 0
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
return 0
|
||||
finally:
|
||||
x[0].close()
|
||||
if modname not in pymodule.__dict__:
|
||||
return 0
|
||||
cl = pymodule.__dict__[modname]
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(get_descr(cl))
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 1
|
||||
try:
|
||||
x = imp.find_module(modname, [path])
|
||||
except ImportError:
|
||||
return 0
|
||||
# x == (<open file './modules/admin.so', mode 'rb' at 0x7fa2dc748d20>,
|
||||
# './modules/admin.so', ('.so', 'rb', 3))
|
||||
# x == (<open file './modules/pythontest.py', mode 'U' at 0x7fa2dc748d20>,
|
||||
# './modules/pythontest.py', ('.py', 'U', 1))
|
||||
if x[0] is None:
|
||||
return 0
|
||||
try:
|
||||
pymodule = imp.load_module(modname, *x)
|
||||
except ImportError:
|
||||
return 0
|
||||
finally:
|
||||
x[0].close()
|
||||
if modname not in pymodule.__dict__:
|
||||
return 0
|
||||
cl = pymodule.__dict__[modname]
|
||||
modinfo.SetGlobal(False)
|
||||
modinfo.SetDescription(get_descr(cl))
|
||||
modinfo.SetName(modname)
|
||||
modinfo.SetPath(pymodule.__file__)
|
||||
return 1
|
||||
|
||||
|
||||
CONTINUE = CModule.CONTINUE
|
||||
HALT = CModule.HALT
|
||||
@@ -358,12 +548,12 @@ VersionMajor = GetVersionMajor()
|
||||
VersionMinor = GetVersionMinor()
|
||||
VersionExtra = GetVersionExtra()
|
||||
|
||||
def CreateWebSubPage(name, title='', params=dict(), admin=False):
|
||||
vpair = VPair()
|
||||
for k, v in params.items():
|
||||
VPair_Add2Str_(vpair, k, v)
|
||||
flags = 0
|
||||
if admin:
|
||||
flags |= CWebSubPage.F_ADMIN
|
||||
return CreateWebSubPage_(name, title, vpair, flags)
|
||||
|
||||
def CreateWebSubPage(name, title='', params=dict(), admin=False):
|
||||
vpair = VPair()
|
||||
for k, v in params.items():
|
||||
VPair_Add2Str_(vpair, k, v)
|
||||
flags = 0
|
||||
if admin:
|
||||
flags |= CWebSubPage.F_ADMIN
|
||||
return CreateWebSubPage_(name, title, vpair, flags)
|
||||
|
||||
Reference in New Issue
Block a user