Logo Search packages:      
Sourcecode: scigraphica version File versions  Download package

python_int.c

/* This is the interface to the python interpreter
   Originally from the now defunct gnocci project.
   C. Steenberg 15 May 2000
*/

#include <stdio.h>
#include <string.h>

#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkkeysyms.h>
#include <gtkextra/gtkextra.h>

#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;i<PyList_GET_SIZE (keys);i++)
    { gchar *name;
      gint flag;
      PyObject *pflag;
      key_name=PyList_GetItem (keys,i);
      name=PyString_AsString (key_name);
      
      flag=(gint)PyInt_AsLong(PyDict_GetItemString (dict,name));
      module_object=PyImport_ImportModuleEx (name, main_dict, sg_dict, full);

      /*python_error_report(module_object);*/
      if (!module_object) {
          
          snprintf(temp,200,"Couldn't import module '%s'\nView verbose error log?",name);
          python_error_report_verbose(module_object,FALSE,temp,1);
          continue;
      }
      
      Py_INCREF(module_object);

      if (flag&SG_MODULE_LOAD_SYMBOLS){
          g_snprintf(temp,200,"from %s import *",name);
          object=PyRun_String (temp, Py_single_input, main_dict, sg_dict);
          python_error_report(object);
          if (module_object)
            PyDict_SetItemString (main_dict, name, module_object);
      }
      else if (comp_imports[i].flags&SG_MODULE_LOAD_MAIN && module_object){
          PyDict_SetItemString (main_dict, name, module_object);
      }
    }
    Py_XDECREF(full);
    return i;
}

static gint init_canvas_labels_pos(SGconfig *config){
  sg_config_set_value(config->name, 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;j<PyList_GET_SIZE (default_paths);j++){
       PyDict_SetItem(items, PyList_GetItem (default_paths,j),Py_None);
     }
     if (!PyDict_GetItemString(items, PYTHON_MODULE_PATH))
         PyDict_SetItemString(items, PYTHON_MODULE_PATH,Py_None);
     sg_config_set_value(config->name, 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;
}


Generated by  Doxygen 1.6.0   Back to index