Commit 80bc340e authored by Bartek Górny's avatar Bartek Górny

rewrote some parts so it almost works; TODO: PUT_factory problem

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@12200 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 5ec7fc53
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
# #
############################################################################## ##############################################################################
import re
import string
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Globals import InitializeClass, DTMLFile from Globals import InitializeClass, DTMLFile
...@@ -39,6 +41,9 @@ from Acquisition import aq_base ...@@ -39,6 +41,9 @@ from Acquisition import aq_base
NO_DISCOVER_METADATA_KEY = '_v_no_discover_metadata' NO_DISCOVER_METADATA_KEY = '_v_no_discover_metadata'
USER_NAME_KEY = '_v_document_user_login' USER_NAME_KEY = '_v_document_user_login'
TEMP_NEW_OBJECT_KEY = '_v_new_object'
_marker = [] # Create a new marker object.
class ContributionTool(BaseTool): class ContributionTool(BaseTool):
""" """
...@@ -61,7 +66,7 @@ class ContributionTool(BaseTool): ...@@ -61,7 +66,7 @@ class ContributionTool(BaseTool):
id = 'portal_contributions' id = 'portal_contributions'
meta_type = 'ERP5 Contribution Tool' meta_type = 'ERP5 Contribution Tool'
portal_type = 'Contribution Tool' portal_type = 'Contribution Tool'
allowed_types = ('File', 'Image') # XXX Is this really needed ? allowed_types = ('File', 'Image', 'Text') # XXX Is this really needed ?
# Declarative Security # Declarative Security
security = ClassSecurityInfo() security = ClassSecurityInfo()
...@@ -70,11 +75,12 @@ class ContributionTool(BaseTool): ...@@ -70,11 +75,12 @@ class ContributionTool(BaseTool):
manage_overview = DTMLFile( 'explainContributionTool', _dtmldir ) manage_overview = DTMLFile( 'explainContributionTool', _dtmldir )
security.declarePrivate('findTypeName') security.declarePrivate('findTypeName')
def findTypeName(self, name, ob): def findTypeName(self, file_name, ob):
""" """
Finds the appropriate portal type based on the file name Finds the appropriate portal type based on the file name
or if necessary the content of ob or if necessary the content of ob
""" """
portal_type = None
# We should only consider those portal_types which share the # We should only consider those portal_types which share the
# same meta_type with the current object # same meta_type with the current object
valid_portal_type_list = [] valid_portal_type_list = []
...@@ -83,21 +89,31 @@ class ContributionTool(BaseTool): ...@@ -83,21 +89,31 @@ class ContributionTool(BaseTool):
valid_portal_type_list.append(pt.id) valid_portal_type_list.append(pt.id)
# Check if the filename tells which portal_type this is # Check if the filename tells which portal_type this is
portal_type = self.getPropertyDictFromFileName(file_name).get('portal_type', None) portal_type_list = self.getPropertyDictFromFileName(file_name).get('portal_type', [])
if len(portal_type_list) == 1:
# if we have only one, then this is it
return portal_type_list[0]
# If it is still None, we need to read the document # If it is still None, we need to read the document
# to check which of the candidates is suitable # to check which of the candidates is suitable
if portal_type is None: if portal_type is None:
# The document is now responsible of telling all its properties # The document is now responsible of telling all its properties
portal_type = ob.getPropertyDictFromContent().get('portal_type', None) portal_type = ob.getPropertyDictFromContent().get('portal_type', None)
if portal_type is not None:
# we check if it matches the candidate list, if there were any
if len(portal_type_list)>1 and portal_type not in portal_type_list:
raise TypeError('%s not in the list of %s' % (portal_type, str(portal_type_list)))
return portal_type
if portal_type is None: if portal_type is None:
# We can not do anything anymore # We can not do anything anymore
return ob.portal_type return ob.portal_type
#return None
if portal_type not in valid_portal_type_list: if portal_type not in valid_portal_type_list:
# We will not be able to migrate ob to portal_type # We will not be able to migrate ob to portal_type
return ob.portal_type #return ob.portal_type
return None
return portal_type return portal_type
...@@ -118,6 +134,9 @@ class ContributionTool(BaseTool): ...@@ -118,6 +134,9 @@ class ContributionTool(BaseTool):
We always generate ID. So, we must prevent using the one We always generate ID. So, we must prevent using the one
which we were provided. which we were provided.
""" """
if portal_type is None:
portal_type = kw.get('portal_type')
kw['portal_type'] = portal_type
# Temp objects use the standard newContent from Folder # Temp objects use the standard newContent from Folder
if temp_object: if temp_object:
# For temp_object creation, use the standard method # For temp_object creation, use the standard method
...@@ -126,19 +145,25 @@ class ContributionTool(BaseTool): ...@@ -126,19 +145,25 @@ class ContributionTool(BaseTool):
# Try to find the file_name # Try to find the file_name
file = kw.get('file', None) file = kw.get('file', None)
if file is not None: if file is not None:
file_name = file.name try:
file_name = file.filename
except AttributeError: # file can be raw data
file_name = kw.get('file_name')
else: else:
file_name = None file_name = None
if file_name is not None:
# we store it as source_reference
kw['source_reference'] = file_name
# If the portal_type was provided, we can go faster # If the portal_type was provided, we can go faster
if portal_type is not None: if portal_type is not None and portal_type != '':
# We know the portal_type, let us find the module # We know the portal_type, let us find the module
module = self.getDefaultModule(portal_type) module = self.getDefaultModule(portal_type)
# And return a document # And return a document
# NOTE: we use the module ID generator rather than the provided ID # NOTE: we use the module ID generator rather than the provided ID
document = module.newContent(portal_type=portal_type, **kw) document = module.newContent(**kw)
if discover_metadata: document.discoverMetadata(file_name=file_name, user_login=user_login) #if discover_metadata: document.discoverMetadata(file_name=file_name, user_login=user_login)
return document return document
# From here, there is no hope unless a file was provided # From here, there is no hope unless a file was provided
...@@ -146,25 +171,26 @@ class ContributionTool(BaseTool): ...@@ -146,25 +171,26 @@ class ContributionTool(BaseTool):
raise ValueError, "could not determine portal type" raise ValueError, "could not determine portal type"
# So we will simulate WebDAV to get an empty object # So we will simulate WebDAV to get an empty object
# woith PUT_factory # with PUT_factory
ob = self.PUT_factory( file_name, None, None ) ob = self.PUT_factory( file_name, None, None )
# Then put the file inside ourselves for a short while # Then put the file inside ourselves for a short while
BaseTool._setObject(self, name, ob) #BaseTool._setObject(self, name, ob)
document = self[name] #document = self[name]
# Then edit the document contents (so that upload can happen)
document._edit(**kw)
# Remove the object from ourselves # Remove the object from ourselves
self._delObject(name, ob) #self._delObject(name, ob)
# Move it to where it belongs # Move it to where it belongs
if not discover_metadata: setattr(self, NO_DISCOVER_METADATA_KEY, 1) if not discover_metadata: setattr(self, NO_DISCOVER_METADATA_KEY, 1)
setattr(ob, USER_NAME_KEY, user_login) setattr(ob, USER_NAME_KEY, user_login)
document = self._setObject(name, ob) #document = self._setObject(name, ob)
# Reindex it and return it # Reindex it and return it
# because PUT_factory unwraps the object, we have to get it from volatile, grrr...
document = getattr(self, TEMP_NEW_OBJECT_KEY)[0]
# Then edit the document contents (so that upload can happen)
#document._edit(**kw)
document.immediateReindexObject() document.immediateReindexObject()
return document return document
...@@ -177,21 +203,36 @@ class ContributionTool(BaseTool): ...@@ -177,21 +203,36 @@ class ContributionTool(BaseTool):
pass pass
security.declareProtected(Permissions.ModifyPortalContent,'getPropertyDictFromFileName') security.declareProtected(Permissions.ModifyPortalContent,'getPropertyDictFromFileName')
def getPropertyDictFromFileName(self, fname): def getPropertyDictFromFileName(self, file_name):
""" """
Gets properties from filename. File name is parsed with a regular expression Gets properties from filename. File name is parsed with a regular expression
set in preferences. The regexp should contain named groups. set in preferences. The regexp should contain named groups.
""" """
if file_name is None:
return {}
property_dict = {}
rx_src = self.portal_preferences.getPreferredDocumentFileNameRegularExpression() rx_src = self.portal_preferences.getPreferredDocumentFileNameRegularExpression()
if not rx_src: if rx_src:
return
rx_parse = re.compile() rx_parse = re.compile()
if rx_parse is None: if rx_parse is not None:
return try:
dict = rx_parse.match(fname) property_dict = rx_parse.match(file_name).groupdict()
except AttributeError: # no match
pass
method = self._getTypeBasedMethod('getPropertyDictFromFileName', method = self._getTypeBasedMethod('getPropertyDictFromFileName',
fallback_script_id = 'ContributionTool_getPropertyDictFromFileName') fallback_script_id = 'ContributionTool_getPropertyDictFromFileName')
return method(fname, **dict) property_dict = method(file_name, property_dict)
if not property_dict.has_key('portal_type'):
# we have to find candidates by file extenstion
try:
index = file_name.rfind('.')
if index != -1:
ext = file_name[index+1:]
property_dict['portal_type'] = self.ContributionTool_getCandidateTypeListByExtension(ext)
except ValueError: # no dot in file name
pass
return property_dict
# WebDAV virtual folder support # WebDAV virtual folder support
def _setObject(self, name, ob, user_login=None): def _setObject(self, name, ob, user_login=None):
...@@ -219,6 +260,8 @@ class ContributionTool(BaseTool): ...@@ -219,6 +260,8 @@ class ContributionTool(BaseTool):
# Find the portal type based on file name and content # Find the portal type based on file name and content
# We provide ob in the context of self to make sure scripting is possible # We provide ob in the context of self to make sure scripting is possible
portal_type = self.findTypeName(name, ob.__of__(self)) portal_type = self.findTypeName(name, ob.__of__(self))
if portal_type is None:
raise TypeError, "Unable to determine portal type"
# We know the portal_type, let us find the module # We know the portal_type, let us find the module
module = self.getDefaultModule(portal_type) module = self.getDefaultModule(portal_type)
...@@ -231,10 +274,37 @@ class ContributionTool(BaseTool): ...@@ -231,10 +274,37 @@ class ContributionTool(BaseTool):
# We can now discover metadata unless NO_DISCOVER_METADATA_KEY was set on ob # We can now discover metadata unless NO_DISCOVER_METADATA_KEY was set on ob
document = module[new_id] document = module[new_id]
# store as volatile to be able to retrieve in a while
# keep name (to doublecheck this is the one)
# because PUT_factory will eventually call it by file name
setattr(self, TEMP_NEW_OBJECT_KEY, (document, name))
user_login = getattr(self, USER_NAME_KEY, None) user_login = getattr(self, USER_NAME_KEY, None)
if not getattr(ob, NO_DISCOVER_METADATA_KEY, 0): document.discoverMetadata(file_name=name, user_login=user_login) if not getattr(ob, NO_DISCOVER_METADATA_KEY, 0): document.discoverMetadata(file_name=name, user_login=user_login)
# Return document to newContent method # Return document to newContent method
return document return document
def _getOb(self, id, default=_marker):
"""
Check for volatile temp object info first
and try to find it
"""
ob, new_id = getattr(self, TEMP_NEW_OBJECT_KEY, (None, None))
if ob is not None:
if new_id == id:
return ob
return BaseTool._getOb(self, id, default)
def _delOb(self, id):
"""
We don't need to delete, since we never set here
"""
pass
InitializeClass(ContributionTool) InitializeClass(ContributionTool)
# vim: filetype=python syntax=python shiftwidth=2
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment