modules: modpython: Implement Module.AddCommand()

Currently, there is no usable wrapper for CModCommand for use within
bindings, so this commit adds a proxy class that adds itself as a
callback and allows implementing Python classes to implement commands
via __call__().

A completely synthetic example:

import znc

class foo(znc.Module):
    module_types = [znc.CModInfo.UserModule]

    def OnLoad(self, args, message):
        self.AddHelpCommand()
        self.AddCommand(FooCmd)

        return True

class FooCmd(znc.Command):
    cmd = 'foo'
    args = foo.t_d('bar')
    desc = foo.t_d('baz')

    def __call__(self, line):
        self.GetModule().PutModule('I have been foo’d!')

Fixes https://github.com/znc/znc/issues/198
This commit is contained in:
Ernestas Kulik
2022-07-04 00:03:30 +03:00
parent fab1bb1bd5
commit 94f1c32729
4 changed files with 110 additions and 2 deletions
+32
View File
@@ -296,5 +296,37 @@ TEST_F(ZNCTest, ModpythonModperl) {
client.ReadUntil("Loaded module modperl");
}
TEST_F(ZNCTest, ModpythonCommand) {
if (QProcessEnvironment::systemEnvironment().value(
"DISABLED_ZNC_PERL_PYTHON_TEST") == "1") {
return;
}
auto znc = Run();
znc->CanLeak();
InstallModule("cmdtest.py", R"(
import znc
class cmdtest(znc.Module):
def OnLoad(self, args, message):
self.AddCommand(testcmd)
return True
class testcmd(znc.Command):
cmd = 'ping'
def __call__(self, line):
self.GetModule().PutModule('pong')
)");
auto ircd = ConnectIRCd();
auto client = LoginClient();
client.Write("znc loadmod modpython");
client.Write("znc loadmod cmdtest");
client.Write("PRIVMSG *cmdtest :ping");
client.ReadUntil("pong");
}
} // namespace
} // namespace znc_inttest