* src/Plugins.py: move non-gui functions to PluginMgr.py

* src/PluginMgr.py: Non-gui functions for plugins
* src/Makefile.am: Added PluginMgr.py
* various: switch from Plugins to PluginMgr


svn: r3866
This commit is contained in:
Don Allingham
2005-01-05 05:02:19 +00:00
parent 5ed9b8db51
commit e7569e2671
79 changed files with 589 additions and 539 deletions

View File

@@ -60,41 +60,7 @@ import Utils
import GrampsGconfKeys
import Errors
import Report
#-------------------------------------------------------------------------
#
# Global lists
#
#-------------------------------------------------------------------------
_reports = []
_tools = []
_imports = []
_exports = []
_success = []
_expect = []
_attempt = []
_loaddir = []
_textdoc = []
_bookdoc = []
_drawdoc = []
_failmsg = []
_bkitems = []
_cl = []
_status_up = None
#-------------------------------------------------------------------------
#
# Default relationship calculator
#
#-------------------------------------------------------------------------
import Relationship
_relcalc_class = Relationship.RelationshipCalculator
#-------------------------------------------------------------------------
#
#
#-------------------------------------------------------------------------
_unavailable = _("No description was provided"),
import PluginMgr
#-------------------------------------------------------------------------
#
@@ -341,9 +307,13 @@ class ReportPlugins(PluginDialog):
"""Display the dialog box, and build up the list of available
reports. This is used to build the selection tree on the left
hand side of the dailog box."""
PluginDialog.__init__(self,parent,db,active,_reports,_("Report Selection"),
_("Select a report from those available on the left."),
_("_Generate"), _("Generate selected report"))
PluginDialog.__init__(
self,parent,
db,
active,
PluginMgr.report_list,_("Report Selection"),
_("Select a report from those available on the left."),
_("_Generate"), _("Generate selected report"))
#-------------------------------------------------------------------------
#
@@ -359,9 +329,16 @@ class ToolPlugins(PluginDialog):
reports. This is used to build the selection tree on the left
hand side of the dailog box."""
PluginDialog.__init__(self,parent,db,active,_tools,_("Tool Selection"),
_("Select a tool from those available on the left."),
_("_Run"), _("Run selected tool"))
PluginDialog.__init__(
self,
parent,
db,
active,
PluginMgr.tool_list,
_("Tool Selection"),
_("Select a tool from those available on the left."),
_("_Run"),
_("Run selected tool"))
self.update = update
#-------------------------------------------------------------------------
@@ -373,10 +350,9 @@ class PluginStatus:
"""Displays a dialog showing the status of loaded plugins"""
def __init__(self):
global _status_up
if _status_up:
_status_up.close(None)
_status_up = self
if PluginMgr.status_up:
PluginMgr.status_up.close(None)
PluginMgr.status_up = self
import cStringIO
@@ -401,16 +377,16 @@ class PluginStatus:
info = cStringIO.StringIO()
if len(_expect) + len(_failmsg) == 0:
if len(PluginMgr.expect_list) + len(PluginMgr.failmsg_list) == 0:
window.get_buffer().set_text(_('All modules were successfully loaded.'))
else:
info.write(_("The following modules could not be loaded:"))
info.write("\n\n")
for (filename,msg) in _expect:
for (filename,msg) in PluginMgr.expect_list:
info.write("%s: %s\n\n" % (filename,msg))
for (filename,msgs) in _failmsg:
for (filename,msgs) in PluginMgr.failmsg_list:
error = str(msgs[0])
if error[0:11] == "exceptions.":
error = error[11:]
@@ -421,11 +397,11 @@ class PluginStatus:
window.get_buffer().set_text(info.read())
def on_delete(self,obj1,obj2):
_status_up = None
PluginMgr.status_up = None
def close(self,obj):
self.top.destroy()
_status_up = None
PluginMgr.status_up = None
def help(self,obj):
"""Display the GRAMPS manual"""
@@ -434,316 +410,6 @@ class PluginStatus:
def pop_button_update(self, client,cnxn_id,entry,data):
self.pop_button.set_active(GrampsGconfKeys.get_pop_plugin_status())
#-------------------------------------------------------------------------
#
# load_plugins
#
#-------------------------------------------------------------------------
def load_plugins(direct):
"""Searches the specified directory, and attempts to load any python
modules that it finds, adding name to the _attempts list. If the module
successfully loads, it is added to the _success list. Each plugin is
responsible for registering itself in the correct manner. No attempt
is done in this routine to register the tasks."""
global _success,_attempt,_loaddir,_failmsg
# if the directory does not exist, do nothing
if not os.path.isdir(direct):
return
# if the path has not already been loaded, save it in the _loaddir
# list for use on reloading
if direct not in _loaddir:
_loaddir.append(direct)
# add the directory to the python search path
sys.path.append(direct)
pymod = compile(r"^(.*)\.py$")
# loop through each file in the directory, looking for files that
# have a .py extention, and attempt to load the file. If it succeeds,
# add it to the _success list. If it fails, add it to the _failure
# list
for filename in os.listdir(direct):
name = os.path.split(filename)
match = pymod.match(name[1])
if not match:
continue
_attempt.append(filename)
plugin = match.groups()[0]
try:
a = __import__(plugin)
_success.append(a)
except Errors.PluginError, msg:
_expect.append((filename,str(msg)))
except:
_failmsg.append((filename,sys.exc_info()))
if GrampsGconfKeys.get_pop_plugin_status() and len(_expect)+len(_failmsg):
PluginStatus()
#-------------------------------------------------------------------------
#
# reload_plugins
#
#-------------------------------------------------------------------------
def reload_plugins(obj=None,junk1=None,junk2=None,junk3=None):
"""Treated as a callback, causes all plugins to get reloaded. This is
useful when writing and debugging a plugin"""
pymod = compile(r"^(.*)\.py$")
global _success,_attempt,_loaddir,_failmsg
oldfailmsg = _failmsg[:]
_failmsg = []
# attempt to reload all plugins that have succeeded in the past
for plugin in _success:
filename = os.path.basename(plugin.__file__)
filename = filename.replace('pyc','py')
filename = filename.replace('pyo','py')
try:
reload(plugin)
except:
_failmsg.append((filename,sys.exc_info()))
# attempt to load the plugins that have failed in the past
for (filename,message) in oldfailmsg:
name = os.path.split(filename)
match = pymod.match(name[1])
if not match:
continue
_attempt.append(filename)
plugin = match.groups()[0]
try:
# For some strange reason second importing of a failed plugin
# results in success. Then reload reveals the actual error.
# Looks like a bug in Python.
a = __import__(plugin)
reload(a)
_success.append(a)
except:
_failmsg.append((filename,sys.exc_info()))
# attempt to load any new files found
for directory in _loaddir:
for filename in os.listdir(directory):
name = os.path.split(filename)
match = pymod.match(name[1])
if not match:
continue
if filename in _attempt:
continue
_attempt.append(filename)
plugin = match.groups()[0]
try:
a = __import__(plugin)
if a not in _success:
_success.append(a)
except:
_failmsg.append((filename,sys.exc_info()))
if GrampsGconfKeys.get_pop_plugin_status():
global _status_up
if len(_failmsg):
PluginStatus()
elif _status_up:
_status_up.close(None)
_status_up = None
#-------------------------------------------------------------------------
#
# Plugin registering
#
#-------------------------------------------------------------------------
def register_export(exportData,title,description='',config=None,filename=''):
"""
Register an export filter, taking the task, file filter,
and the list of patterns for the filename matching.
"""
if description and filename:
_exports.append((exportData,title,description,config,filename))
def register_import(task, ffilter, mime=None, native_format=0):
"""Register an import filter, taking the task and file filter"""
if mime:
_imports.append((task, ffilter, mime, native_format))
def register_tool(task, name,
category=_("Uncategorized"),
description=_unavailable,
status=_("Unknown"),
author_name=_("Unknown"),
author_email=_("Unknown")
):
"""Register a tool with the plugin system"""
del_index = -1
for i in range(0,len(_tools)):
val = _tools[i]
if val[2] == name:
del_index = i
if del_index != -1:
del _tools[del_index]
_tools.append((task, category, name, description, status, author_name, author_name))
#-------------------------------------------------------------------------
#
# Report registration
#
#-------------------------------------------------------------------------
def register_report(
name,
category,
report_class,
options_class,
modes,
translated_name,
status=_("Unknown"),
description=_unavailable,
author_name=_("Unknown"),
author_email=_("Unknown")
):
"""
Registers report for all possible flavors.
This function should be used to register report as a stand-alone,
book item, or command-line flavor in any combination of those.
The low-level functions (starting with '_') should not be used
on their own. Instead, this function will call them as needed.
"""
(junk,standalone_task) = divmod(modes,2**Report.MODE_GUI)
if standalone_task:
_register_standalone(report_class,options_class,translated_name,
name,category,description,
status,author_name,author_email)
(junk,book_item_task) = divmod(modes-standalone_task,2**Report.MODE_BKI)
if book_item_task:
book_item_category = const.book_categories[category]
_register_book_item(translated_name,book_item_category,
report_class,options_class,name)
(junk,command_line_task) = divmod(modes-standalone_task-book_item_task,
2**Report.MODE_CLI)
if command_line_task:
_register_cl_report(name,category,report_class,options_class)
def _register_standalone(report_class, options_class, translated_name,
name, category,
description=_unavailable,
status=_("Unknown"),
author_name=_("Unknown"),
author_email=_("Unknown")
):
"""Register a report with the plugin system"""
del_index = -1
for i in range(0,len(_reports)):
val = _reports[i]
if val[2] == name:
del_index = i
if del_index != -1:
del _reports[del_index]
_reports.append((report_class, options_class, translated_name,
category, name, description, status, author_name, author_email))
def _register_book_item(translated_name,category,report_class,option_class,name):
"""Register a book item"""
for n in _bkitems:
if n[0] == name:
return
_bkitems.append((translated_name,category,report_class,option_class,name))
def _register_cl_report(name,category,report_class,options_class):
for n in _cl:
if n[0] == name:
return
_cl.append((name,category,report_class,options_class))
#-------------------------------------------------------------------------
#
# Text document generator registration
#
#-------------------------------------------------------------------------
def register_text_doc(name,classref, table, paper, style, ext,
print_report_label=None,clname=''):
"""Register a text document generator"""
for n in _textdoc:
if n[0] == name:
return
if not clname:
clname = ext[1:]
_textdoc.append((name,classref,table,paper,style,ext,print_report_label,clname))
#-------------------------------------------------------------------------
#
# Book document generator registration
#
#-------------------------------------------------------------------------
def register_book_doc(name,classref, table, paper, style, ext, clname=''):
"""Register a text document generator"""
for n in _bookdoc:
if n[0] == name:
return
if not clname:
clname = ext[1:]
_bookdoc.append((name,classref,table,paper,style,ext,clname))
#-------------------------------------------------------------------------
#
# Drawing document generator registration
#
#-------------------------------------------------------------------------
def register_draw_doc(name,classref,paper,style, ext,
print_report_label=None,clname=''):
"""Register a drawing document generator"""
for n in _drawdoc:
if n[0] == name:
return
if not clname:
clname = ext[1:]
_drawdoc.append((name,classref,paper,style,ext,print_report_label,clname))
#-------------------------------------------------------------------------
#
# Relationship calculator registration
#
#-------------------------------------------------------------------------
def register_relcalc(relclass, languages):
"""Register a relationshp calculator"""
global _relcalc_class
try:
if os.environ["LANG"] in languages:
_relcalc_class = relclass
except:
pass
def relationship_class(db):
global _relcalc_class
return _relcalc_class(db)
#-------------------------------------------------------------------------
#
# Image attributes
#
#-------------------------------------------------------------------------
_image_attributes = []
def register_image_attribute(name):
if name not in _image_attributes:
_image_attributes.append(name)
def get_image_attributes():
return _image_attributes
#-------------------------------------------------------------------------
#
# Building pulldown menus
@@ -790,7 +456,7 @@ def build_report_menu(top_menu,callback):
report_menu.show()
hash_data = {}
for report in _reports:
for report in PluginMgr.report_list:
standalone_category = const.standalone_categories[report[3]]
if hash_data.has_key(standalone_category):
hash_data[standalone_category].append(
@@ -827,7 +493,7 @@ def build_report_menu(top_menu,callback):
#
#-------------------------------------------------------------------------
def build_tools_menu(top_menu,callback):
build_menu(top_menu,_tools,callback)
build_menu(top_menu,PluginMgr.tool_list,callback)
#-------------------------------------------------------------------------
#
@@ -966,53 +632,3 @@ class GrampsBookFormatComboBox(gtk.ComboBox):
def get_printable(self):
return self.data[self.get_active()][6]
#-------------------------------------------------------------------------
#
# get_text_doc_list
#
#-------------------------------------------------------------------------
def get_text_doc_list():
l = []
_textdoc.sort()
for item in _textdoc:
l.append(item[0])
return l
#-------------------------------------------------------------------------
#
# get_book_doc_list
#
#-------------------------------------------------------------------------
def get_book_doc_list():
l = []
_bookdoc.sort()
for item in _bookdoc:
l.append(item[0])
return l
#-------------------------------------------------------------------------
#
# get_draw_doc_list
#
#-------------------------------------------------------------------------
def get_draw_doc_list():
l = []
_drawdoc.sort()
for item in _drawdoc:
l.append(item[0])
return l
#-------------------------------------------------------------------------
#
# Register the plugin reloading tool
#
#-------------------------------------------------------------------------
register_tool(
reload_plugins,
_("Reload plugins"),
category=_("Debug"),
description=_("Attempt to reload plugins. Note: This tool itself is not reloaded!"),
)