diff --git a/setup.py b/setup.py
index 3eb6be9..5e4edd9 100644
--- a/setup.py
+++ b/setup.py
@@ -45,6 +45,7 @@ setup(
'setuptools',
'five.grok',
'plone.app.contenttypes',
+ 'Products.SQLAlchemyDA',
],
entry_points="""
[z3c.autoinclude.plugin]
diff --git a/src/pfwbged/tabellio/configure.zcml b/src/pfwbged/tabellio/configure.zcml
index 64ab71a..15d1239 100644
--- a/src/pfwbged/tabellio/configure.zcml
+++ b/src/pfwbged/tabellio/configure.zcml
@@ -11,4 +11,12 @@
+
+
+
diff --git a/src/pfwbged/tabellio/documents.py b/src/pfwbged/tabellio/documents.py
new file mode 100644
index 0000000..336d303
--- /dev/null
+++ b/src/pfwbged/tabellio/documents.py
@@ -0,0 +1,175 @@
+import datetime
+
+from plone import api
+from five import grok
+from zope.interface import implements
+from AccessControl import ClassSecurityInfo, getSecurityManager
+from AccessControl.Permissions import access_contents_information
+
+from plone.dexterity.content import Container
+from plone.supermodel import model
+
+class IDocumentsFolder(model.Schema):
+ pass
+
+
+class DocumentsFolder(Container):
+ implements(IDocumentsFolder)
+ security = ClassSecurityInfo()
+
+ _v_dbcache = None # volatile attribute
+
+ @property
+ def db_connection(self):
+ return api.portal.get().db._wrapper.connection
+
+ def __iter__(self):
+ if not self._v_dbcache:
+ self._v_dbcache = {}
+
+ cursor = self.db_connection.cursor()
+ cursor.execute('''SELECT id, ts, intit, textdefts
+ FROM t_document''')
+ while True:
+ row = cursor.fetchone()
+ if row is None:
+ break
+ rowid, ts, intit, textdfts = row
+ self._v_dbcache[rowid] = {'ts': ts, 'intit': intit, 'textdfts': textdfts}
+ yield rowid
+
+ cursor.close()
+
+ def __getitem__(self, id):
+ try:
+ int(id)
+ except ValueError:
+ pass
+ else:
+ cursor = self.db_connection.cursor()
+ cursor.execute('''SELECT id, intit, sess
+ FROM t_document
+ WHERE id = %(id)s''', {'id': id})
+ row = cursor.fetchone()
+ if row is None:
+ return super(DocumentsFolder, self).__getitem__(id)
+ cursor.close()
+
+ row_id, intit, sess = row
+ from collective.dms.basecontent.dmsfile import DmsFile
+ t = DmsFile(id=row_id, title=intit, label=sess)
+ t.portal_type = 'dmsmainfile'
+ from Acquisition import aq_chain
+ return aq_chain(t.__of__(self))[0]
+ return super(DocumentsFolder, self).__getitem__(id)
+
+ def keys(self):
+ return list(self.__iter__())
+
+ def getFolderContents(self, *args, **kwargs):
+ folder = self
+ parent_path = '/'.join(folder.getPhysicalPath()) + '/'
+ parent_url = folder.absolute_url() + '/'
+
+ class FakeBrain(object):
+ def __init__(self, object_id):
+ self.id = object_id
+ self._object = None
+ self.getId = object_id
+ self.getObjSize = 0
+ self.is_folderish = True
+ self.portal_type = 'dmsmainfile'
+ self.Creator = 'Tabellio'
+
+ def Type(self):
+ return self.portal_type
+
+ def get_object_attibute(self, attribute):
+ if not self._object:
+ self._object = folder[self.id]
+ return getattr(self._object, attribute)
+
+ @property
+ def modified(self):
+ if folder._v_dbcache and self.id in folder._v_dbcache:
+ return folder._v_dbcache[self.id]['ts']
+ return datetime.datetime.now()
+
+ def ModificationDate(self):
+ return self.modified
+
+ @property
+ def CreationDate(self):
+ if folder._v_dbcache and self.id in folder._v_dbcache:
+ t = folder._v_dbcache[self.id]['textdfts']
+ if t:
+ return t
+ return datetime.datetime.now()
+
+ @property
+ def title(self):
+ if folder._v_dbcache and self.id in folder._v_dbcache:
+ return folder._v_dbcache[self.id]['intit']
+ return self.get_object_attibute('title')
+
+ def pretty_title_or_id(self):
+ if self.title:
+ return self.title
+ return self.id
+
+ def Title(self):
+ return self.title
+
+ review_state = None
+ Description = None
+
+ def getPath(self):
+ return parent_path + self.id
+
+ def getURL(self, relative=True):
+ if relative:
+ return self.id
+ return parent_url + self.id
+
+ # plone.batching.batch doesn't support generators
+ t = []
+ for k in self.__iter__():
+ t.append(FakeBrain(k))
+ return t
+
+ # Acquisition wrappers don't support the __iter__ slot, so re-implement
+ # iteritems to call __iter__ directly.
+ def iteritems(self):
+ for k in self.__iter__():
+ yield (k, self[k])
+
+ security.declareProtected(access_contents_information,
+ 'objectIds')
+ def objectIds(self, spec=None):
+ # Returns a list of subobject ids of the current object.
+ # If 'spec' is specified, returns objects whose meta_type
+ # matches 'spec'.
+ assert spec is None, 'spec argument unsupported'
+ return self.__iter__()
+
+
+ security.declareProtected(access_contents_information,
+ 'objectValues')
+ def objectValues(self, spec=None):
+ # Returns a list of actual subobjects of the current object.
+ # If 'spec' is specified, returns only objects whose meta_type
+ # match 'spec'.
+ assert spec is None, 'spec argument unsupported'
+ for k in self.__iter__():
+ yield self[k]
+
+ security.declareProtected(access_contents_information,
+ 'objectItems')
+ def objectItems(self, spec=None):
+ # Returns a list of (id, subobject) tuples of the current object.
+ # If 'spec' is specified, returns only objects whose meta_type match
+ # 'spec'
+ assert spec is None, 'spec argument unsupported'
+ return self.iteritems()
+
+grok.context(DocumentsFolder)
diff --git a/src/pfwbged/tabellio/profiles/default/metadata.xml b/src/pfwbged/tabellio/profiles/default/metadata.xml
new file mode 100644
index 0000000..58812bd
--- /dev/null
+++ b/src/pfwbged/tabellio/profiles/default/metadata.xml
@@ -0,0 +1,6 @@
+
+ 0.1
+
+
+
+
diff --git a/src/pfwbged/tabellio/profiles/default/types.xml b/src/pfwbged/tabellio/profiles/default/types.xml
new file mode 100644
index 0000000..13c4681
--- /dev/null
+++ b/src/pfwbged/tabellio/profiles/default/types.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/src/pfwbged/tabellio/profiles/default/types/pfwbged.tabellio.documentsfolder.xml b/src/pfwbged/tabellio/profiles/default/types/pfwbged.tabellio.documentsfolder.xml
new file mode 100644
index 0000000..7a58827
--- /dev/null
+++ b/src/pfwbged/tabellio/profiles/default/types/pfwbged.tabellio.documentsfolder.xml
@@ -0,0 +1,47 @@
+
+
+ Documents from Tabellio
+ string:${portal_url}/++resource++pfwbged.tabellio.documentsfolder_icon.png
+
+ string:${folder_url}/++add++pfwbged.tabellio.documentsfolder
+
+ view
+ True
+ True
+ False
+ view
+
+
+
+ False
+ cmf.AddPortalContent
+ pfwbged.tabellio.documents.DocumentsFolder
+
+
+
+
+
+
+ True
+
+
+
+
+
+ pfwbged.tabellio.documents.IDocumentsFolder
+
+
+
+
+
+
+
+
+
+
+