00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: pythonscript.c,v 1.6 2008-10-17 15:57:42 sven Exp $";
00022 #endif
00023
00024 #include <Python.h>
00025 #include <structmember.h>
00026
00027
00028 #include <eggdrop/eggdrop.h>
00029
00030 #include "pythonscript.h"
00031
00032
00033 static int my_load_script(void *ignore, char *fname);
00034 static int my_link_var(void *ignore, script_linked_var_t *var);
00035 static int my_unlink_var(void *ignore, script_linked_var_t *var);
00036 static int my_create_command(void *ignore, script_raw_command_t *info);
00037 static int my_delete_command(void *ignore, script_raw_command_t *info);
00038 static int my_get_arg(void *ignore, script_args_t *args, int num, script_var_t *var, int type);
00039
00040 static int my_python_cb_delete(event_owner_t *owner, void *client_data);
00041
00042 script_module_t my_script_interface = {
00043 "Python", NULL,
00044 my_load_script,
00045 my_link_var, my_unlink_var,
00046 my_create_command, my_delete_command,
00047 my_get_arg
00048 };
00049
00050 static egg_module_t *python_modinfo;
00051
00052 static int python_owners = 0;
00053 static event_owner_t *python_owner = 0;
00054
00055 static event_owner_t *python_owner;
00056 static PyObject *SysPath, *SysModules, *CommonModule, *PartylineModule, *PartylineDict, *RealHelper, *SysMod;
00057 static PyObject *MinInt, *MaxInt, *MinUInt, *MaxUInt;
00058
00059 static event_owner_t *CurrentContext;
00060 static char *CurrentContextString;
00061
00062 static event_owner_t *GetContext()
00063 {
00064 PyObject *Mod;
00065
00066 if (CurrentContext) return CurrentContext;
00067 if (!(python_owners & 7)) python_owner = realloc(python_owner, (python_owners + 8) * sizeof(*python_owner));
00068
00069 Mod = PyDict_GetItemString(SysModules, CurrentContextString);
00070 Py_INCREF(Mod);
00071
00072 python_owner[python_owners].name = "pythonscript";
00073 python_owner[python_owners].module = python_modinfo;
00074 python_owner[python_owners].script = strdup(CurrentContextString);
00075 python_owner[python_owners].client_data = Mod;
00076 python_owner[python_owners].on_delete = my_python_cb_delete;
00077 CurrentContext = &python_owner[python_owners++];
00078 return CurrentContext;
00079 }
00080
00081
00082 static int my_load_script(void *ignore, char *fname)
00083 {
00084 int len, i;
00085 char *fullname, *name, *path;
00086 PyObject *PathString, *CommonDict, *NewMod;
00087
00088
00089 len = strlen(fname);
00090 if (len < 4 || fname[len-1] != 'y' || fname[len-2] != 'p' || fname[len-3] != '.') {
00091
00092 return SCRIPT_ERR_NOT_RESPONSIBLE;
00093 }
00094 fullname = strdup(fname);
00095 name = rindex(fullname, '/');
00096 if (!name) {
00097 name = fullname;
00098 path = "";
00099 } else {
00100 *name++ = 0;
00101 path = fullname;
00102 }
00103 name[strlen(name) - 3] = 0;
00104
00105 for (i = 1; i < python_owners; ++i) {
00106 if (!strcmp(python_owner[i].script, name)) {
00107 CurrentContext = &python_owner[i];
00108 if (!PyImport_ReloadModule(python_owner[i].client_data)) {
00109 PyErr_Print();
00110 FlushAll();
00111 free(fullname);
00112 CurrentContext = 0;
00113 return SCRIPT_ERR_CODE;
00114 }
00115 CurrentContext = 0;
00116 return SCRIPT_OK;
00117 }
00118 }
00119
00120 CurrentContext = 0;
00121 CurrentContextString = name;
00122 PathString = PyString_FromString(path);
00123 PyList_Insert(SysPath, 0, PathString);
00124 Py_DECREF(PathString);
00125 if (!(NewMod = PyImport_ImportModule(name))) {
00126 PyErr_Print();
00127 FlushAll();
00128 free(fullname);
00129 CurrentContextString = 0;
00130 return SCRIPT_ERR_CODE;
00131 }
00132
00133 CommonDict = PyObject_GetAttrString(CommonModule, name);
00134 if (!CommonDict) {
00135 PyErr_Clear();
00136 CommonDict = PyDict_New();
00137 PyModule_AddObject(CommonModule, name, CommonDict);
00138 } else {
00139 Py_DECREF(CommonDict);
00140 }
00141 PyDict_SetItemString(CommonDict, "module", NewMod);
00142
00143
00144
00145 PyList_SetSlice(SysPath, 0, 0, 0);
00146 free(fullname);
00147 CurrentContextString = 0;
00148 CurrentContext = 0;
00149 return SCRIPT_OK;
00150 }
00151
00152
00153 static int my_link_var(void *ignore, script_linked_var_t *var) {
00154 CallableObject *O;
00155 char *cmdname;
00156
00157 O = PyObject_New(CallableObject, &Callable_Type);
00158 if (!O) {
00159 PyErr_Print();
00160 FlushAll();
00161 return -1;
00162 }
00163
00164 if (var->class && strlen(var->class)) {
00165 cmdname = egg_mprintf("%s_%s", var->class, var->name);
00166 }
00167 else {
00168 cmdname = strdup(var->name);
00169 }
00170 O->type = PYTHON_VAR;
00171 O->client_data = var;
00172 PyModule_AddObject(EggdropModule, cmdname, (PyObject *) O);
00173 free(cmdname);
00174 return 0;
00175 }
00176
00177
00178 static int my_unlink_var(void *ignore, script_linked_var_t *var) {
00179 PyObject *Dict = *_PyObject_GetDictPtr(EggdropModule);
00180 CallableObject *Callable;
00181
00182 Callable = (CallableObject *) PyDict_GetItemString(Dict, var->name);
00183 if (!Callable) return 0;
00184 Callable->client_data = 0;
00185 PyDict_DelItemString(Dict, var->name);
00186
00187 return 0;
00188 }
00189
00190
00191
00192 static int my_python_callbacker(script_callback_t *me, ...)
00193 {
00194 script_var_t var;
00195 int i, n, retval;
00196 PyObject *cmd, *param, *arg, *RetObj;
00197 va_list va;
00198
00199 cmd = me->callback_data;
00200
00201 if (me->syntax) n = strlen(me->syntax);
00202 else n = 0;
00203
00204 if (n) param = PyTuple_New(n);
00205 else param = 0;
00206
00207 va_start(va, me);
00208 for (i = 0; i < n; i++) {
00209 var.type = me->syntax[i];
00210 if (var.type == SCRIPT_UNSIGNED || var.type == SCRIPT_INTEGER) var.value = (void *) (va_arg(va, int));
00211 else var.value = va_arg(va, void *);
00212 var.len = -1;
00213 arg = c_to_python_var(&var);
00214 if (!arg) {
00215 Py_DECREF(param);
00216 PyErr_Print();
00217 FlushAll();
00218 return 0;
00219 }
00220 PyTuple_SET_ITEM(param, i, arg);
00221 }
00222 va_end(va);
00223
00224 CurrentContext = me->owner;
00225 RetObj = PyObject_CallObject(cmd, param);
00226 FlushAll();
00227 CurrentContext = 0;
00228
00229 if (!RetObj) {
00230 PyErr_Print();
00231 FlushAll();
00232 return 0;
00233 }
00234 if (PyInt_Check(RetObj)) retval = PyInt_AS_LONG(RetObj);
00235 else retval = !PyObject_Not(RetObj);
00236
00237 Py_DECREF(RetObj);
00238
00239 return retval;
00240 }
00241
00242
00243 static int my_python_cb_delete(event_owner_t *owner, void *client_data) {
00244 script_callback_t *me = client_data;
00245 PyObject *Callback = me->callback_data;
00246
00247 Py_DECREF(Callback);
00248 if (me->syntax) free(me->syntax);
00249 if (me->name) free(me->name);
00250 free(me);
00251 return 0;
00252 }
00253
00254
00255 static int my_create_command(void *ignore, script_raw_command_t *info) {
00256 char *cmdname;
00257 CallableObject *O = PyObject_New(CallableObject, &Callable_Type);
00258
00259 if (info->class && strlen(info->class)) {
00260 cmdname = egg_mprintf("%s_%s", info->class, info->name);
00261 }
00262 else {
00263 cmdname = strdup(info->name);
00264 }
00265 O->type = PYTHON_FUNC;
00266 O->client_data = info;
00267 if (PyModule_AddObject(EggdropModule, cmdname, (PyObject *)O)) {
00268 free(cmdname);
00269 PyErr_Print();
00270 FlushAll();
00271 return 1;
00272 }
00273 free(cmdname);
00274 return 0;
00275 }
00276
00277
00278 static int my_delete_command(void *ignore, script_raw_command_t *info)
00279 {
00280 PyObject *Dict = *_PyObject_GetDictPtr(EggdropModule);
00281 CallableObject *Callable;
00282
00283 Callable = (CallableObject *) PyDict_GetItemString(Dict, info->name);
00284
00285 if (!Callable) return 0;
00286 Callable->client_data = 0;
00287 PyDict_DelItemString(Dict, info->name);
00288 return 0;
00289 }
00290
00291
00292
00293 PyObject *c_to_python_var(script_var_t *v) {
00294 PyObject *result;
00295
00296 result = NULL;
00297
00298 if (v->type & SCRIPT_ARRAY) {
00299 PyObject *element;
00300 int i;
00301
00302 result = PyTuple_New(v->len);
00303
00304 if ((v->type & SCRIPT_TYPE_MASK) == SCRIPT_VAR) {
00305 script_var_t **v_list;
00306
00307 v_list = (script_var_t **)v->value;
00308 for (i = 0; i < v->len; i++) {
00309 element = c_to_python_var(v_list[i]);
00310 if (!element) {
00311 Py_DECREF(result);
00312 return 0;
00313 }
00314 PyTuple_SET_ITEM(result, i, element);
00315 }
00316 }
00317 else {
00318
00319 script_var_t v_sub;
00320 void **values;
00321
00322 values = (void **)v->value;
00323 for (i = 0; i < v->len; i++) {
00324 v_sub.type = v->type & (~SCRIPT_ARRAY);
00325 v_sub.value = values[i];
00326 v_sub.len = -1;
00327 element = c_to_python_var(&v_sub);
00328 if (!element) {
00329 Py_DECREF(result);
00330 return 0;
00331 }
00332 PyTuple_SET_ITEM(result, i, element);
00333 }
00334 }
00335
00336 if (v->type & SCRIPT_FREE) free(v->value);
00337 if (v->type & SCRIPT_FREE_VAR) free(v);
00338 return result;
00339 }
00340
00341
00342 switch (v->type & SCRIPT_TYPE_MASK) {
00343 case SCRIPT_INTEGER:
00344 result = PyInt_FromLong((int) v->value);
00345 break;
00346 case SCRIPT_UNSIGNED:
00347
00348
00349
00350
00351 if ((unsigned) v->value <= PyInt_GetMax()) {
00352 result = PyInt_FromLong((unsigned) v->value);
00353 } else {
00354 result = PyLong_FromUnsignedLong((unsigned) v->value);
00355 }
00356 break;
00357 case SCRIPT_STRING: {
00358 char *str = v->value;
00359
00360 if (!str) str = "";
00361 if (v->len == -1) v->len = strlen(str);
00362 result = PyString_FromStringAndSize(str, v->len);
00363 if (v->value && v->type & SCRIPT_FREE) free(v->value);
00364 break;
00365 }
00366 case SCRIPT_STRING_LIST: {
00367 char **str = v->value;
00368 PyObject *element;
00369
00370 result = PyList_New(0);
00371 for (str = v->value; str && *str; ++str) {
00372 element = PyString_FromString(*str);
00373 PyList_Append(result, element);
00374 }
00375 break;
00376 }
00377 case SCRIPT_BYTES: {
00378 byte_array_t *bytes = v->value;
00379 result = PyString_FromStringAndSize(bytes->bytes, bytes->len);
00380 if (bytes->do_free) free(bytes->bytes);
00381 if (v->type & SCRIPT_FREE) free(bytes);
00382 break;
00383 }
00384 #if 0
00385 case SCRIPT_POINTER: {
00386 char str[32];
00387
00388 sprintf(str, "#%u", (unsigned int) v->value);
00389 result = Tcl_NewStringObj(str, -1);
00390 break;
00391 }
00392 case SCRIPT_PARTIER: {
00393 partymember_t *p = v->value;
00394 int pid;
00395
00396 if (p) pid = p->pid;
00397 else pid = -1;
00398 result = Tcl_NewIntObj(pid);
00399 break;
00400 }
00401 #endif
00402 case SCRIPT_USER: {
00403
00404 user_t *u = v->value;
00405
00406 if (u) {
00407 EgguserObject *O = (EgguserObject *) Egguser_Type.tp_new(&Egguser_Type, 0, 0);
00408 O->user = u;
00409 result = (PyObject *) O;
00410 } else {
00411 Py_INCREF(Py_None);
00412 result = Py_None;
00413 }
00414 break;
00415 }
00416 default:
00417
00418 Py_INCREF(Py_None);
00419 result = Py_None;
00420 }
00421 if (v->type & SCRIPT_FREE_VAR) free(v);
00422 return result;
00423 }
00424
00425
00426
00427
00428
00429 int python_to_c_var(PyObject *obj, script_var_t *var, int type) {
00430 var->type = type;
00431 var->len = -1;
00432 var->value = 0;
00433
00434 switch (type & SCRIPT_TYPE_MASK) {
00435 case SCRIPT_STRING: {
00436 char *Str;
00437
00438 Str = PyString_AsString(obj);
00439 if (!Str) return 1;
00440 var->value = strdup(Str);
00441 var->len = strlen(var->value);
00442 return 0;
00443 }
00444 case SCRIPT_CALLBACK: {
00445 script_callback_t *cback;
00446 PyObject *FunctionName, *ModuleName;
00447 char *CFuncName = 0, *CModName = 0;
00448
00449 if (!PyCallable_Check(obj)) {
00450 PyErr_Format(PyExc_TypeError, "Object of type %s is not callable.", obj->ob_type->tp_name);
00451 return 1;
00452 }
00453 cback = malloc(sizeof(*cback));
00454 cback->callback = (Function) my_python_callbacker;
00455 cback->callback_data = obj;
00456 Py_INCREF(obj);
00457
00458 ModuleName = PyObject_GetAttrString(obj, "__module__");
00459 FunctionName = PyObject_GetAttrString(obj, "__name__");
00460 if (ModuleName) CModName = PyString_AsString(ModuleName);
00461 if (FunctionName) CFuncName = PyString_AsString(FunctionName);
00462 PyErr_Clear();
00463 if (!CModName) CModName = "python";
00464 if (CFuncName) {
00465 cback->name = malloc(strlen(CModName) + strlen(CFuncName) + 2);
00466 sprintf(cback->name, "%s.%s", CModName, CFuncName);
00467 } else {
00468 cback->name = malloc(strlen(CModName) + 12);
00469 sprintf(cback->name, "%s.0x%08x", CModName, ((int) obj) & 0xFFFFFFFF);
00470 }
00471
00472 Py_XDECREF(ModuleName);
00473 Py_XDECREF(FunctionName);
00474
00475 cback->delete_data = 0;
00476 cback->syntax = 0;
00477 cback->flags = 0;
00478 cback->owner = GetContext();
00479
00480
00481 var->value = cback;
00482 return 0;
00483 }
00484 case SCRIPT_BYTES: {
00485 byte_array_t *byte_array;
00486
00487 byte_array = malloc(sizeof(*byte_array));
00488
00489 var->value = byte_array;
00490 var->type |= SCRIPT_FREE;
00491
00492 return PyString_AsStringAndSize(obj, (char **) &byte_array->bytes, &byte_array->len);
00493 }
00494 case SCRIPT_UNSIGNED:
00495 case SCRIPT_INTEGER: {
00496 if (!PyInt_Check(obj) && !PyLong_Check(obj)) {
00497 PyErr_SetString(PyExc_TypeError, "an integer is required");
00498 return 1;
00499 }
00500 PyErr_Clear();
00501 if ((((type & SCRIPT_TYPE_MASK) == SCRIPT_UNSIGNED) && (PyObject_Compare(obj, MinUInt) < 0 ||
00502 PyObject_Compare(obj, MaxUInt) > 0)) ||
00503 (((type & SCRIPT_TYPE_MASK) == SCRIPT_INTEGER) && (PyObject_Compare(obj, MinInt) < 0 ||
00504 PyObject_Compare(obj, MaxInt) > 0))) {
00505 PyErr_SetString(PyExc_OverflowError, "Python value does not fit in C type");
00506 return 1;
00507 }
00508
00509 if (PyInt_Check(obj)) var->value = (void *) PyInt_AsLong(obj);
00510 else var->value = (void *) PyLong_AsUnsignedLong(obj);
00511 return 0;
00512 }
00513 #if 0
00514 case SCRIPT_PARTIER: {
00515 int pid = -1;
00516
00517 err = Tcl_GetIntFromObj(myinterp, obj, &pid);
00518 if (!err) var->value = partymember_lookup_pid(pid);
00519 else var->value = NULL;
00520 break;
00521 }
00522 #endif
00523 case SCRIPT_USER: {
00524 EgguserObject *O = (EgguserObject *) obj;
00525
00526 if (!Egguser_Check(obj)) {
00527 PyErr_Format(PyExc_TypeError, "Expected eggdrop.egguser, got %s", obj->ob_type->tp_name);
00528 return 1;
00529 }
00530 if (!O->user || (O->user->flags & USER_DELETED)) {
00531 PyErr_SetString(PyExc_RuntimeError, "This user has been deleted.");
00532 return 1;
00533 }
00534 var->value = O->user;
00535 return 0;
00536 }
00537 }
00538 return 1;
00539 }
00540
00541 static int my_get_arg(void *ignore, script_args_t *args, int num, script_var_t *var, int type) {
00542 PyObject *ParameterTuple, *Parameter;
00543
00544 ParameterTuple = args->client_data;
00545 Parameter = PyTuple_GetItem(ParameterTuple, num);
00546 if (!Parameter) {
00547
00548 PyErr_Clear();
00549 return 1;
00550 }
00551
00552 return python_to_c_var(Parameter, var, type);
00553 }
00554
00555 static int mls(partymember_t *p, char *nick, user_t *u, char *cmd, char *text) {
00556 LogTarget = p;
00557 my_load_script(0, text);
00558 LogTarget = 0;
00559 return 0;
00560 }
00561
00562 static int party_python(partymember_t *p, char *nick, user_t *u, char *cmd, char *text)
00563 {
00564 PyObject *ret;
00565
00566 if (!u || !egg_isowner(u->handle)) {
00567 partymember_write(p, _("You must be a permanent owner (defined in the config file) to use this command.\n"), -1);
00568 return BIND_RET_LOG;
00569 }
00570
00571 if (!text) {
00572 partymember_write(p, _("Syntax: .python <pythonexpression>"), -1);
00573 return 0;
00574 }
00575
00576 CurrentContext = python_owner;
00577 LogTarget = p;
00578 ret = PyRun_String(text, Py_single_input, PartylineDict, PartylineDict);
00579 CurrentContext = 0;
00580 if (!ret) PyErr_Print();
00581 FlushAll();
00582 LogTarget = 0;
00583 return 0;
00584 }
00585
00586 static int Cleanup(void *client_data, script_args_t *args, script_var_t *retval ) {
00587 if (args->len) {
00588 retval->type = SCRIPT_ERROR | SCRIPT_STRING;
00589 retval->value = "This function does not accept any parameters.";
00590 return 0;
00591 }
00592 retval->type = SCRIPT_INTEGER;
00593 retval->value = (void *) script_remove_events_by_owner(python_modinfo, GetContext()->client_data);
00594 return 0;
00595 }
00596
00597 static PyObject *Help(PyObject *self, PyObject *Args) {
00598 PyObject *O = 0, *Stdout, *Write, *DocStr, *HelpStr;
00599
00600 PyArg_ParseTuple(Args, "|O", &O);
00601 if (!O || !Callable_Check(O)) return PyObject_CallObject(RealHelper, Args);
00602 Stdout = PyObject_GetAttrString(SysMod, "stdout");
00603 if (!Stdout || !(Write = PyObject_GetAttrString(Stdout, "write"))) return 0;
00604 Py_DECREF(Stdout);
00605 DocStr = PyObject_GetAttrString(O, "__doc__");
00606 if (!(HelpStr = Py_BuildValue("(O)", DocStr))) {
00607 Py_DECREF(Write);
00608 return 0;
00609 }
00610 Py_DECREF(DocStr);
00611 PyObject_CallObject(Write, HelpStr);
00612 Py_DECREF(HelpStr);
00613 FlushAll();
00614 Py_INCREF(Py_None);
00615 return Py_None;
00616 }
00617
00618 static PyMethodDef HelpMethod = {
00619 "help", Help, METH_VARARGS, 0
00620 };
00621
00622 static bind_list_t party_commands[] = {
00623 {"n", "python", (Function) party_python},
00624 {"n", "load", (Function) mls},
00625 {0}
00626 };
00627
00628 static int pythonscript_close(int why)
00629 {
00630 bind_rem_list("party", party_commands);
00631
00632 script_unregister_module(&my_script_interface);
00633
00634 return 0;
00635 }
00636
00637 static void pythonscript_unload(void)
00638 {
00639 Py_Finalize();
00640 }
00641
00642 static PyMethodDef *methods = {
00643 0
00644 };
00645
00646 EXPORT_SCOPE int pythonscript_LTX_start(egg_module_t *modinfo);
00647
00648 int pythonscript_LTX_start(egg_module_t *modinfo) {
00649 PyObject *builtinModule, *Stdout, *Stderr, *Para, *Helper;
00650 static script_raw_command_t script_cleanup = {
00651 "python", "cleanup", Cleanup, 0
00652 };
00653
00654 python_modinfo = modinfo;
00655
00656 modinfo->name = "pythonscript";
00657 modinfo->author = "eggdev";
00658 modinfo->version = "0.0.1";
00659 modinfo->description = "provides python scripting support";
00660 modinfo->close_func = pythonscript_close;
00661 modinfo->unload_func = pythonscript_unload;
00662
00663
00664 Py_Initialize();
00665
00666 MyModule_Init();
00667 PyType_Ready(&MyDict_Type);
00668 PyType_Ready(&Callable_Type);
00669 PyType_Ready(&Stdio_Type);
00670 PyType_Ready(&Egguser_Type);
00671
00672 MinInt = PyInt_FromLong(INT_MIN);
00673 MaxInt = PyInt_FromLong(INT_MAX);
00674 MinUInt = PyInt_FromLong(0);
00675 MaxUInt = PyInt_FromLong(UINT_MAX);
00676 if (PyObject_Compare(MinUInt, MaxUInt) >= 0) MaxUInt = PyLong_FromUnsignedLong(UINT_MAX);
00677
00678 SysMod = PyImport_ImportModule("sys");
00679 if (!SysMod || !(SysPath = PyObject_GetAttrString(SysMod, "path")) || !(SysModules = PyObject_GetAttrString(SysMod, "modules"))) {
00680 putlog(LOG_MISC, "*", "Module 'pythonscript' could not be initialized: Couldn't get sys.path");
00681 Py_Finalize();
00682 return -4;
00683 }
00684
00685 EggdropModule = MyModule_Add("eggdrop", "this module contains the interface to the eggdrop bot");
00686 CommonModule = Py_InitModule3("common", methods, "this module is a kind of semipersistent storage space for scripts");
00687 PartylineModule = Py_InitModule3("partyline", methods, "this is the partyline mamespace");
00688 PartylineDict = PyModule_GetDict(PartylineModule);
00689
00690 if (!EggdropModule || !CommonModule || !PartylineModule|| !PartylineDict) {
00691 putlog(LOG_MISC, "*", "Module 'pythonscript' could not be initialized: Failed to create modules");
00692 Py_Finalize();
00693 return -4;
00694 }
00695
00696 Py_INCREF(&Stdio_Type);
00697 Py_INCREF(&Egguser_Type);
00698 PyModule_AddObject(EggdropModule, "stdio", (PyObject *) &Stdio_Type);
00699 PyModule_AddObject(EggdropModule, "egguser", (PyObject *) &Egguser_Type);
00700
00701 Para = Py_BuildValue("(i)", 1);
00702 Stdout = Stdio_Type.tp_new(&Stdio_Type, Para, 0);
00703 Py_DECREF(Para);
00704 Para = Py_BuildValue("(i)", 2);
00705 Stderr = Stdio_Type.tp_new(&Stdio_Type, Para, 0);
00706 Py_DECREF(Para);
00707 PyModule_AddObject(SysMod, "stdout", Stdout);
00708 PyModule_AddObject(SysMod, "stderr", Stderr);
00709
00710 builtinModule = PyImport_ImportModule("__builtin__");
00711 if (!builtinModule || PyModule_AddObject(PartylineModule, "__builtins__", builtinModule)) {
00712 putlog(LOG_MISC, "*", "Error inserting '__builtin__' module. builtin commands will not be available from the partyline");
00713 } else {
00714 Helper = PyCFunction_NewEx(&HelpMethod, 0, 0);
00715 RealHelper = PyObject_GetAttrString(builtinModule, "help");
00716 PyModule_AddObject(builtinModule, "help", Helper);
00717 }
00718 Py_XDECREF(builtinModule);
00719 PyErr_Clear();
00720
00721 my_create_command(0, &script_cleanup);
00722 script_register_module(&my_script_interface);
00723 script_playback(&my_script_interface);
00724
00725 bind_add_list("party", party_commands);
00726
00727 python_owners = 1;
00728 python_owner = malloc(8 * sizeof(*python_owner));
00729 python_owner[0].name = "pythonscript";
00730 python_owner[0].module = python_modinfo;
00731 python_owner[0].script = "partyline";
00732 python_owner[0].client_data = PartylineModule;
00733 python_owner[0].on_delete = my_python_cb_delete;
00734
00735
00736 return 0;
00737 }
00738