2
* Copyright (C) 2004-2011 See the AUTHORS file for details.
2
* Copyright (C) 2004-2012 See the AUTHORS file for details.
4
4
* This program is free software; you can redistribute it and/or modify it
5
5
* under the terms of the GNU General Public License version 2 as published
12
#include "FileUtils.h"
12
#include <znc/FileUtils.h>
13
#include <znc/IRCSock.h>
14
#include <znc/Modules.h>
19
19
#include "modpython/swigpyrun.h"
20
20
#include "modpython/module.h"
21
#include "modpython/retstring.h"
23
class CModPython: public CGlobalModule {
21
#include "modpython/ret.h"
26
class CModPython: public CModule {
25
28
PyObject* m_PyZNCModule;
26
29
PyObject* m_PyFormatException;
30
vector<PyObject*> m_vpObject;
78
82
bool OnLoad(const CString& sArgsi, CString& sMessage) {
79
83
CString sModPath, sTmp;
80
if (!CModules::FindModPath("modpython/_znc_core.so", sModPath, sTmp)) {
81
sMessage = "modpython/_znc_core.so not found.";
85
CString sDllPath = "modpython/_znc_core.dll";
87
CString sDllPath = "modpython/_znc_core.so";
89
if (!CModules::FindModPath(sDllPath, sModPath, sTmp)) {
90
sMessage = sDllPath + " not found.";
84
93
sTmp = CDir::ChangeDir(sModPath, "..");
129
138
virtual EModRet OnModuleLoading(const CString& sModName, const CString& sArgs,
130
bool& bSuccess, CString& sRetMsg) {
139
CModInfo::EModuleType eType, bool& bSuccess, CString& sRetMsg) {
134
140
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "load_module");
136
142
sRetMsg = GetPyExceptionStr();
138
144
bSuccess = false;
141
PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssNNN"),
147
PyObject* pyRes = PyObject_CallFunction(pyFunc, const_cast<char*>("ssiNNNN"),
142
148
sModName.c_str(),
144
SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0),
151
(eType == CModInfo::GlobalModule ? Py_None : SWIG_NewInstanceObj(GetUser(), SWIG_TypeQuery("CUser*"), 0)),
152
(eType == CModInfo::NetworkModule ? SWIG_NewInstanceObj(GetNetwork(), SWIG_TypeQuery("CIRCNetwork*"), 0) : Py_None),
145
153
CPyRetString::wrap(sRetMsg),
146
SWIG_NewInstanceObj(reinterpret_cast<CGlobalModule*>(this), SWIG_TypeQuery("CGlobalModule*"), 0));
154
SWIG_NewInstanceObj(reinterpret_cast<CModule*>(this), SWIG_TypeQuery("CModPython*"), 0));
148
156
sRetMsg = GetPyExceptionStr();
149
157
DEBUG("modpython: " << sRetMsg);
255
void TryAddModInfo(const CString& sPath, const CString& sName, set<CModInfo>& ssMods, set<CString>& ssAlready) {
268
void TryAddModInfo(const CString& sPath, const CString& sName, set<CModInfo>& ssMods, set<CString>& ssAlready, CModInfo::EModuleType eType) {
256
269
if (ssAlready.count(sName)) {
298
if (x && ModInfo.SupportsType(eType)) {
286
299
ssMods.insert(ModInfo);
287
300
ssAlready.insert(sName);
291
virtual void OnGetAvailableMods(set<CModInfo>& ssMods, bool bGlobal) {
304
virtual void OnGetAvailableMods(set<CModInfo>& ssMods, CModInfo::EModuleType eType) {
297
306
CModules::ModDirList dirs = CModules::GetModDirs();
299
308
while (!dirs.empty()) {
300
309
set<CString> already;
302
Dir.FillByWildcard(dirs.front().first, "*.py");
303
for (unsigned int a = 0; a < Dir.size(); a++) {
304
CFile& File = *Dir[a];
305
CString sName = File.GetShortName();
306
CString sPath = File.GetLongName();
307
sPath.TrimSuffix(sName);
309
TryAddModInfo(sPath, sName, ssMods, already);
312
Dir.FillByWildcard(dirs.front().first, "*.pyc");
313
for (unsigned int a = 0; a < Dir.size(); a++) {
314
CFile& File = *Dir[a];
315
CString sName = File.GetShortName();
316
CString sPath = File.GetLongName();
317
sPath.TrimSuffix(sName);
319
TryAddModInfo(sPath, sName, ssMods, already);
322
Dir.FillByWildcard(dirs.front().first, "*.so");
323
for (unsigned int a = 0; a < Dir.size(); a++) {
324
CFile& File = *Dir[a];
325
CString sName = File.GetShortName();
326
CString sPath = File.GetLongName();
327
sPath.TrimSuffix(sName);
329
TryAddModInfo(sPath, sName, ssMods, already);
311
Dir.Fill(dirs.front().first);
312
for (unsigned int a = 0; a < Dir.size(); a++) {
313
CFile& File = *Dir[a];
314
CString sName = File.GetShortName();
315
CString sPath = File.GetLongName();
316
sPath.TrimSuffix(sName);
319
if (sName.WildCmp("*.pyc")) {
321
} else if (sName.WildCmp("*.py") || sName.WildCmp("*.so")) {
328
TryAddModInfo(sPath, sName, ssMods, already, eType);
336
335
virtual ~CModPython() {
337
const map<CString, CUser*>& users = CZNC::Get().GetUserMap();
338
for (map<CString, CUser*>::const_iterator i = users.begin(); i != users.end(); ++i) {
339
CModules& M = i->second->GetModules();
343
for (CModules::iterator it = M.begin(); it != M.end(); ++it) {
345
CPyModule* mod = AsPyModule(m);
348
bool bSuccess = false;
350
OnModuleUnloading(mod, bSuccess, sRetMsg);
352
DEBUG("Error unloading python module in ~CModPython: " << sRetMsg);
336
if (!m_PyZNCModule) {
337
DEBUG("~CModPython(): seems like CModPython::OnLoad() didn't initialize python");
340
PyObject* pyFunc = PyObject_GetAttrString(m_PyZNCModule, "unload_all");
342
CString sRetMsg = GetPyExceptionStr();
343
DEBUG("~CModPython(): couldn't find unload_all: " << sRetMsg);
346
PyObject* pyRes = PyObject_CallFunctionObjArgs(pyFunc, NULL);
348
CString sRetMsg = GetPyExceptionStr();
349
DEBUG("modpython tried to unload all modules in its destructor, but: " << sRetMsg);
359
354
Py_CLEAR(m_PyFormatException);
360
355
Py_CLEAR(m_PyZNCModule);
461
456
Py_CLEAR(m_pyObj);
464
PyObject* CPySocket::WriteBytes(PyObject* data) {
465
if (!PyBytes_Check(data)) {
466
PyErr_SetString(PyExc_TypeError, "socket.WriteBytes needs bytes as argument");
471
if (-1 == PyBytes_AsStringAndSize(data, &buffer, &length)) {
474
if (Write(buffer, length)) {
481
459
template<> void TModInfo<CModPython>(CModInfo& Info) {
482
460
Info.SetWikiPage("modpython");