From 8e8f37d5d37a3530a97d7b81f59f71a0710fb383 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 14 Oct 2008 02:34:28 +0000 Subject: [PATCH] Create a new plugin class for Import plugins. svn: r11142 --- po/POTFILES.in | 2 + src/DbLoader.py | 28 ++++---- src/GrampsDbUtils/_GrampsDbWRFactories.py | 8 +-- src/gen/db/dbconst.py | 1 - src/gen/plug/Makefile.am | 4 +- src/gen/plug/__init__.py | 5 +- src/gen/plug/_import.py | 81 +++++++++++++++++++++++ src/gen/plug/_manager.py | 47 +++++++------ src/gen/plug/_plugin.py | 67 +++++++++++++++++++ src/plugins/ImportCSV.py | 21 ++---- src/plugins/ImportGeneWeb.py | 23 ++----- src/plugins/ImportProGen.py | 25 +++---- src/plugins/ImportvCard.py | 24 ++----- src/plugins/ReadGrdb.py | 22 ++---- src/plugins/ReadPkg.py | 21 ++---- 15 files changed, 242 insertions(+), 137 deletions(-) create mode 100644 src/gen/plug/_import.py create mode 100644 src/gen/plug/_plugin.py diff --git a/po/POTFILES.in b/po/POTFILES.in index 06768bdd0..8f031516c 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -340,7 +340,9 @@ src/PluginUtils/_Tool.py src/gen/utils/dbutils.py src/gen/utils/progressmon.py src/gen/plug/__init__.py +src/gen/plug/_import.py src/gen/plug/_manager.py +src/gen/plug/_plugin.py src/gen/plug/menu/_boolean.py src/gen/plug/menu/_color.py src/gen/plug/menu/_destination.py diff --git a/src/DbLoader.py b/src/DbLoader.py index eda80f028..4f302e205 100644 --- a/src/DbLoader.py +++ b/src/DbLoader.py @@ -126,16 +126,17 @@ class DbLoader: format_list = OPEN_FORMATS[:] # Add more data type selections if opening existing db - for data in pmgr.get_import_list(): - mime_filter = data[1] - mime_types = data[2] - native_format = data[3] - format_name = data[4] + for plugin in pmgr.get_import_plugins(): + mime_types = plugin.get_mime_types() + mime_filter = gtk.FileFilter() + mime_filter.set_name(plugin.get_name()) + for mime_type in mime_types: + mime_filter.add_mime_type(mime_type) + format_name = plugin.get_name() - if not native_format: - choose_db_dialog.add_filter(mime_filter) - format_list.append(mime_types[0]) - _KNOWN_FORMATS[mime_types[0]] = [format_name, mime_types[1:]] + choose_db_dialog.add_filter(mime_filter) + format_list.append(mime_types[0]) + _KNOWN_FORMATS[mime_types[0]] = [format_name, mime_types[1:]] (box, type_selector) = format_maker(format_list) choose_db_dialog.set_extra_widget(box) @@ -180,10 +181,11 @@ class DbLoader: (the_path, the_file) = os.path.split(filename) Config.set(Config.RECENT_IMPORT_DIR, the_path) # Then we try all the known plugins - for (importData, mime_filter, mime_types, native_format, - format_name) in pmgr.get_import_list(): - if filetype in mime_types: - self.do_import(choose_db_dialog, importData, filename) + for plugin in pmgr.get_import_plugins(): + if filetype in plugin.get_mime(): + self.do_import(choose_db_dialog, + plugin.get_import_function(), + filename) return True # Finally, we give up and declare this an unknown format diff --git a/src/GrampsDbUtils/_GrampsDbWRFactories.py b/src/GrampsDbUtils/_GrampsDbWRFactories.py index d75395ed3..0de9e4578 100644 --- a/src/GrampsDbUtils/_GrampsDbWRFactories.py +++ b/src/GrampsDbUtils/_GrampsDbWRFactories.py @@ -67,11 +67,11 @@ def gramps_db_reader_factory(db_type): #see if registered importer found = False pmgr = PluginManager.get_instance() - for data in pmgr.get_import_list(): - if db_type in data[2]: - print "Found import plugin for %s" % data[4] + for plugin in pmgr.get_import_plugins(): + if db_type in plugin.get_mime_types(): + print "Found import plugin for %s" % plugin.get_name() found = True - md = data[0] + md = plugin.get_import_function() break if not found: raise GrampsDbException("Attempt to create a database " diff --git a/src/gen/db/dbconst.py b/src/gen/db/dbconst.py index 82c2b0e05..6b4649171 100644 --- a/src/gen/db/dbconst.py +++ b/src/gen/db/dbconst.py @@ -36,7 +36,6 @@ APP_GRAMPS_XML = "application/x-gramps-xml" APP_GEDCOM = "application/x-gedcom" APP_GRAMPS_PKG = "application/x-gramps-package" APP_GENEWEB = "application/x-geneweb" -APP_VCARD = ["text/x-vcard", "text/x-vcalendar"] PERSON_KEY = 0 FAMILY_KEY = 1 diff --git a/src/gen/plug/Makefile.am b/src/gen/plug/Makefile.am index 0af654c19..37dd7fe58 100644 --- a/src/gen/plug/Makefile.am +++ b/src/gen/plug/Makefile.am @@ -10,7 +10,9 @@ pkgdatadir = $(datadir)/@PACKAGE@/gen/plug pkgdata_PYTHON = \ __init__.py \ - _manager.py + _import.py \ + _manager.py \ + _plugin.py pkgpyexecdir = @pkgpyexecdir@/gen/plug pkgpythondir = @pkgpythondir@/gen/plug diff --git a/src/gen/plug/__init__.py b/src/gen/plug/__init__.py index 77a8b9970..b8db1da02 100644 --- a/src/gen/plug/__init__.py +++ b/src/gen/plug/__init__.py @@ -21,7 +21,8 @@ The "plug" package for handling plugins in Gramps. """ -__all__ = [ "opt" ] - +from _plugin import Plugin from _manager import PluginManager +from _import import ImportPlugin +__all__ = [ "menu", Plugin, PluginManager, ImportPlugin ] diff --git a/src/gen/plug/_import.py b/src/gen/plug/_import.py new file mode 100644 index 000000000..dfd7b2a1a --- /dev/null +++ b/src/gen/plug/_import.py @@ -0,0 +1,81 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2008 Brian G. Matherly +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +""" +This module provides the Plugin class for import plugins. +""" + +from gen.plug import Plugin + +class ImportPlugin(Plugin): + """ + This class represents a plugin for importing data into Gramps + """ + def __init__(self, name, description, import_function, mime_types=None): + """ + @param name: A friendly name to call this plugin. + Example: "GEDCOM Import" + @type name: string + @param description: An short description of the plugin. + Example: "This plugin will import a GEDCOM file into a database" + @type description: string + @param import_function: A function to call to perform the import. + The function must take the form: + def import_function(db, filename, callback): + where: + "db" is a Gramps database to import the data into + "filename" is the file that contains data to be imported + "callback" is a callable object that takes two parameters. + The first parameter is a progress indicator. + The second parameter is a text string. + @type import_function: callable + @param mime_types: A list of mime types that apply to the file type. + Example: "['application/x-gramps']" + @type mime_types: [str] (list of strings) + @return: nothing + """ + Plugin.__init__(self, name, description) + self.__import_func = import_function + self.__mime_types = mime_types + + def get_module_name(self): + """ + Get the name of the module that this plugin lives in. + + @return: a string representing the name of the module for this plugin + """ + return self.__import_func.__module__ + + def get_import_function(self): + """ + Get the import function for this plugins. + + @return: the callable import_function passed into __init__ + """ + return self.__import_func + + def get_mime_types(self): + """ + Get the list of mime types that apply to the import file. + + @return: [str] (list of strings) + """ + return self.__mime_types diff --git a/src/gen/plug/_manager.py b/src/gen/plug/_manager.py index ad8f50504..8c36509e8 100644 --- a/src/gen/plug/_manager.py +++ b/src/gen/plug/_manager.py @@ -52,7 +52,7 @@ import Relationship # Constants # #------------------------------------------------------------------------- -_UNAVAILABLE = _("No description was provided"), +_UNAVAILABLE = _("No description was provided") #------------------------------------------------------------------------- # @@ -71,7 +71,7 @@ class PluginManager(gen.utils.Callback): REPORT_MODE_CLI = 4 # Command line interface (CLI) # Modes for running tools - TOOL_MODE_GUI = 1 # Standrt tool using GUI + TOOL_MODE_GUI = 1 # Standard tool using GUI TOOL_MODE_CLI = 2 # Command line interface (CLI) def get_instance(): @@ -93,8 +93,8 @@ class PluginManager(gen.utils.Callback): self.__report_list = [] self.__quick_report_list = [] self.__tool_list = [] - self.__import_list = [] self.__export_list = [] + self.__import_plugins = [] self.__attempt_list = [] self.__loaddir_list = [] self.__textdoc_list = [] @@ -257,10 +257,6 @@ class PluginManager(gen.utils.Callback): """ Return the list of command line tool plugins. """ return self.__cli_tool_list - def get_import_list(self): - """ Return the list of import plugins. """ - return self.__import_list - def get_export_list(self): """ Return the list of export plugins. """ return self.__export_list @@ -268,6 +264,24 @@ class PluginManager(gen.utils.Callback): def get_module_description(self, module): """ Given a module name, return the module description. """ return self.__mod2text.get(module, '') + + def register_plugin(self, plugin): + """ + @param plugin: The plugin to be registered. + @type plugin: gen.plug.Plugin + @return: nothing + """ + if isinstance(plugin, gen.plug.ImportPlugin): + self.__import_plugins.append(plugin) + self.__mod2text[plugin.get_module_name()] = plugin.get_description() + + def get_import_plugins(self): + """ + Get the list of import plugins. + + @return: [gen.plug.ImportPlugin] (a list of ImportPlugin instances) + """ + return self.__import_plugins def register_export(self, export_data, title, description='', config=None, filename=''): @@ -287,21 +301,6 @@ class PluginManager(gen.utils.Callback): (export_data, title, description, config, filename)) self.__mod2text[export_data.__module__] = description - def register_import(self, task, ffilter, mime=None, native_format=0, - format_name=""): - """Register an import filter, taking the task and file filter""" - if mime: - del_index = -1 - for i in range(0, len(self.__import_list)): - if self.__import_list[i][2] == mime: - del_index = i - if del_index != -1: - del self.__import_list[del_index] - - self.__import_list.append( - (task, ffilter, mime, native_format, format_name)) - self.__mod2text[task.__module__] = format_name - def register_tool(self, name, category, tool_class, options_class, modes, translated_name, status=_("Unknown"), description=_UNAVAILABLE, author_name=_("Unknown"), @@ -548,8 +547,8 @@ class PluginManager(gen.utils.Callback): self.__export_list[:] = [ item for item in self.__export_list if item[0].__module__ not in failed_module_names ][:] - self.__import_list[:] = [ item for item in self.__import_list - if item[0].__module__ not in failed_module_names ][:] + self.__import_plugins[:] = [ item for item in self.__import_plugins + if item.get_module_name not in failed_module_names ][:] self.__tool_list[:] = [ item for item in self.__tool_list if item[0].__module__ not in failed_module_names ][:] self.__cli_tool_list[:] = [ item for item in self.__cli_tool_list diff --git a/src/gen/plug/_plugin.py b/src/gen/plug/_plugin.py new file mode 100644 index 000000000..fd87bf427 --- /dev/null +++ b/src/gen/plug/_plugin.py @@ -0,0 +1,67 @@ +# +# Gramps - a GTK+/GNOME based genealogy program +# +# Copyright (C) 2008 Brian G. Matherly +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# $Id$ + +""" +This module provides the base class for plugins. +""" + +class Plugin: + """ + This class serves as a base class for all plugins that can be registered + with the plugin manager + """ + def __init__(self, name, description): + """ + @param name: A friendly name to call this plugin. + Example: "GEDCOM Import" + @type name: string + @param description: An short description of the plugin. + Example: "This plugin will import a GEDCOM file into a database" + @type description: string + @return: nothing + """ + self.__name = name + self.__desc = description + + def get_name(self): + """ + Get the name of this plugin. + + @return: a string representing the name of the plugin + """ + return self.__name + + def get_description(self): + """ + Get the description of this plugin. + + @return: a string that describes the plugin + """ + return self.__desc + + def get_module_name(self): + """ + Get the name of the module that this plugin lives in. + + @return: a string representing the name of the module for this plugin + """ + raise NotImplementedError + \ No newline at end of file diff --git a/src/plugins/ImportCSV.py b/src/plugins/ImportCSV.py index 866e47409..980daf7b8 100644 --- a/src/plugins/ImportCSV.py +++ b/src/plugins/ImportCSV.py @@ -43,13 +43,6 @@ import cStringIO import logging log = logging.getLogger(".ImportCSV") -#------------------------------------------------------------------------- -# -# GTK/GNOME Modules -# -#------------------------------------------------------------------------- -import gtk - #------------------------------------------------------------------------- # # GRAMPS modules @@ -58,7 +51,7 @@ import gtk import gen.lib from QuestionDialog import ErrorDialog from DateHandler import parser as _dp -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin from Utils import gender as gender_map from Utils import ProgressMeter @@ -798,12 +791,10 @@ class CSVParser: #------------------------------------------------------------------------- _mime_type = "text/x-comma-separated-values" # CSV Document _mime_type_rfc_4180 = "text/csv" # CSV Document See rfc4180 for mime type -_filter = gtk.FileFilter() -_filter.set_name(_('CSV spreadsheet files')) -_filter.add_mime_type(_mime_type) -_filter.add_mime_type(_mime_type_rfc_4180) -_format_name = _('CSV Spreadheet') pmgr = PluginManager.get_instance() -pmgr.register_import(importData, _filter, [_mime_type, _mime_type_rfc_4180], - 0, _format_name) +plugin = ImportPlugin(name = _('CSV Spreadheet'), + description = _("Import data from CSV files"), + import_function = importData, + mime_types = [_mime_type, _mime_type_rfc_4180]) +pmgr.register_plugin(plugin) \ No newline at end of file diff --git a/src/plugins/ImportGeneWeb.py b/src/plugins/ImportGeneWeb.py index 7840fca9e..13bf27491 100644 --- a/src/plugins/ImportGeneWeb.py +++ b/src/plugins/ImportGeneWeb.py @@ -40,13 +40,6 @@ from gettext import gettext as _ import logging log = logging.getLogger(".ImportGeneWeb") -#------------------------------------------------------------------------- -# -# GTK/GNOME Modules -# -#------------------------------------------------------------------------- -import gtk - #------------------------------------------------------------------------- # # GRAMPS modules @@ -56,7 +49,7 @@ import Errors import gen.lib import const from QuestionDialog import ErrorDialog -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin from htmlentitydefs import name2codepoint _date_parse = re.compile('([kmes~?<>]+)?([0-9/]+)([J|H|F])?(\.\.)?([0-9/]+)?([J|H|F])?') @@ -926,14 +919,12 @@ class GeneWebParser: print txt #------------------------------------------------------------------------- # -# +# Register with the plugin system # #------------------------------------------------------------------------- -_mime_type = const.APP_GENEWEB -_filter = gtk.FileFilter() -_filter.set_name(_('GeneWeb files')) -_filter.add_mime_type(_mime_type) -_format_name = _('GeneWeb') - pmgr = PluginManager.get_instance() -pmgr.register_import(importData, _filter, [_mime_type], 0, _format_name) +plugin = ImportPlugin(name = _('GeneWeb'), + description = _("Import data from GeneWeb files"), + import_function = importData, + mime_types = [const.APP_GENEWEB]) +pmgr.register_plugin(plugin) diff --git a/src/plugins/ImportProGen.py b/src/plugins/ImportProGen.py index 727a465db..8819f5f68 100644 --- a/src/plugins/ImportProGen.py +++ b/src/plugins/ImportProGen.py @@ -34,8 +34,6 @@ from gettext import gettext as _ import os import struct -import time - #------------------------------------------------------------------------ # # Set up logging @@ -49,12 +47,10 @@ log = logging.getLogger('.ImportProGen') # GRAMPS modules # #------------------------------------------------------------------------- -import Errors import Utils import gen.lib -import const from QuestionDialog import ErrorDialog -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin class ProgenError(Exception): @@ -1214,13 +1210,14 @@ class ProgenParser: self.db.commit_person(person, self.trans) self.progress.step() - -_mime_type = "application/x-progen" -import gtk -_filter = gtk.FileFilter() -_filter.set_name(_('Pro-Gen files')) -_filter.add_mime_type(_mime_type) -_format_name = _('Pro-Gen') - +#------------------------------------------------------------------------- +# +# Register with the plugin system +# +#------------------------------------------------------------------------- pmgr = PluginManager.get_instance() -pmgr.register_import(_importData, _filter, [_mime_type], 0, _format_name) +plugin = ImportPlugin(name = _('Pro-Gen'), + description = _("Import data from Pro-Gen files"), + import_function = _importData, + mime_types = ["application/x-progen"]) +pmgr.register_plugin(plugin) diff --git a/src/plugins/ImportvCard.py b/src/plugins/ImportvCard.py index aa35592b7..8ebd6dbe0 100644 --- a/src/plugins/ImportvCard.py +++ b/src/plugins/ImportvCard.py @@ -40,13 +40,6 @@ from gettext import gettext as _ import logging log = logging.getLogger(".ImportVCard") -#------------------------------------------------------------------------- -# -# GTK/GNOME Modules -# -#------------------------------------------------------------------------- -import gtk - #------------------------------------------------------------------------- # # GRAMPS modules @@ -54,9 +47,8 @@ import gtk #------------------------------------------------------------------------- import Errors import gen.lib -import const from QuestionDialog import ErrorDialog -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin #------------------------------------------------------------------------- # @@ -217,14 +209,12 @@ class VCardParser: #------------------------------------------------------------------------- # -# +# Register with the plugin system # #------------------------------------------------------------------------- -_mime_type = const.APP_VCARD -_filter = gtk.FileFilter() -_filter.set_name(_('vCard files')) -for mime in _mime_type: - _filter.add_mime_type(mime) - pmgr = PluginManager.get_instance() -pmgr.register_import(importData, _filter, _mime_type, 1) +plugin = ImportPlugin(name = _('vCard'), + description = _("Import data from vCard files"), + import_function = importData, + mime_types = ["text/x-vcard", "text/x-vcalendar"]) +pmgr.register_plugin(plugin) diff --git a/src/plugins/ReadGrdb.py b/src/plugins/ReadGrdb.py index 0e9b0fc84..31d7edeef 100644 --- a/src/plugins/ReadGrdb.py +++ b/src/plugins/ReadGrdb.py @@ -34,13 +34,6 @@ import shutil import tempfile from gettext import gettext as _ -#------------------------------------------------------------------------- -# -# GTK+ Modules -# -#------------------------------------------------------------------------- -import gtk - #------------------------------------------------------------------------- # # Gramps Modules @@ -51,7 +44,7 @@ from QuestionDialog import ErrorDialog from Errors import HandleError from BasicUtils import UpdateCallback from BasicUtils import name_displayer -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin #------------------------------------------------------------------------- # @@ -321,11 +314,10 @@ def make_peron_name_remapper(other_database, formats_map): # Register with the plugin system # #------------------------------------------------------------------------ -_mime_type = 'application/x-gramps' -_filter = gtk.FileFilter() -_filter.set_name(_('GRAMPS 2.x database')) -_filter.add_mime_type(_mime_type) -_format_name = _('GRAMPS 2.x database') - pmgr = PluginManager.get_instance() -pmgr.register_import(importData, _filter, [_mime_type], 0, _format_name) +plugin = ImportPlugin(name = _('GRAMPS 2.x database'), + description = _("Import data from GRAMPS 2.x " + "database files"), + import_function = importData, + mime_types = ['application/x-gramps']) +pmgr.register_plugin(plugin) diff --git a/src/plugins/ReadPkg.py b/src/plugins/ReadPkg.py index 8c3193bb7..2c449e2aa 100644 --- a/src/plugins/ReadPkg.py +++ b/src/plugins/ReadPkg.py @@ -41,13 +41,6 @@ from gettext import gettext as _ import logging log = logging.getLogger(".ReadPkg") -#------------------------------------------------------------------------- -# -# GNOME/GTK+ modules -# -#------------------------------------------------------------------------- -import gtk - #------------------------------------------------------------------------- # # GRAMPS modules @@ -57,7 +50,7 @@ import const from GrampsDbUtils import gramps_db_reader_factory from QuestionDialog import ErrorDialog, WarningDialog import Utils -from gen.plug import PluginManager +from gen.plug import PluginManager, ImportPlugin #------------------------------------------------------------------------- # @@ -149,11 +142,9 @@ def impData(database, name, cb=None, cl=0): # Register with the plugin system # #------------------------------------------------------------------------ -_mime_type = 'application/x-gramps-package' -_filter = gtk.FileFilter() -_filter.set_name(_('GRAMPS packages')) -_filter.add_mime_type(_mime_type) -_format_name = _('GRAMPS package') - pmgr = PluginManager.get_instance() -pmgr.register_import(impData, _filter, [_mime_type], 0, _format_name) +plugin = ImportPlugin(name = _('GRAMPS package'), + description = _("Import data from GRAMPS packages"), + import_function = impData, + mime_types = ['application/x-gramps-package']) +pmgr.register_plugin(plugin)