Back to index

plone3  3.1.7
copy.py
Go to the documentation of this file.
00001 from OFS.SimpleItem import SimpleItem
00002 from persistent import Persistent 
00003 
00004 from zope.interface import implements, Interface
00005 from zope.component import adapts
00006 from zope.formlib import form
00007 from zope import schema
00008 
00009 from zope.event import notify
00010 from zope.lifecycleevent import ObjectCopiedEvent
00011 
00012 import OFS.subscribers
00013 from OFS.event import ObjectClonedEvent
00014 
00015 from plone.contentrules.rule.interfaces import IExecutable, IRuleElementData
00016 
00017 from plone.app.contentrules.browser.formhelper import AddForm, EditForm
00018 from plone.app.vocabularies.catalog import SearchableTextSourceBinder
00019 from plone.app.form.widgets.uberselectionwidget import UberSelectionWidget
00020 
00021 import transaction
00022 from Acquisition import aq_inner, aq_parent
00023 from ZODB.POSException import ConflictError
00024 from Products.CMFCore.utils import getToolByName
00025 from Products.CMFPlone import PloneMessageFactory as _
00026 
00027 from Products.CMFPlone import utils
00028 from Products.statusmessages.interfaces import IStatusMessage
00029 
00030 class ICopyAction(Interface):
00031     """Interface for the configurable aspects of a move action.
00032     
00033     This is also used to create add and edit forms, below.
00034     """
00035     
00036     target_folder = schema.Choice(title=_(u"Target folder"),
00037                                   description=_(u"As a path relative to the portal root."),
00038                                   required=True,
00039                                   source=SearchableTextSourceBinder({'is_folderish' : True},
00040                                                                     default_query='path:'))
00041          
00042 class CopyAction(SimpleItem):
00043     """The actual persistent implementation of the action element.
00044     """
00045     implements(ICopyAction, IRuleElementData)
00046     
00047     target_folder = ''
00048     element = 'plone.actions.Copy'
00049     
00050     @property
00051     def summary(self):
00052         return _(u"Copy to folder ${folder}.",
00053                  mapping=dict(folder=self.target_folder))
00054     
00055 class CopyActionExecutor(object):
00056     """The executor for this action.
00057     """
00058     implements(IExecutable)
00059     adapts(Interface, ICopyAction, Interface)
00060          
00061     def __init__(self, context, element, event):
00062         self.context = context
00063         self.element = element
00064         self.event = event
00065 
00066     def __call__(self):
00067         portal_url = getToolByName(self.context, 'portal_url', None)
00068         if portal_url is None:
00069             return False
00070         
00071         obj = self.event.object
00072         
00073         path = self.element.target_folder
00074         if len(path) > 1 and path[0] == '/':
00075             path = path[1:]
00076         target = portal_url.getPortalObject().unrestrictedTraverse(str(path), None)
00077     
00078         if target is None:
00079             self.error(obj, _(u"Target folder ${target} does not exist.", mapping={'target' : path}))
00080             return False
00081 
00082         try:
00083             obj._notifyOfCopyTo(target, op=0)
00084         except ConflictError:
00085             raise
00086         except Exception, e:
00087             self.error(obj, str(e))
00088             return False
00089             
00090         old_id = obj.getId()
00091         new_id = self.generate_id(target, old_id)
00092         
00093         orig_obj = obj
00094         obj = obj._getCopy(target)
00095         obj._setId(new_id)
00096         
00097         notify(ObjectCopiedEvent(obj, orig_obj))
00098 
00099         target._setObject(new_id, obj)
00100         obj = target._getOb(new_id)
00101         obj.wl_clearLocks()
00102 
00103         obj._postCopy(target, op=0)
00104 
00105         OFS.subscribers.compatibilityCall('manage_afterClone', obj, obj)
00106         
00107         notify(ObjectClonedEvent(obj))
00108         
00109         return True 
00110         
00111     def error(self, obj, error):
00112         request = getattr(self.context, 'REQUEST', None)
00113         if request is not None:
00114             title = utils.pretty_title_or_id(obj, obj)
00115             message = _(u"Unable to copy ${name} as part of content rule 'copy' action: ${error}",
00116                           mapping={'name' : title, 'error' : error})
00117             IStatusMessage(request).addStatusMessage(message, type="error")
00118             
00119     def generate_id(self, target, old_id):
00120         taken = getattr(target, 'has_key', None)
00121         if taken is None:
00122             item_ids = set(target.objectIds())
00123             taken = lambda x: x in item_ids
00124         if not taken(old_id):
00125             return old_id
00126         idx = 1
00127         while taken("%s.%d" % (old_id, idx)):
00128             idx += 1
00129         return "%s.%d" % (old_id, idx)
00130         
00131 class CopyAddForm(AddForm):
00132     """An add form for move-to-folder actions.
00133     """
00134     form_fields = form.FormFields(ICopyAction)
00135     form_fields['target_folder'].custom_widget = UberSelectionWidget
00136     label = _(u"Add Copy Action")
00137     description = _(u"A copy action can copy an object to a different folder.")
00138     form_name = _(u"Configure element")
00139     
00140     def create(self, data):
00141         a = CopyAction()
00142         form.applyChanges(a, self.form_fields, data)
00143         return a
00144 
00145 class CopyEditForm(EditForm):
00146     """An edit form for copy rule actions.
00147     
00148     Formlib does all the magic here.
00149     """
00150     form_fields = form.FormFields(ICopyAction)
00151     form_fields['target_folder'].custom_widget = UberSelectionWidget
00152     label = _(u"Edit Copy Action")
00153     description = _(u"A copy action can copy an object to a different folder.")
00154     form_name = _(u"Configure element")