/* This is the interface to the python interpreter Originally from the now defunct gnocci project. C. Steenberg 15 May 2000 */ #include #include #include #include #include #include #include "python_main.h" #include "../sg.h" #include "../sg_project_autosave.h" #include "../sg_config.h" #include "../sg_dialogs.h" /* autosave timeout interval defaults to 5 minutes */ gint sg_autosave_interval = 5; /* compress level defaults to best compression */ gint sg_compress_level = 9; gboolean sg_report_python_error; PyObject *main_dict, *sys_dict, *sg_o, *sg_dict, *config_dict; static gchar def_safe_modules[][80]={"audioop", "array","binascii", "cmath","errno", "imageop","marshal", "math", "md5", "operator","parser", "regex", "rotor", "select","strop", "struct","time","gtk","_gtk","GDK","GTK","gnome","GNOME","pickle","Numeric","pysga",""}; static gchar def_safe_os[][80]={"error", "fstat","listdir", "lstat", "readlink", "stat","times", "uname", "getpid", "getppid","getcwd","getuid", "getgid", "geteuid","getegid","name","environ","ctermid","getgroups","getlogin", "getpgrp","getpid","getppid","strerror","umask","uname","fpathconf","isatty", "times","confstr","confstr_names","sysconf","sysconf_names","curdir", "pardir","sep","altsep","pathsep","defpath","linesep","path","_get_exports_list","_names",""}; static gchar def_safe_sys[][80]={"argv","ps1","ps2", "copyright", "version", "platform","exit", "maxint","stderr","stdout","stdin","byteorder","builtin_module_names", "executable","exitfunc","getrefcount","getrecursionlimit","maxint","platform", "prefix","version_info","path","excepthook","displayhook",""}; typedef struct _module_opts module_opts; struct _module_opts { gchar *name; gint flags; }; static module_opts comp_imports[]={ {"os",SG_MODULE_LOAD_MAIN|SG_MODULE_LOAD_REQ}, {"sys",SG_MODULE_LOAD_MAIN|SG_MODULE_LOAD_REQ}, {"Numeric",SG_MODULE_LOAD_SYMBOLS|SG_MODULE_LOAD_REQ}, {"pickle",SG_MODULE_LOAD_MAIN|SG_MODULE_LOAD_REQ}, {"gtk",SG_MODULE_LOAD_MAIN}, /* These two modules are not absolutely required*/ {"pysga",SG_MODULE_LOAD_SYMBOLS}, /* and may be loaded from non-standard places */ {NULL,0}}; /* Remember to increase the size of save_vars and save_obj when adding to this list static gchar *save_vars_names[]={"sg_safe_modules","sg_safe_os","sg_safe_sys","sg_import_modules","sg_canvas_labels_pos", "sg_canvas_labels_width","sg_save_freq","sg_compression_level","sg_module_paths",""};*/ static PyObject *default_paths = NULL, *builtin_dict = NULL, *builtin_o = NULL, *os_dict = NULL, *os_o = NULL, *main_o = NULL, *sys_o = NULL; gint python_init_minimal(gchar *progname) { PyObject *module_object, *module_dict, *keys, *functions, *key_name, *object, *full, *empty, *items, *string,*pickle; gint i,flag,size; gchar temp[200],*name,*homedir; PyObject *av; int argc; char **argv; Py_SetProgramName(progname); Py_Initialize(); import_array(); sg_report_python_error=TRUE; main_o=PyImport_ImportModule("__main__"); builtin_o=PyImport_AddModule("__builtin__"); sys_o=PyImport_ImportModule ("sys"); sys_o=PyImport_AddModule ("sys"); os_o=PyImport_ImportModule ("os"); os_o=PyImport_AddModule ("os"); main_dict=PyModule_GetDict(main_o); sys_dict=PyModule_GetDict(sys_o); os_dict=PyModule_GetDict(os_o); builtin_dict=PyModule_GetDict(builtin_o); PyDict_SetItemString (main_dict, "os", os_o); PyDict_SetItemString (main_dict, "sys", sys_o); /* sg module init */ init_sg_python(); sg_o=PyImport_AddModule("sg"); sg_dict=PyModule_GetDict(sg_o); PyDict_SetItemString (main_dict, "sg", sg_o); /* gtk.py requires this*/ full=PyList_New (1); string=PyString_FromString (progname); PyList_SET_ITEM (full, 0, string); PyDict_SetItemString (sys_dict, "argv",full); default_paths=PyDict_GetItemString (sys_dict, "path"); pickle=PyImport_ImportModule("pickle"); pickle=PyImport_AddModule("pickle"); PyDict_SetItemString (main_dict, "pickle", pickle); if (!pickle) return FALSE; return TRUE; } static gint pickle_config_file(gchar *fname, PyObject *globals, PyObject *locals) { gint i=0; FILE *fp; PyObject *object, *fo; gchar temp[200]; if (!(fp=fopen(fname,"w"))) return FALSE; fo=PyFile_FromFile (fp, "pickle_file", "w", NULL); PyDict_SetItemString (sg_dict, "pickle_file", fo); g_snprintf(temp,200,"pickler=pickle.Pickler(pickle_file)"); object=PyRun_String (temp, Py_file_input, globals, locals); if (python_error_report(object)) return FALSE; object=PyRun_String ("pickler.dump(sg.config)", Py_file_input, globals, locals); python_error_report(object); object=PyRun_String ("del pickle_file,pickler", Py_file_input, globals, locals); if (python_error_report(object)) return (FALSE); fclose(fp); return TRUE; } gint python_config_save(void) { gchar dir[] = ".scigraphica"; gchar file[] = "config"; gint size; gchar *rcdir,*rcfile; PyObject *config_dict; size = strlen(g_get_home_dir())+1 + strlen(dir)+1; rcdir = g_new(gchar,size); g_snprintf(rcdir,size,"%s/%s",g_get_home_dir(),dir); size = strlen(rcdir)+1 + strlen(file)+1; rcfile = g_new(gchar,size); g_snprintf(rcfile,size,"%s/%s",rcdir,file); if ( pickle_config_file(rcfile, main_dict, sg_dict) == FALSE ) {/* create scigraphica directory and try again */ gchar *create_dir; size = strlen(rcdir) + 10; create_dir = g_new(gchar,size); g_snprintf(create_dir,size,"mkdir -p %s",rcdir); system(create_dir); g_free(create_dir); pickle_config_file(rcfile, main_dict, sg_dict); } g_free(rcdir); g_free(rcfile); return (TRUE); } static gint init_modules(SGconfig *config){ gint i; PyObject *dict,*items; dict=PyDict_New(); for (i=0;comp_imports[i].name!=NULL;i++){ PyDict_SetItemString(dict,comp_imports[i].name, PyInt_FromLong ((long) comp_imports[i].flags)); } items=PyDict_Items(dict); sg_config_set_value(config->name, config->group, dict, FALSE); return TRUE; } static gint commit_modules(SGconfig *config){ PyObject *keys, *items, *key_name, *module_object,*object,*full,*string,*dict; int i=0; gint flag; gchar *name,temp[200]; dict=sg_config_get_value(config->name, config->group); full=PyList_New (1); string=PyString_FromString ("*"); PyList_SET_ITEM (full, 0, string); keys=PyDict_Keys(dict); for (i=0;iname, config->group, PyInt_FromLong ((long) sg_canvas_label_pos),FALSE); return TRUE; } static gint commit_canvas_labels_pos(SGconfig *config){ gint pos; pos=(gint)PyInt_AsLong(sg_config_get_value(config->name, config->group)); sg_canvas_label_pos=pos; gtk_icon_list_freeze(GTK_ICON_LIST(iconlist1)); gtk_icon_list_set_mode(GTK_ICON_LIST(iconlist1), pos + 1); gtk_icon_list_thaw(GTK_ICON_LIST(iconlist1)); gtk_icon_list_freeze(GTK_ICON_LIST(iconlist2)); gtk_icon_list_set_mode(GTK_ICON_LIST(iconlist2), pos + 1); gtk_icon_list_thaw(GTK_ICON_LIST(iconlist2)); return TRUE; } static gint init_canvas_labels_width(SGconfig *config){ sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_canvas_label_width),FALSE); return TRUE; } static gint commit_canvas_labels_width(SGconfig *config){ gint width; width=(gint)PyInt_AsLong(sg_config_get_value(config->name, config->group)); sg_canvas_label_width=width; gtk_icon_list_freeze(GTK_ICON_LIST(iconlist1)); gtk_icon_list_set_text_space(GTK_ICON_LIST(iconlist1), width); gtk_icon_list_thaw(GTK_ICON_LIST(iconlist1)); gtk_icon_list_freeze(GTK_ICON_LIST(iconlist2)); gtk_icon_list_set_text_space(GTK_ICON_LIST(iconlist2), width); gtk_icon_list_thaw(GTK_ICON_LIST(iconlist2)); return TRUE; } static gint init_show_plot_toolbar(SGconfig *config){ sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_show_plot_toolbar),FALSE); return TRUE; } static gint commit_show_plot_toolbar(SGconfig *config){ gint show; GList *list; SGplot *plot; show=(gint)PyInt_AsLong(sg_config_get_value(config->name, config->group)); sg_show_plot_toolbar=show; list=plots; while (list) { plot=(SGplot *)list->data; if (show==TRUE) gtk_widget_show_all(plot->toolbox); else gtk_widget_hide(plot->toolbox); list=list->next; } return TRUE; } static gint init_show_plot_menubar(SGconfig *config){ sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_show_plot_menubar),FALSE); return TRUE; } static gint commit_show_plot_menubar(SGconfig *config){ gint show; SGplot *plot; GList *plotlist; show=(gint)PyInt_AsLong(sg_config_get_value(config->name, config->group)); sg_show_plot_menubar=show; plotlist=plots; while (plotlist) { plot=(SGplot *)plotlist->data; sg_plot_show_top_toolbar(plot); plotlist=plotlist->next; } return TRUE; } static gint init_save_interval(SGconfig *config){ sg_config_set_value(config->name, config->group, PyInt_FromLong((long)sg_autosave_interval),FALSE); return TRUE; } static gint commit_save_interval(SGconfig *config){ PyObject *value; value=sg_config_get_value(config->name, config->group); sg_autosave_interval=(gint)PyInt_AsLong(value); sg_project_autosave_set(sg_autosave_interval); return TRUE; } static gint init_compress_level(SGconfig *config){ sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_compress_level),FALSE); return TRUE; } static gint commit_compress_level(SGconfig *config){ PyObject *value; value=sg_config_get_value(config->name, config->group); sg_compress_level=(gint)PyInt_AsLong(value); return TRUE; } static gint init_autoscale(SGconfig *config){ if (!strcmp(config->name,"autoscale_left")) sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_autoscale_left),FALSE); else if (!strcmp(config->name,"autoscale_right")) sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_autoscale_right),FALSE); if (!strcmp(config->name,"autoscale_top")) sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_autoscale_top),FALSE); else if (!strcmp(config->name,"autoscale_bottom")) sg_config_set_value(config->name, config->group, PyInt_FromLong ((long) sg_autoscale_bottom),FALSE); else return FALSE; return TRUE; } static gint commit_autoscale(SGconfig *config){ PyObject *value; value=sg_config_get_value(config->name, config->group); if (!strcmp(config->name,"autoscale_left")) sg_autoscale_left=(gint)PyInt_AsLong(value); else if (!strcmp(config->name,"autoscale_right")) sg_autoscale_right=(gint)PyInt_AsLong(value); else if (!strcmp(config->name,"autoscale_top")) sg_autoscale_top=(gint)PyInt_AsLong(value); else if (!strcmp(config->name,"autoscale_bottom")) sg_autoscale_bottom=(gint)PyInt_AsLong(value); else return FALSE; return TRUE; } static gint init_module_paths(SGconfig *config){ int j; PyObject *items; items=PyDict_New(); for (j=0;jname, config->group, items,FALSE); return TRUE; } static gint commit_module_paths(SGconfig *config){ PyObject *value; value=sg_config_get_value(config->name, config->group); PyDict_SetItemString (sys_dict, "path", PyDict_Keys(value)); return TRUE; } static gint unpickle_config_file(gchar *fname, PyObject *globals, PyObject *locals) { gint i=0; FILE *fp; PyObject *object, *fo, *dict; gchar temp[200]; if (!(fp=fopen(fname,"r"))) return FALSE; fo=PyFile_FromFile (fp, "pickle_file", "r", NULL); PyDict_SetItemString (sg_dict, "pickle_file", fo); g_snprintf(temp,200,"unpickler=pickle.Unpickler(pickle_file)"); object=PyRun_String (temp, Py_file_input, globals, locals); if (!object){ python_error_report_verbose(object,FALSE,"Cannot load preferences - Restoring defaults.\n\n" "View verbose error log?",1); Py_XDECREF(object); fclose(fp); Py_XDECREF(fo); return 0; } g_snprintf(temp,200,"sg.config=unpickler.load()"); object=PyRun_String (temp, Py_file_input, globals, locals); if (!object){ python_error_report_verbose(object,FALSE,"Cannot load preferences - Restoring defaults.\n\n" "View verbose error log?",1); Py_XDECREF(object); fclose(fp); Py_XDECREF(fo); return 0; } g_snprintf(temp,200,"del pickle_file,unpickler"); object=PyRun_String (temp, Py_file_input, globals, locals); sg_config_dict=PyDict_GetItemString(sg_dict,"config"); fclose(fp); Py_XDECREF(object); Py_XDECREF(fo); if (dict) return 1; else return 0; } gint python_config_init(void) { gchar dir[] = ".scigraphica"; gchar file[] = "config"; gchar *rcdir,*rcfile; gint size; PyObject *config_dict; size = strlen(g_get_home_dir())+1 + strlen(dir)+1; rcdir = g_new(gchar,size); g_snprintf(rcdir,size,"%s/%s",g_get_home_dir(),dir); size = strlen(rcdir)+1 + strlen(file)+1; rcfile=g_new(gchar,size); g_snprintf(rcfile,size,"%s/%s",rcdir,file); if ( unpickle_config_file(rcfile, main_dict, sg_dict) == FALSE ) {/* create scigraphica directory and try again */ gchar *create_dir; size = strlen(rcdir) + 10; create_dir=g_new(gchar,size); g_snprintf(create_dir,size,"mkdir -p %s", rcdir); system(create_dir); g_free(create_dir); /* try again */ unpickle_config_file(rcfile, main_dict, sg_dict); } g_free(rcdir); g_free(rcfile); sg_config_init(); sg_config_new_c("startup", "module", init_modules, commit_modules); sg_config_new_c("path", "module", init_module_paths, commit_module_paths); sg_config_new_c("label_width", "maingui", init_canvas_labels_width, commit_canvas_labels_width); sg_config_new_c("label_pos", "maingui", init_canvas_labels_pos, commit_canvas_labels_pos); sg_config_new_c("save_interval", "file", init_save_interval, commit_save_interval); sg_config_new_c("compress_level", "file", init_compress_level, commit_compress_level); sg_config_new_c("autoscale_left", "plotgui", init_autoscale, commit_autoscale); sg_config_new_c("autoscale_right", "plotgui", init_autoscale, commit_autoscale); sg_config_new_c("autoscale_top", "plotgui", init_autoscale, commit_autoscale); sg_config_new_c("autoscale_bottom", "plotgui", init_autoscale, commit_autoscale); sg_config_new_c("show_toolbar", "plotgui", init_show_plot_toolbar, commit_show_plot_toolbar); sg_config_new_c("show_menubar", "plotgui", init_show_plot_menubar, commit_show_plot_menubar); /* Make sure the standard modules are loaded */ sg_config_exec_commit(sg_config_get_config("path", "module")); return (TRUE); } gint python_error_report(PyObject *object) { if (!object) { if (sg_report_python_error) create_python_term(NULL,NULL); PyErr_Print(); if (Py_FlushLine()) PyErr_Clear(); return TRUE; } return FALSE; } gint python_error_report_verbose(PyObject *object,gboolean report, gchar *message, gint type){ if (!object){ if (report|| sg_accept_dialog(message,type)==YES_CLICKED){ create_python_term(NULL,NULL); PyErr_Print(); } if (Py_FlushLine()) PyErr_Clear(); return TRUE; } return FALSE; }