Creating a file content type with preview

31 views
Skip to first unread message

Marcel Maré

unread,
Apr 21, 2016, 1:12:04 PM4/21/16
to Kotti
I'd like to create a file like content type with an image preview. For example when one uploads a pdf file a background process would create a series of images of pages. 
Since I'm not very familiar with Pyramid/Kotti yet I have some architectural questions: 

I don't know where to put the preview images. Could I (ab)use kotti.resources.Node.annotations for this? Or should I put the images in filedepot and store the references in the content type?
Where should I put code that should run when the user has posted the add-form? Override something from AddFormView?

Any pointers welcome. TIA

Marcel


Andreas Kaiser

unread,
Apr 21, 2016, 2:36:24 PM4/21/16
to Kotti
I'd just add one or more Depot filters to my content type. Fortunately
Kotti makes that *very* easy:
https://kotti.readthedocs.org/en/testing/developing/advanced/blobs.html.
For a real world example see
https://github.com/Kotti/kotti_image/blob/master/kotti_image/resources.py.
You probably need to implement a custom filter, but should be about all
you need to do. Your uploaded files will be passed to the filter
whenever you add or edit a file and the filter will save whatever it
produces as an attachment to the actual file. After that it can be
accessed via the node's data attribute. Also see
http://depot.readthedocs.org/en/latest/database.html#custom-behaviour-in-attachments
on that topic.


HTH,

Andreas

Marcel Maré

unread,
Apr 21, 2016, 5:00:38 PM4/21/16
to Kotti
Yes that makes sense. Didn't know that the depot functionality was exposed through the UploadedFileField.

Thanks again Andreas for the prompt reply.

Marcel

Marcel Maré

unread,
Apr 22, 2016, 1:37:21 AM4/22/16
to Kotti
I noticed from the Image source code that kotti.resources.SaveDataMixin has an undocumented but handy data_filters property. That's nice to know.

Marcel Maré

unread,
Apr 29, 2016, 5:43:40 PM4/29/16
to Kotti
I've hit a speed bump.

Since I want to use the data_filters class property (of the SaveDataMixin) I thought it best to create a content type identical to kotti.resources.File (because I think File cannot be subclassed). This is it, with only the name in the type_info changed. By marking it as an File implementer I hoped being able to reuse File's views. [Later I would create an additional view that would make use of the output of the datafilter]

@implementer(IFile)
class PreviewFile(SaveDataMixin, Content):
id = Column(ForeignKey(Content.id), primary_key=True)

type_info = Content.type_info.copy(
name=u'PreviewFile',
title=_(u'Preview File'),
add_view=u'add_file',
addable_to=[u'Document'],
selectable_default_views=[],
uploadable_mimetypes=['*', ],
)

However the code doesn't work. See stack trace below. There seems to be a "data" member missing. I'd expect SaveDataMixin to provide this. 

What gives?

Marcel

Traceback (most recent call last):
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/bin/pserve", line 9, in <module>
    load_entry_point('pyramid', 'console_scripts', 'pserve')()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/pyramid/scripts/pserve.py", line 58, in main
    return command.run()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/pyramid/scripts/pserve.py", line 328, in run
    global_conf=vars)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/pyramid/scripts/pserve.py", line 363, in loadapp
    return loadapp(app_spec, name=name, relative_to=relative_to, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 247, in loadapp
    return loadobj(APP, uri, name=name, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 272, in loadobj
    return context.create()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 710, in create
    return self.object_type.invoke(self)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 203, in invoke
    app = context.app_context.create()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 710, in create
    return self.object_type.invoke(self)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/loadwsgi.py", line 146, in invoke
    return fix_call(context.object, context.global_conf, **context.local_conf)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/util.py", line 55, in fix_call
    val = callable(*args, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/__init__.py", line 187, in main
    initialize_sql(engine)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/resources.py", line 863, in initialize_sql
    populate()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/populate.py", line 45, in populate
    if DBSession.query(Node.id).count() == 0:
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 150, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1260, in query
    return self._query_cls(entities, self, **kwargs)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 110, in __init__
    self._set_entities(entities)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 120, in _set_entities
    self._set_entity_selectables(self._entities)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 137, in _set_entity_selectables
    ext_info.mapper._equivalent_columns
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 153, in _mapper_loads_polymorphically_with
    for m2 in mapper._with_polymorphic_mappers or [mapper]:
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 747, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1893, in _with_polymorphic_mappers
    configure_mappers()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2771, in configure_mappers
    Mapper.dispatch._for_class(Mapper).after_configured()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/event/attr.py", line 218, in __call__
    fn(*args, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/events.py", line 613, in wrap
    fn(*arg, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 144, in after_configured
    self.cls.__declare_last__()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/resources.py", line 664, in __declare_last__
    args = (mapper.attrs['data'], 'set', _SQLAMutationTracker._field_set)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/util/_collections.py", line 193, in __getitem__
    return self._data[key]
KeyError: 'data'
 

Oshane Bailey

unread,
Jul 6, 2016, 1:41:40 AM7/6/16
to Kotti
Check out kotti_pdf, which creates a preview of the PDF file.
Reply all
Reply to author
Forward
0 new messages