odoo/odoo — pull request #1870 by naglis (2014-08-19 20:07:11+00:00)
Title: [need review] Download action module proposal

_Please don't consider this for merging, at the moment I only need your opinion/code review._

Hello,
as part of my internship I've created this module and I would like to know your opinion:

- The functionality of the module can/should be added to the core
- The module could/should better be added as an addon
- The module should stay as a 3rd party addon
- It's generally a bad idea and it should not be used

I would really appreciate any comments on the code, critique, improvement ideas or thoughts on the security weaknesses of this approach.

Thanks you for your time,
Naglis

## What it does
It's main idea is to allow to generate downloads on the fly inside a button action. It also allows to download a file from a binary field inside DB, if you provide the model, field and ID of the record (_I was also thinking about allowing downloads of files from disk, when the full path to the file is provided_).

You can also provide a filename/mimetype (optional).

## An example
Let's say you have a button which triggers an action method on a model, which in turn returns an action `dict` that is sent to the client. Inside the method, we generate a file.

```python

@download_file
def act_download(self, cr, uid, ids, *args, **kwargs):

import io
import os

bio = io.BytesIO()
bio.write(os.urandom(1024 * 1024)) # 1MB

return {
'type': 'ir.actions.download',
'filename': 'test.bin',
'file': bio.getvalue()
}
```

As you can see, the generated file is returned inside the `dict`. The `@download_file` decorator extracts the file and stores it in a `dict` inside a model (in memory), so that it wouldn't get sent to the client. The decorator also puts a download ID inside the `dict`.

The client get's a download ID, and an action `ir.actions.download`, and triggers the controller (via [session.get_file](https://github.com/odoo/odoo/blob/d7b33f18f0b7af723d14bb4d31099d2369b9214e/addons/web/static/src/js/core.js#L411)), which, given the download ID, returns the file, so the download occurs in the same window with UI freeze/unfreeze.

I've added a CRON job, which clears unclaimed files every 10 minutes, in case the file was generated, but wasn't downloaded.

The download ID is the MD5 of the file, so duplicate files wouldn't get stored. As a security measure, I also store the UID of the user who generated the file and only allow that UID to initiate the download.

I've tested it on Odoo v8.0.