From ed0d168a97a178f5d5081f66d9afd088856aac08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Wed, 9 Jan 2013 10:39:51 +0100 Subject: [PATCH] add basic import of files --- src/collective/dms/batchimport/batchimport.py | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/src/collective/dms/batchimport/batchimport.py b/src/collective/dms/batchimport/batchimport.py index fd612ec..f569b25 100644 --- a/src/collective/dms/batchimport/batchimport.py +++ b/src/collective/dms/batchimport/batchimport.py @@ -1,9 +1,16 @@ +import os +import logging + from zope.interface import Interface from zope import schema +from zope import component +from Products.CMFCore.utils import getToolByName from Products.Five.browser import BrowserView from plone.autoform.directives import widget +from plone.namedfile.file import NamedBlobFile +from plone.registry.interfaces import IRegistry from collective.z3cform.datagridfield import DataGridFieldFactory from collective.z3cform.datagridfield.registry import DictRow @@ -12,10 +19,14 @@ from plone.app.registry.browser import controlpanel from . import _ +log = logging.getLogger('collective.dms.batchimport') + + class ICodeTypeMapSchema(Interface): code = schema.TextLine(title=_("Code")) portal_type = schema.TextLine(title=_("Portal Type")) + class ISettings(Interface): fs_root_directory = schema.TextLine( title=_("FS Root Directory")) @@ -27,8 +38,74 @@ class ISettings(Interface): ) widget(code_to_type_mapping=DataGridFieldFactory) + class BatchImporter(BrowserView): - pass + def __call__(self): + settings = component.getUtility(IRegistry).forInterface(ISettings, False) + + if not settings.fs_root_directory: + log.warning('settings.fs_root_directory is not defined') + return + + if not os.path.exists(settings.fs_root_directory): + log.warning('settings.fs_root_directory do not exist') + return + + self.code_to_type_mapping = dict() + for mapping in settings.code_to_type_mapping: + self.code_to_type_mapping[mapping['code']] = mapping['portal_type'] + + for basename, dirnames, filenames in os.walk(settings.fs_root_directory): + # first pass, handle metadata files (TODO) + + # second pass, handle other files, creating individual documents + for filename in filenames: + filepath = os.path.join(basename, filename) + foldername = basename[len(settings.fs_root_directory):] + self.import_one(filepath, foldername) + + # TODO: return the number of files that have been successfully imported. + return 'OK' + + def get_folder(self, foldername): + folder = getToolByName(self.context, 'portal_url').getPortalObject() + for part in foldername.split('/'): + if not part: + continue + folder = getattr(folder, part) + return folder + + def import_one(self, filepath, foldername): + filename = os.path.basename(filepath) + try: + folder = self.get_folder(foldername) + except AttributeError: + log.warning("the directory on the filesystem doesn't match a plone folder") + return + code = filename.split('-', 1)[0] + portal_type = self.code_to_type_mapping.get(code) + if not portal_type: + log.warning("no portal type associated to this code") + return + + plone_utils = getToolByName(self.context, 'plone_utils') + + # TODO: give the document an appropriate title + document_title = os.path.splitext(filename)[0] + + document_id = plone_utils.normalizeString(document_title) + if hasattr(folder, document_id): + log.warning("document already exists") + return + + log.info("creating the document for real (%s)" % document_id) + folder.invokeFactory(portal_type, id=document_id, title=document_title) + + document = folder[document_id] + + document_file = NamedBlobFile(file(filepath).read(), filename=unicode(filename)) + document.invokeFactory('dmsmainfile', id='main', title=_(u'Main File'), + file=document_file) class ControlPanelEditForm(controlpanel.RegistryEditForm):