Back to index

plone3  3.1.7
interfaces.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2004 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ GenericSetup product interfaces
00014 
00015 $Id: interfaces.py 82852 2008-01-13 20:51:57Z wichert $
00016 """
00017 
00018 from zope.interface import Attribute
00019 from zope.interface import Interface
00020 from zope.schema import Text
00021 from zope.schema import TextLine
00022 
00023 # Please note that these values may change. Always import 
00024 # the values from here instead of using the values directly.
00025 BASE, EXTENSION = 1, 2
00026 SKIPPED_FILES = ('CVS', '.svn', '_svn', '_darcs')
00027 SKIPPED_SUFFIXES = ('~',)
00028 
00029 
00030 class IPseudoInterface( Interface ):
00031 
00032     """ API documentation;  not testable / enforceable.
00033     """
00034 
00035 
00036 class ISetupEnviron(Interface):
00037 
00038     """Context for im- and export adapters.
00039     """
00040 
00041     def getLogger(name):
00042         """Get a logger with the specified name, creating it if necessary.
00043         """
00044 
00045     def shouldPurge():
00046         """When installing, should the existing setup be purged?
00047         """
00048 
00049 
00050 class ISetupContext(ISetupEnviron):
00051 
00052     """ Context used for export / import plugins.
00053     """
00054     def getSite():
00055 
00056         """ Return the site object being configured / dumped.
00057         """
00058 
00059     def getSetupTool():
00060 
00061         """ Return the site object being configured / dumped.
00062         """
00063 
00064     def getEncoding():
00065 
00066         """ Get the encoding used for configuration data within the site.
00067 
00068         o Return None if the data should not be encoded.
00069         """
00070 
00071     def listNotes():
00072         """ Return notes recorded by this context.
00073         
00074         o Result a sequence of (component, message) tuples
00075         """
00076 
00077     def clearNotes():
00078         """ Clear all notes recorded by this context.
00079         """
00080 
00081 class IImportContext( ISetupContext ):
00082 
00083     def readDataFile( filename, subdir=None ):
00084 
00085         """ Search the current configuration for the requested file.
00086 
00087         o 'filename' is the name (without path elements) of the file.
00088 
00089         o 'subdir' is an optional subdirectory;  if not supplied, search
00090           only the "root" directory.
00091 
00092         o Return the file contents as a string, or None if the
00093           file cannot be found.
00094         """
00095 
00096     def getLastModified( path ):
00097 
00098         """ Return the modification timestamp of the item at 'path'.
00099 
00100         o Result will be a DateTime instance.
00101 
00102         o Search profiles in the configuration in order.
00103 
00104         o If the context is filesystem based, return the 'stat' timestamp
00105           of the file / directory to which 'path' points.
00106 
00107         o If the context is ZODB-based, return the Zope modification time
00108           of the object to which 'path' points.
00109 
00110         o Return None if 'path' does not point to any object.
00111         """
00112 
00113     def isDirectory( path ):
00114 
00115         """ Test whether path points to a directory / folder.
00116 
00117         o If the context is filesystem based, check that 'path' points to
00118           a subdirectory within the "root" directory.
00119 
00120         o If the context is ZODB-based, check that 'path' points to a
00121           "container" under the context's tool.
00122 
00123         o Return None if 'path' does not resolve;  otherwise, return a
00124           bool.
00125         """
00126 
00127     def listDirectory( path, skip=SKIPPED_FILES ):
00128 
00129         """ List IDs of the contents of a  directory / folder.
00130 
00131         o Omit names in 'skip'.
00132 
00133         o If 'path' does not point to a directory / folder, return None.
00134         """
00135 
00136 
00137 class IImportPlugin( IPseudoInterface ):
00138 
00139     """ Signature for callables used to import portions of site configuration.
00140     """
00141     def __call__( context ):
00142 
00143         """ Perform the setup step.
00144 
00145         o Return a message describing the work done.
00146 
00147         o 'context' must implement IImportContext.
00148         """
00149 
00150 class IExportContext( ISetupContext ):
00151 
00152     def writeDataFile( filename, text, content_type, subdir=None ):
00153 
00154         """ Write data into the specified location.
00155 
00156         o 'filename' is the unqualified name of the file.
00157 
00158         o 'text' is the content of the file.
00159 
00160         o 'content_type' is the MIMEtype of the file.
00161 
00162         o 'subdir', if passed, is a path to a subdirectory / folder in
00163           which to write the file;  if not passed, write the file to the
00164           "root" of the target.
00165         """
00166 
00167 class IExportPlugin( IPseudoInterface ):
00168 
00169     """ Signature for callables used to export portions of site configuration.
00170     """
00171     def __call__( context ):
00172 
00173         """ Write export data for the site wrapped by context.
00174 
00175         o Return a message describing the work done.
00176 
00177         o 'context' must implement IExportContext.  The plugin will use
00178           its 'writeDataFile' method for each file to be exported.
00179         """
00180 
00181 class IStepRegistry( Interface ):
00182 
00183     """ Base interface for step registries.
00184     """
00185     def listSteps():
00186 
00187         """ Return a sequence of IDs of registered steps.
00188 
00189         o Order is not significant.
00190         """
00191 
00192     def listStepMetadata():
00193 
00194         """ Return a sequence of mappings describing registered steps.
00195 
00196         o Mappings will be ordered alphabetically.
00197         """
00198 
00199     def getStepMetadata( key, default=None ):
00200 
00201         """ Return a mapping of metadata for the step identified by 'key'.
00202 
00203         o Return 'default' if no such step is registered.
00204 
00205         o The 'handler' metadata is available via 'getStep'.
00206         """
00207 
00208     def generateXML():
00209 
00210         """ Return a round-trippable XML representation of the registry.
00211 
00212         o 'handler' values are serialized using their dotted names.
00213         """
00214 
00215     def parseXML( text ):
00216 
00217         """ Parse 'text'.
00218         """
00219 
00220 class IImportStepRegistry( IStepRegistry ):
00221 
00222     """ API for import step registry.
00223     """
00224     def sortSteps():
00225 
00226         """ Return a sequence of registered step IDs
00227 
00228         o Sequence is sorted topologically by dependency, with the dependent
00229           steps *after* the steps they depend on.
00230         """
00231 
00232     def checkComplete():
00233 
00234         """ Return a sequence of ( node, edge ) tuples for unsatisifed deps.
00235         """
00236 
00237     def getStep( key, default=None ):
00238 
00239         """ Return the IImportPlugin registered for 'key'.
00240 
00241         o Return 'default' if no such step is registered.
00242         """
00243 
00244     def registerStep( id
00245                     , version=None
00246                     , handler=None
00247                     , dependencies=()
00248                     , title=None
00249                     , description=None
00250                     ):
00251         """ Register a setup step.
00252 
00253         o 'id' is a unique name for this step,
00254 
00255         o 'version' is a string for comparing versions, it is preferred to
00256           be a yyyy/mm/dd-ii formatted string (date plus two-digit
00257           ordinal).  when comparing two version strings, the version with
00258           the lower sort order is considered the older version.
00259 
00260           - Newer versions of a step supplant older ones.
00261 
00262           - Attempting to register an older one after a newer one results
00263             in a KeyError.
00264 
00265           NOTE: The version argument is deprecated.
00266 
00267         o 'handler' should implement IImportPlugin.
00268 
00269         o 'dependencies' is a tuple of step ids which have to run before
00270           this step in order to be able to run at all. Registration of
00271           steps that have unmet dependencies are deferred until the
00272           dependencies have been registered.
00273 
00274         o 'title' is a one-line UI description for this step.
00275           If None, the first line of the documentation string of the handler
00276           is used, or the id if no docstring can be found.
00277 
00278         o 'description' is a one-line UI description for this step.
00279           If None, the remaining line of the documentation string of
00280           the handler is used, or default to ''.
00281         """
00282 
00283 class IExportStepRegistry( IStepRegistry ):
00284 
00285     """ API for export step registry.
00286     """
00287     def getStep( key, default=None ):
00288 
00289         """ Return the IExportPlugin registered for 'key'.
00290 
00291         o Return 'default' if no such step is registered.
00292         """
00293 
00294     def registerStep( id, handler, title=None, description=None ):
00295 
00296         """ Register an export step.
00297 
00298         o 'id' is the unique identifier for this step
00299 
00300         o 'handler' should implement IExportPlugin.
00301 
00302         o 'title' is a one-line UI description for this step.
00303           If None, the first line of the documentation string of the step
00304           is used, or the id if no docstring can be found.
00305 
00306         o 'description' is a one-line UI description for this step.
00307           If None, the remaining line of the documentation string of
00308           the step is used, or default to ''.
00309         """
00310 
00311 class IToolsetRegistry( Interface ):
00312 
00313     """ API for toolset registry.
00314     """
00315     def listForbiddenTools():
00316 
00317         """ Return a list of IDs of tools which must be removed, if present.
00318         """
00319 
00320     def addForbiddenTool(tool_id ):
00321 
00322         """ Add 'tool_id' to the list of forbidden tools.
00323 
00324         o Raise KeyError if 'tool_id' is already in the list.
00325 
00326         o Raise ValueError if 'tool_id' is in the "required" list.
00327         """
00328 
00329     def listRequiredTools():
00330 
00331         """ Return a list of IDs of tools which must be present.
00332         """
00333 
00334     def getRequiredToolInfo( tool_id ):
00335 
00336         """ Return a mapping describing a partiuclar required tool.
00337 
00338         o Keys include:
00339 
00340           'id' -- the ID of the tool
00341 
00342           'class' -- a dotted path to its class
00343 
00344         o Raise KeyError if 'tool_id' id not a known tool.
00345         """
00346 
00347     def listRequiredToolInfo():
00348 
00349         """ Return a list of IDs of tools which must be present.
00350         """
00351 
00352     def addRequiredTool( tool_id, dotted_name ):
00353 
00354         """ Add a tool to our "required" list.
00355 
00356         o 'tool_id' is the tool's ID.
00357 
00358         o 'dotted_name' is a dotted (importable) name of the tool's class.
00359 
00360         o Raise KeyError if we have already registered a class for 'tool_id'.
00361 
00362         o Raise ValueError if 'tool_id' is in the "forbidden" list.
00363         """
00364 
00365 class IProfileRegistry( Interface ):
00366 
00367     """ API for profile registry.
00368     """
00369     def getProfileInfo( profile_id, for_=None ):
00370 
00371         """ Return a mapping describing a registered filesystem profile.
00372 
00373         o Keys include:
00374 
00375           'id' -- the ID of the profile
00376 
00377           'title' -- its title
00378 
00379           'description' -- a textual description of the profile
00380 
00381           'path' -- a path to the profile on the filesystem.
00382 
00383           'product' -- the name of the product to which 'path' is
00384              relative (None for absolute paths).
00385 
00386           'type' -- either BASE or EXTENSION
00387         
00388         o 'for_', if passed, should be the interface specifying the "site
00389             type" for which the profile is relevant, e.g.
00390             Products.CMFCore.interfaces.ISiteRoot or
00391             Products.PluggableAuthService.interfaces.IPluggableAuthService.
00392             If 'None', list all profiles.
00393         """
00394 
00395     def listProfiles( for_=None ):
00396 
00397         """ Return a list of IDs for registered profiles.
00398         
00399         o 'for_', if passed, should be the interface specifying the "site
00400             type" for which the profile is relevant, e.g.
00401             Products.CMFCore.interfaces.ISiteRoot or
00402             Products.PluggableAuthService.interfaces.IPluggableAuthService.
00403             If 'None', list all profiles.
00404         """
00405 
00406     def listProfileInfo( for_=None ):
00407 
00408         """ Return a list of mappings describing registered profiles.
00409 
00410         o See 'getProfileInfo' for a description of the mappings' keys.
00411         
00412         o 'for_', if passed, should be the interface specifying the "site
00413             type" for which the profile is relevant, e.g.
00414             Products.CMFCore.interfaces.ISiteRoot or
00415             Products.PluggableAuthService.interfaces.IPluggableAuthService.
00416             If 'None', list all profiles.
00417         """
00418 
00419     def registerProfile( name
00420                        , title
00421                        , description
00422                        , path
00423                        , product=None
00424                        , profile_type=BASE
00425                        , for_=None
00426                        ):
00427         """ Add a new profile to the registry.
00428 
00429         o If an existing profile is already registered for 'product:name',
00430           raise KeyError.
00431 
00432         o If 'product' is passed, then 'path' should be interpreted as
00433           relative to the corresponding product directory.
00434         
00435         o 'for_', if passed, should be the interface specifying the "site
00436           type" for which the profile is relevant, e.g.
00437           Products.CMFCore.interfaces.ISiteRoot or
00438           Products.PluggableAuthService.interfaces.IPluggableAuthService.
00439           If 'None', the profile might be used in any site.
00440         """
00441 
00442 class ISetupTool( Interface ):
00443 
00444     """ API for SetupTool.
00445     """
00446 
00447     def getEncoding():
00448 
00449         """ Get the encoding used for configuration data within the site.
00450 
00451         o Return None if the data should not be encoded.
00452         """
00453 
00454     def getImportContextID():
00455 
00456         """ Get the ID of the active import context.
00457 
00458         DEPRECATED.  The idea of a stateful active import context is
00459         going away.
00460         """
00461 
00462     def getBaselineContextID():
00463         """ Get the ID of the base profile for this configuration.
00464         """
00465 
00466     def setImportContext( context_id ):
00467 
00468         """ Set the ID of the active import context and update the registries.
00469 
00470         DEPRECATED.  The idea of a stateful active import context is
00471         going away.
00472         """
00473 
00474     def setBaselineContext( context_id, encoding=None):
00475         """ Specify the base profile for this configuration.
00476         """
00477 
00478     def applyContext( context, encoding=None ):
00479 
00480         """ Update the tool from the supplied context, without modifying its
00481             "permanent" ID.
00482         """
00483 
00484     def getImportStepRegistry():
00485 
00486         """ Return the IImportStepRegistry for the tool.
00487         """
00488 
00489     def getExportStepRegistry():
00490 
00491         """ Return the IExportStepRegistry for the tool.
00492         """
00493 
00494     def getToolsetRegistry():
00495 
00496         """ Return the IToolsetRegistry for the tool.
00497         """
00498 
00499     def getProfileDependencyChain( profile_id ):
00500 
00501         """Return a list of dependencies for a profile.
00502 
00503         The list is ordered by install order, with the requested profile as
00504         last item.
00505         """
00506 
00507     def runImportStepFromProfile(profile_id, step_id,
00508                                  run_dependencies=True, purge_old=None):
00509 
00510         """ Execute a given setup step from the given profile.
00511 
00512         o 'profile_id' must be a valid ID of a registered profile;
00513            otherwise, raise KeyError.
00514 
00515         o 'step_id' is the ID of the step to run.
00516 
00517         o If 'purge_old' is True, then run the step after purging any
00518           "old" setup first (this is the responsibility of the step,
00519           which must check the context we supply).
00520 
00521         o If 'run_dependencies' is True, then run any out-of-date
00522           dependency steps first.
00523 
00524         o Return a mapping, with keys:
00525 
00526           'steps' -- a sequence of IDs of the steps run.
00527 
00528           'messages' -- a dictionary holding messages returned from each
00529             step
00530         """
00531 
00532     def runImportStep(step_id, run_dependencies=True, purge_old=None):
00533 
00534         """ Execute a given setup step from the current
00535         _import_context_id context.
00536 
00537         o 'step_id' is the ID of the step to run.
00538 
00539         o If 'purge_old' is True, then run the step after purging any
00540           "old" setup first (this is the responsibility of the step,
00541           which must check the context we supply).
00542 
00543         o If 'run_dependencies' is True, then run any out-of-date
00544           dependency steps first.
00545 
00546         o Return a mapping, with keys:
00547 
00548           'steps' -- a sequence of IDs of the steps run.
00549 
00550           'messages' -- a dictionary holding messages returned from each
00551             step
00552 
00553         DEPRECATED.  Use runImportStepFromProfile instead.
00554         """
00555 
00556     def runAllImportStepsFromProfile(profile_id, purge_old=None, ignore_dependencies=False):
00557 
00558         """ Run all setup steps for the given profile in dependency order.
00559 
00560         o 'profile_id' must be a valid ID of a registered profile;
00561            otherwise, raise KeyError.
00562 
00563         o If 'purge_old' is True, then run each step after purging any
00564           "old" setup first (this is the responsibility of the step,
00565           which must check the context we supply).
00566 
00567         o Unless 'ignore_dependencies' is true this will also import
00568           all profiles this profile depends on.
00569 
00570         o Return a mapping, with keys:
00571 
00572           'steps' -- a sequence of IDs of the steps run.
00573 
00574           'messages' -- a dictionary holding messages returned from each
00575             step
00576         """
00577 
00578     def runAllImportSteps(purge_old=None):
00579 
00580         """ Run all setup steps for the _import_context_id profile in
00581         dependency order.
00582 
00583         o If 'purge_old' is True, then run each step after purging any
00584           "old" setup first (this is the responsibility of the step,
00585           which must check the context we supply).
00586 
00587         o Return a mapping, with keys:
00588 
00589           'steps' -- a sequence of IDs of the steps run.
00590 
00591           'messages' -- a dictionary holding messages returned from each
00592             step
00593 
00594         DEPRECATED.  Use runAllImportStepsFromProfile instead.
00595         """
00596 
00597     def runExportStep( step_id ):
00598 
00599         """ Generate a tarball containing artifacts from one export step.
00600 
00601         o 'step_id' identifies the export step.
00602 
00603         o Return a mapping, with keys:
00604 
00605           'steps' -- a sequence of IDs of the steps run.
00606 
00607           'messages' -- a dictionary holding messages returned from each
00608             step
00609 
00610           'tarball' -- the stringified tar-gz data.
00611         """
00612 
00613     def runAllExportSteps():
00614 
00615         """ Generate a tarball containing artifacts from all export steps.
00616 
00617         o Return a mapping, with keys:
00618 
00619           'steps' -- a sequence of IDs of the steps run.
00620 
00621           'messages' -- a dictionary holding messages returned from each
00622             step
00623 
00624           'tarball' -- the stringified tar-gz data.
00625         """
00626 
00627     def createSnapshot( snapshot_id ):
00628 
00629         """ Create a snapshot folder using all steps.
00630 
00631         o 'snapshot_id' is the ID of the new folder.
00632         """
00633 
00634     def compareConfigurations( lhs_context
00635                              , rhs_context
00636                              , missing_as_empty=False
00637                              , ignore_whitespace=False
00638                              ):
00639         """ Compare two configurations.
00640 
00641         o 'lhs_context' and 'rhs_context' must implement IImportContext.
00642 
00643         o If 'missing_as_empty', then compare files not present as though
00644           they were zero-length;  otherwise, omit such files.
00645 
00646         o If 'ignore_whitespace', then suppress diffs due only to whitespace
00647           (c.f:  'diff -wbB')
00648         """
00649 
00650     def getProfileImportDate(profile_id):
00651         """ Return the last date an extension was imported.
00652 
00653         o The result will be a string, formated as IS0.
00654         """
00655 
00656 
00657 class IWriteLogger(Interface):
00658 
00659     """Write methods used by the python logging Logger.
00660     """
00661 
00662     def debug(msg, *args, **kwargs):
00663         """Log 'msg % args' with severity 'DEBUG'.
00664         """
00665 
00666     def info(msg, *args, **kwargs):
00667         """Log 'msg % args' with severity 'INFO'.
00668         """
00669 
00670     def warning(msg, *args, **kwargs):
00671         """Log 'msg % args' with severity 'WARNING'.
00672         """
00673 
00674     def error(msg, *args, **kwargs):
00675         """Log 'msg % args' with severity 'ERROR'.
00676         """
00677 
00678     def exception(msg, *args):
00679         """Convenience method for logging an ERROR with exception information.
00680         """
00681 
00682     def critical(msg, *args, **kwargs):
00683         """Log 'msg % args' with severity 'CRITICAL'.
00684         """
00685 
00686     def log(level, msg, *args, **kwargs):
00687         """Log 'msg % args' with the integer severity 'level'.
00688         """
00689 
00690 
00691 class INode(Interface):
00692 
00693     """Node im- and exporter.
00694     """
00695 
00696     node = Text(description=u'Im- and export the object as a DOM node.')
00697 
00698 
00699 class IBody(INode):
00700 
00701     """Body im- and exporter.
00702     """
00703 
00704     body = Text(description=u'Im- and export the object as a file body.')
00705 
00706     mime_type = TextLine(description=u'MIME type of the file body.')
00707 
00708     name = TextLine(description=u'Enforce this name for the file.')
00709 
00710     suffix = TextLine(description=u'Suffix for the file.')
00711 
00712 
00713 class IFilesystemExporter(Interface):
00714     """ Plugin interface for site structure export.
00715     """
00716     def export(export_context, subdir, root=False):
00717         """ Export our 'context' using the API of 'export_context'.
00718 
00719         o 'export_context' must implement
00720           Products.GenericSupport.interfaces.IExportContext.
00721 
00722         o 'subdir', if passed, is the relative subdirectory containing our
00723           context within the site.
00724 
00725         o 'root', if true, indicates that the current context is the
00726           "root" of an import (this may be used to adjust paths when
00727           interacting with the context).
00728         """
00729 
00730     def listExportableItems():
00731         """ Return a sequence of the child items to be exported.
00732 
00733         o Each item in the returned sequence will be a tuple,
00734           (id, object, adapter) where adapter must implement
00735           IFilesystemExporter.
00736         """
00737 
00738 class IFilesystemImporter(Interface):
00739     """ Plugin interface for site structure export.
00740     """
00741     def import_(import_context, subdir, root=False):
00742         """ Import our 'context' using the API of 'import_context'.
00743 
00744         o 'import_context' must implement
00745           Products.GenericSupport.interfaces.IImportContext.
00746 
00747         o 'subdir', if passed, is the relative subdirectory containing our
00748           context within the site.
00749 
00750         o 'root', if true, indicates that the current context is the
00751           "root" of an import (this may be used to adjust paths when
00752           interacting with the context).
00753         """
00754 
00755 class IContentFactory(Interface):
00756     """ Adapter interface for factories specific to a container.
00757     """
00758     def __call__(id):
00759         """ Return a new instance, seated in the context under 'id'.
00760         """
00761 
00762 class IContentFactoryName(Interface):
00763     """ Adapter interface for finding the name of the ICF for an object.
00764     """
00765     def __call__():
00766         """ Return a string, suitable for looking up an IContentFactory.
00767         
00768         o The string should allow finding a factory for our context's
00769           container which would create an "empty" instance of the same
00770           type as our context.
00771         """
00772 
00773 class ICSVAware(Interface):
00774     """ Interface for objects which dump / load 'text/comma-separated-values'.
00775     """
00776     def getId():
00777         """ Return the Zope id of the object.
00778         """
00779 
00780     def as_csv():
00781         """ Return a string representing the object as CSV.
00782         """
00783 
00784     def put_csv(fd):
00785         """ Parse CSV and update the object.
00786 
00787         o 'fd' must be a file-like object whose 'read' method returns
00788           CSV text parseable by the 'csv.reader'.
00789         """
00790 
00791 class IINIAware(Interface):
00792     """ Interface for objects which dump / load INI-format files..
00793     """
00794     def getId():
00795         """ Return the Zope id of the object.
00796         """
00797 
00798     def as_ini():
00799         """ Return a string representing the object as INI.
00800         """
00801 
00802     def put_ini(stream_or_text):
00803         """ Parse INI-formatted text and update the object.
00804 
00805         o 'stream_or_text' must be either a string, or else a stream
00806           directly parseable by ConfigParser.
00807         """
00808 
00809 class IDAVAware(Interface):
00810     """ Interface for objects which handle their own FTP / DAV operations.
00811     """
00812     def getId():
00813         """ Return the Zope id of the object.
00814         """
00815 
00816     def manage_FTPget():
00817         """ Return a string representing the object as a file.
00818         """
00819 
00820     def PUT(REQUEST, RESPONSE):
00821         """ Parse file content and update the object.
00822 
00823         o 'REQUEST' will have a 'get' method, which will have the 
00824           content object in its "BODY" key.  It will also have 'get_header'
00825           method, whose headers (e.g., "Content-Type") may affect the
00826           processing of the body.
00827         """
00828 
00829 class IBeforeProfileImportEvent(Interface):
00830     """ An event which is fired before (part of) a profile is imported.
00831     """
00832     profile_id = Attribute("id of the profile to be imported or None for non-profile imports.")
00833 
00834     steps = Attribute("list of steps that will be imported")
00835 
00836     full_import = Attribute("True if all steps will be imported")
00837 
00838     tool = Attribute("The tool which is performing the import")
00839 
00840 
00841 class IProfileImportedEvent(Interface):
00842     """ An event which is fired when (part of) a profile is imported.
00843     """
00844     profile_id = Attribute("id of the imported profile")
00845 
00846     steps = Attribute("list of steps have been imported")
00847 
00848     full_import = Attribute("True if all steps are imported")
00849 
00850     tool = Attribute("The tool which is performing the import")
00851