diff --git a/src/pfwbged/tabellio/__init__.py b/src/pfwbged/tabellio/__init__.py index 93c83d9..4052d59 100644 --- a/src/pfwbged/tabellio/__init__.py +++ b/src/pfwbged/tabellio/__init__.py @@ -7,3 +7,8 @@ _ = MessageFactory('pfwbged.tabellio') def initialize(context): """Initializer called when used as a Zope 2 product.""" + pass + + +from .monkey import patchDocumentViewer +patchDocumentViewer() diff --git a/src/pfwbged/tabellio/documents.py b/src/pfwbged/tabellio/documents.py index 88ad795..ddffcc2 100644 --- a/src/pfwbged/tabellio/documents.py +++ b/src/pfwbged/tabellio/documents.py @@ -1,5 +1,8 @@ import datetime +import os import psycopg2.extras +import urllib2 +import urlparse from Acquisition import aq_chain from plone import api @@ -11,6 +14,7 @@ from AccessControl.Permissions import access_contents_information from zope import schema from plone.dexterity.content import Container, Item from plone.supermodel import model +from plone.namedfile.file import NamedBlobFile from collective.dms.basecontent.dmsdocument import IDmsDocument, DmsDocument from collective.dms.basecontent.dmsfile import DmsFile @@ -180,6 +184,54 @@ class IDocument(IDmsDocument): noannexe = schema.TextLine(title=_('Appendix Number'), required=False) + +class RemoteFile(NamedBlobFile): + _v_filename = None + + def __init__(self, url): + self.url = url + self._file_data = None + + @property + def filename(self): + return os.path.basename(urlparse.urlparse(self.url).path) + + @property + def contentType(self): + return 'application/pdf' + + @property + def data(self): + if self._file_data: + return self._file_data + self._file_data = urllib2.urlopen(self.url).read() + return self._file_data + + @property + def _blob(self): + # compatibility with collective.documentviewer + from ZODB.blob import Blob + blob = Blob() + f = blob.open('w') + f.write(self.data) + f.close() + return blob + + def getSize(self): + return len(self.data) + + +class TabellioDmsFile(DmsFile): + + @property + def file(self): + if self.base_id.startswith('pdf-') or self.base_id.startswith('legi-') or \ + self.base_id.startswith('doc-'): + # get it from Tabellio + return None + return RemoteFile('http://archive.pfwb.be/' + self.base_id) + + class Document(DmsDocument): implements(IDocument) _v_portal_type = 'pfwbged.tabellio.document' @@ -197,7 +249,7 @@ class Document(DmsDocument): raise KeyError() obj = cls() obj.portal_type = cls._v_portal_type - obj.id = row.id + obj.id = str(row.id) obj.title = row.intit obj.doctype = typenames.MAPPING.get(row.type, row.type) obj.no = row.no @@ -215,13 +267,15 @@ class Document(DmsDocument): def __getitem__(self, id): if id.startswith('version-'): - t = DmsFile() - t.id = id.split('-', 1)[1] - t.title = t.id - t.file = None - t.UID = lambda: 'tabellio-' + t.id + t = TabellioDmsFile() + t.id = str(id) + t.base_id = id.split('-', 1)[1] + t.title = t.base_id + uid = str(''.join(reversed(id)) + '-tabellio') + t.UID = lambda: uid t.portal_type = 'dmsmainfile' - return aq_chain(t.__of__(self))[0] + t = aq_chain(t.__of__(self))[0] + return t return super(Document, self).__getitem__(id) diff --git a/src/pfwbged/tabellio/monkey.py b/src/pfwbged/tabellio/monkey.py new file mode 100644 index 0000000..5d59c49 --- /dev/null +++ b/src/pfwbged/tabellio/monkey.py @@ -0,0 +1,55 @@ +from Acquisition import aq_parent + +from persistent.dict import PersistentDict +from DateTime import DateTime +from zope.annotation.interfaces import IAnnotations + +import collective.documentviewer.convert +import collective.documentviewer.settings +import collective.documentviewer.views +from Products.Five.browser.resource import DirectoryResource + +import plone.namedfile.utils + +from . import documents + +# Monkeypatching of various collective.documentviewer parts + +class PDFFiles(collective.documentviewer.views.PDFFiles): + # don't check permissions for tabellio thumbnails; this would otherwise + # require the objects to have a stable UID and to be registered in the + # catalog. + def publishTraverse(self, request, name): + if name.endswith('-noisrev-tabellio'): + fi = DirectoryResource.publishTraverse(self, request, name) + return fi + return super(PDFFiles, self).publishTraverse(request, name) + + +orig_init = collective.documentviewer.settings.Base.__init__ +def base_init(self, context): + # for our transient files we cannot store documentviewer information in + # the object annotations so we have to create them under varying names + # in the DocumentsFolder object. + if isinstance(context, documents.TabellioDmsFile): + self.context = context + tabellio_folder = aq_parent(aq_parent(context)) + annotations = IAnnotations(tabellio_folder) + # store metadata in top tabellio folder + self._metadata = annotations.get('collective.documentviewer-%s' % context.id, None) + if self._metadata is None: + self._metadata = PersistentDict() + self._metadata['last_updated'] = DateTime('1901/01/01').ISO8601() + self.storage_version = collective.documentviewer.settings.STORAGE_VERSION + annotations['collective.documentviewer-%s' % context.id] = self._metadata + else: + orig_init(self, context) + + +def patchDocumentViewer(): + collective.documentviewer.views.PDFFiles = PDFFiles + collective.documentviewer.settings.Base.__init__ = base_init + collective.documentviewer.convert.Converter.isIndexationEnabled = lambda x: True + + # avoid streaming files as the blob hack breaks this + plone.namedfile.utils.filestream_iterator = None