static gboolean gplp_func_desc_load (GOPluginService *service, char const *name, GnmFuncDescriptor *res) { ServiceLoaderDataFunctionGroup *loader_data; PyObject *fn_info_obj; g_return_val_if_fail (GNM_IS_PLUGIN_SERVICE_FUNCTION_GROUP (service), FALSE); g_return_val_if_fail (name != NULL, FALSE); loader_data = g_object_get_data (G_OBJECT (service), "loader_data"); SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service)); fn_info_obj = PyDict_GetItemString (loader_data->python_fn_info_dict, (gchar *) name); if (fn_info_obj == NULL) { gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); return FALSE; } if (PyTuple_Check (fn_info_obj)) { PyObject *python_args; PyObject *python_fn; if (PyTuple_Size (fn_info_obj) == 3 && (python_args = PyTuple_GetItem (fn_info_obj, 0)) != NULL && PyString_Check (python_args) && (python_fn = PyTuple_GetItem (fn_info_obj, 2)) != NULL && PyCallable_Check (python_fn)) { res->arg_spec = PyString_AsString (python_args); res->help = python_function_get_gnumeric_help ( loader_data->python_fn_info_dict, python_fn, name); res->fn_args = &call_python_function_args; res->fn_nodes = NULL; res->linker = NULL; res->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC; res->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN; return TRUE; } gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); return FALSE; } if (PyCallable_Check (fn_info_obj)) { res->arg_spec = ""; res->help = python_function_get_gnumeric_help ( loader_data->python_fn_info_dict, fn_info_obj, name); res->fn_args = NULL; res->fn_nodes = &call_python_function_nodes; res->linker = NULL; res->impl_status = GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC; res->test_status = GNM_FUNC_TEST_STATUS_UNKNOWN; return TRUE; } gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); return FALSE; }
static void gplp_load_service_file_opener (GOPluginLoader *loader, GOPluginService *service, GOErrorInfo **ret_error) { printf("gplp_load_service_file_opener(start)\n"); GnmPythonPluginLoader *loader_python = GNM_PYTHON_PLUGIN_LOADER (loader); gchar *func_name_file_probe, *func_name_file_open; PyObject *python_func_file_probe, *python_func_file_open; g_return_if_fail (GO_IS_PLUGIN_SERVICE_FILE_OPENER (service)); GO_INIT_RET_ERROR_INFO (ret_error); gnm_py_interpreter_switch_to (loader_python->py_interpreter_info); gnm_py_interpreter_load(loader_python->py_interpreter_info); func_name_file_probe = g_strconcat ( go_plugin_service_get_id (service), "_file_probe", NULL); python_func_file_probe = PyDict_GetItemString (loader_python->main_module_dict, func_name_file_probe); gnm_python_clear_error_if_needed (loader_python->py_object); func_name_file_open = g_strconcat ( go_plugin_service_get_id (service), "_file_open", NULL); python_func_file_open = PyDict_GetItemString (loader_python->main_module_dict, func_name_file_open); gnm_python_clear_error_if_needed (loader_python->py_object); if (python_func_file_open != NULL) { GOPluginServiceFileOpenerCallbacks *cbs; ServiceLoaderDataFileOpener *loader_data; cbs = go_plugin_service_get_cbs (service); cbs->plugin_func_file_probe = gplp_func_file_probe; cbs->plugin_func_file_open = gplp_func_file_open; loader_data = g_new (ServiceLoaderDataFileOpener, 1); loader_data->python_func_file_probe = python_func_file_probe; loader_data->python_func_file_open = python_func_file_open; if (python_func_file_probe != NULL) Py_INCREF (loader_data->python_func_file_probe); Py_INCREF (loader_data->python_func_file_open); g_object_set_data_full (G_OBJECT (service), "loader_data", loader_data, (GDestroyNotify) gplp_loader_data_opener_free); } else { *ret_error = go_error_info_new_printf ( _("Python file \"%s\" has invalid format."), loader_python->module_name); go_error_info_add_details (*ret_error, go_error_info_new_printf ( _("File doesn't contain \"%s\" function."), func_name_file_open)); } g_free (func_name_file_probe); g_free (func_name_file_open); gnm_py_interpreter_save(loader_python->py_interpreter_info); }
static void gplp_func_file_save (G_GNUC_UNUSED GOFileSaver const *fs, GOPluginService *service, GOIOContext *io_context, gconstpointer wb_view, GsfOutput *output) { ServiceLoaderDataFileSaver *saver_data; PyObject *py_workbook; PyObject *save_result = NULL; PyObject *output_wrapper; g_return_if_fail (GO_IS_PLUGIN_SERVICE_FILE_SAVER (service)); g_return_if_fail (output != NULL); g_return_if_fail (_PyGObject_API != NULL); saver_data = g_object_get_data (G_OBJECT (service), "loader_data"); SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service)); py_workbook = py_new_Workbook_object (wb_view_get_workbook (wb_view)); output_wrapper = pygobject_new (G_OBJECT (output)); if (output_wrapper != NULL) { /* wrapping adds a reference */ g_object_unref (output); save_result = PyObject_CallFunction (saver_data->python_func_file_save, (char *) "NO", py_workbook, output_wrapper); Py_DECREF (output_wrapper); } if (save_result != NULL) { Py_DECREF (save_result); } else { go_io_error_string (io_context, py_exc_to_string ()); gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); } }
static void gplp_load_service_function_group (GOPluginLoader *loader, GOPluginService *service, GOErrorInfo **ret_error) { printf("gplp_load_service_function_group(start)\n"); GnmPythonPluginLoader *loader_python = GNM_PYTHON_PLUGIN_LOADER (loader); gchar *fn_info_dict_name; PyObject *python_fn_info_dict; g_return_if_fail (IS_GNM_PLUGIN_SERVICE_FUNCTION_GROUP (service)); GO_INIT_RET_ERROR_INFO (ret_error); gnm_py_interpreter_switch_to (loader_python->py_interpreter_info); gnm_py_interpreter_load(loader_python->py_interpreter_info); fn_info_dict_name = g_strconcat ( go_plugin_service_get_id (service), "_functions", NULL); python_fn_info_dict = PyDict_GetItemString (loader_python->main_module_dict, fn_info_dict_name); gnm_python_clear_error_if_needed (loader_python->py_object); if (python_fn_info_dict != NULL && PyDict_Check (python_fn_info_dict)) { PluginServiceFunctionGroupCallbacks *cbs; ServiceLoaderDataFunctionGroup *loader_data; cbs = go_plugin_service_get_cbs (service); cbs->func_desc_load = &gplp_func_desc_load; loader_data = g_new (ServiceLoaderDataFunctionGroup, 1); loader_data->python_fn_info_dict = (PyObject *) python_fn_info_dict; Py_INCREF (loader_data->python_fn_info_dict); g_object_set_data_full (G_OBJECT (service), "loader_data", loader_data, (GDestroyNotify) gplp_loader_data_fngroup_free); } else { *ret_error = go_error_info_new_printf ( _("Python file \"%s\" has invalid format."), loader_python->module_name); if (python_fn_info_dict == NULL) { go_error_info_add_details (*ret_error, go_error_info_new_printf ( _("File doesn't contain \"%s\" dictionary."), fn_info_dict_name)); } else if (!PyDict_Check (python_fn_info_dict)) { go_error_info_add_details (*ret_error, go_error_info_new_printf ( _("Object \"%s\" is not a dictionary."), fn_info_dict_name)); } } g_free (fn_info_dict_name); gnm_py_interpreter_save(loader_python->py_interpreter_info); printf("gplp_load_service_function_group(end)\n"); }
static void gplp_load_service_ui (GOPluginLoader *loader, GOPluginService *service, GOErrorInfo **ret_error) { GnmPythonPluginLoader *loader_python = GNM_PYTHON_PLUGIN_LOADER (loader); gchar *ui_action_names; PyObject *ui_actions; g_return_if_fail (IS_GNM_PLUGIN_SERVICE_UI (service)); GO_INIT_RET_ERROR_INFO (ret_error); gnm_py_interpreter_switch_to (loader_python->py_interpreter_info); gnm_py_interpreter_load(loader_python->py_interpreter_info); ui_action_names = g_strconcat (go_plugin_service_get_id (service), "_ui_actions", NULL); ui_actions = PyDict_GetItemString (loader_python->main_module_dict, ui_action_names); gnm_python_clear_error_if_needed (loader_python->py_object); if (ui_actions != NULL && PyDict_Check (ui_actions)) { PluginServiceUICallbacks *cbs; ServiceLoaderDataUI *loader_data; cbs = go_plugin_service_get_cbs (service); cbs->plugin_func_exec_action = gplp_func_exec_action; loader_data = g_new (ServiceLoaderDataUI, 1); loader_data->ui_actions = ui_actions; Py_INCREF (loader_data->ui_actions); g_object_set_data_full (G_OBJECT (service), "loader_data", loader_data, (GDestroyNotify) gplp_loader_data_ui_free); } else { *ret_error = go_error_info_new_printf ( _("Python file \"%s\" has invalid format."), loader_python->module_name); if (ui_actions == NULL) { go_error_info_add_details (*ret_error, go_error_info_new_printf ( _("File doesn't contain \"%s\" dictionary."), ui_action_names)); } else if (!PyDict_Check (ui_actions)) { go_error_info_add_details (*ret_error, go_error_info_new_printf ( _("Object \"%s\" is not a dictionary."), ui_action_names)); } } g_free (ui_action_names); gnm_py_interpreter_save(loader_python->py_interpreter_info); }
static void gplp_func_file_open (GOFileOpener const *fo, GOPluginService *service, GOIOContext *io_context, gpointer wb_view, GsfInput *input) { ServiceLoaderDataFileOpener *loader_data; Sheet *sheet, *old_sheet; PyObject *open_result = NULL; PyObject *input_wrapper; printf("gplp_func_file_open(start)\n"); g_return_if_fail (GO_IS_PLUGIN_SERVICE_FILE_OPENER (service)); g_return_if_fail (input != NULL); g_return_if_fail (_PyGObject_API != NULL); old_sheet = wb_view_cur_sheet (wb_view); loader_data = g_object_get_data (G_OBJECT (service), "loader_data"); SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service)); sheet = sheet_new (wb_view_get_workbook (wb_view), _("Some name"), gnm_sheet_get_max_cols (old_sheet), gnm_sheet_get_max_rows (old_sheet)); input_wrapper = pygobject_new (G_OBJECT (input)); if (input_wrapper != NULL) { /* wrapping adds a reference */ g_object_unref (G_OBJECT (input)); open_result = PyObject_CallFunction (loader_data->python_func_file_open, (char *) "NO", py_new_Sheet_object (sheet), input_wrapper); Py_DECREF (input_wrapper); } if (open_result != NULL) { Py_DECREF (open_result); workbook_sheet_attach (wb_view_get_workbook (wb_view), sheet); } else { go_io_error_string (io_context, py_exc_to_string ()); gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); g_object_unref (sheet); } printf("gplp_func_file_open(end)\n"); }
static gboolean gplp_func_file_probe (GOFileOpener const *fo, GOPluginService *service, GsfInput *input, GOFileProbeLevel pl) { ServiceLoaderDataFileOpener *loader_data; PyObject *probe_result = NULL; PyObject *input_wrapper; gboolean result; printf("gplp_func_file_probe(start)\n"); g_return_val_if_fail (GO_IS_PLUGIN_SERVICE_FILE_OPENER (service), FALSE); g_return_val_if_fail (input != NULL, FALSE); g_return_val_if_fail (_PyGObject_API != NULL, FALSE); loader_data = g_object_get_data (G_OBJECT (service), "loader_data"); SWITCH_TO_PLUGIN (go_plugin_service_get_plugin (service)); input_wrapper = pygobject_new (G_OBJECT (input)); if (input_wrapper == NULL) { g_warning ("%s", py_exc_to_string ()); gnm_python_clear_error_if_needed (SERVICE_GET_LOADER (service)->py_object); } if (input_wrapper != NULL && loader_data->python_func_file_probe != NULL) { /* wrapping adds a reference */ g_object_unref (G_OBJECT (input)); probe_result = PyObject_CallFunction (loader_data->python_func_file_probe, (char *) "O", input_wrapper); Py_DECREF (input_wrapper); } if (probe_result != NULL) { result = PyObject_IsTrue (probe_result); Py_DECREF (probe_result); } else { PyErr_Clear (); result = FALSE; } printf("gplp_func_file_probe(end)\n"); return result; }
static void gplp_load_base (GOPluginLoader *loader, GOErrorInfo **ret_error) { static gchar const *python_file_extensions[] = {"py", "pyc", "pyo", NULL}; GnmPythonPluginLoader *loader_python = GNM_PYTHON_PLUGIN_LOADER (loader); gchar const **file_ext; GnmPython *py_object; GnmPyInterpreter *py_interpreter_info; gchar *full_module_file_name = NULL; FILE *f; GOPlugin *plugin = go_plugin_loader_get_plugin (loader); GOErrorInfo *open_error = NULL; PyObject *modules, *main_module, *main_module_dict; GO_INIT_RET_ERROR_INFO (ret_error); g_object_set_data (G_OBJECT (plugin), "python-loader", loader); py_object = gnm_python_object_get (ret_error); if (py_object == NULL) return; /* gnm_python_object_get sets ret_error */ py_interpreter_info = gnm_python_new_interpreter (py_object, plugin); if (py_interpreter_info == NULL) { *ret_error = go_error_info_new_str (_("Cannot create new Python interpreter.")); gnm_python_clear_error_if_needed (py_object); g_object_unref (py_object); return; } for (file_ext = python_file_extensions; *file_ext != NULL; file_ext++) { gchar *file_name = g_strconcat ( loader_python->module_name, ".", *file_ext, NULL); gchar *path = g_build_filename ( go_plugin_get_dir_name (plugin), file_name, NULL); g_free (file_name); if (g_file_test (path, G_FILE_TEST_EXISTS)) { full_module_file_name = path; break; } else g_free (path); } if (full_module_file_name == NULL) { *ret_error = go_error_info_new_printf ( _("Module \"%s\" doesn't exist."), loader_python->module_name); gnm_python_destroy_interpreter (py_object, py_interpreter_info); g_object_unref (py_object); return; } f = gnumeric_fopen_error_info (full_module_file_name, "r", &open_error); g_free (full_module_file_name); if (f == NULL) { *ret_error = open_error; gnm_python_destroy_interpreter (py_object, py_interpreter_info); g_object_unref (py_object); return; } if (PyRun_SimpleFile (f, loader_python->module_name) != 0) { (void) fclose (f); *ret_error = go_error_info_new_printf ( _("Execution of module \"%s\" failed."), loader_python->module_name); gnm_python_destroy_interpreter (py_object, py_interpreter_info); g_object_unref (py_object); return; } (void) fclose (f); modules = PyImport_GetModuleDict (); g_return_if_fail (modules != NULL); main_module = PyDict_GetItemString (modules, (char *) "__main__"); g_return_if_fail (main_module != NULL); main_module_dict = PyModule_GetDict (main_module); g_return_if_fail (main_module_dict != NULL); loader_python->py_object = py_object; loader_python->py_interpreter_info = py_interpreter_info; loader_python->main_module = main_module; loader_python->main_module_dict = main_module_dict; }