Creating a file content type with preview

Skip to first unread message

Marcel Maré

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


Andreas Kaiser

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:
For a real world example see
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
on that topic.



Marcel Maré

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 Maré

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é

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]

class PreviewFile(SaveDataMixin, Content):
id = Column(ForeignKey(, primary_key=True)

type_info = Content.type_info.copy(
title=_(u'Preview File'),
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?


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/", line 58, in main
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/pyramid/scripts/", line 328, in run
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/pyramid/scripts/", 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/", 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/", line 272, in loadobj
    return context.create()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/", 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/", line 203, in invoke
    app = context.app_context.create()
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/paste/deploy/", 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/", 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/", line 55, in fix_call
    val = callable(*args, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/", line 187, in main
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/", line 863, in initialize_sql
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/", line 45, in populate
    if DBSession.query( == 0:
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", 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/", 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/", line 110, in __init__
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", line 120, in _set_entities
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", line 137, in _set_entity_selectables
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", 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/", 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/", line 1893, in _with_polymorphic_mappers
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", line 2771, in configure_mappers
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/event/", line 218, in __call__
    fn(*args, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/orm/", line 613, in wrap
    fn(*arg, **kw)
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/sqlalchemy/ext/declarative/", line 144, in after_configured
  File "/Users/mjm/Dropbox/Devel/_Experiments/pyramid/venv2/lib/python2.7/site-packages/kotti/", 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/", line 193, in __getitem__
    return self._data[key]
KeyError: 'data'

Oshane Bailey

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
0 new messages