Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 56 additions & 1 deletion dms/controllers/main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
# Copyright 2017-2019 MuK IT GmbH
# Copyright 2026 Tecnativa - Víctor Martínez
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo import http
import json
import unicodedata

from odoo import _, http
from odoo.exceptions import AccessError
from odoo.http import request


def clean(name):
return name.replace("\x3c", "")


class OnboardingController(http.Controller):
@http.route("/config/dms.forbidden_extensions", type="json", auth="user")
def forbidden_extensions(self, **_kwargs):
Expand All @@ -13,3 +22,49 @@ def forbidden_extensions(self, **_kwargs):
"dms.forbidden_extensions", default=""
)
}

@http.route("/web/binary/upload_dms_file", type="http", auth="user")
def upload_dms_file(self, ufile, directory_id, callback=None):
"""Similar to the web upload_attachment() method, but customized to
directly create dms.file records.
"""
directory_id = int(directory_id)
files = request.httprequest.files.getlist("ufile")
Model = request.env["dms.file"]
out = """<script language="javascript" type="text/javascript">
var win = window.top.window;
win.jQuery(win).trigger(%s, %s);
</script>"""
args = []
for ufile in files:
filename = ufile.filename
if request.httprequest.user_agent.browser == "safari":
# Safari sends NFD UTF-8 (where é is composed by 'e' and [accent])
# we need to send it the same stuff, otherwise it'll fail
filename = unicodedata.normalize("NFD", ufile.filename)
try:
dms_file = Model.create(
{
"directory_id": directory_id,
"name": filename,
"content": ufile.read(),
}
)
except AccessError:
args.append({"error": _("You are not allowed to upload a file here.")})
except Exception:
args.append({"error": _("Something horrible happened")})
else:
args.append(
{
"filename": clean(filename),
"mimetype": dms_file.mimetype,
"id": dms_file.id,
"size": dms_file.size,
}
)
return (
out % (json.dumps(clean(callback)), json.dumps(args))
if callback
else json.dumps(args)
)
18 changes: 0 additions & 18 deletions dms/models/dms_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,21 +648,3 @@ def get_attachment_object(self, attachment):
"res_model": attachment.res_model,
"mimetype": attachment.mimetype,
}

@api.model
def get_dms_files_from_attachments(self, attachment_ids=None):
"""Get the dms files from uploaded attachments.
:return: An Array of dms files.
"""
if not attachment_ids:
raise UserError(_("No attachment was provided"))

attachments = self.env["ir.attachment"].browse(attachment_ids)

if any(
attachment.res_id or attachment.res_model != "dms.file"
for attachment in attachments
):
raise UserError(_("Invalid attachments!"))

return [self.get_attachment_object(attachment) for attachment in attachments]
74 changes: 15 additions & 59 deletions dms/static/src/js/views/dms_file_upload.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,37 +80,8 @@ export function createFileUploadExtension() {
},

async onChangeFileInput() {
const params = {
csrf_token: odoo.csrf_token,
ufile: [...this.fileInput.el.files],
model: "dms.file",
id: 0,
};

const fileData = await this.http.post(
"/web/binary/upload_attachment",
params,
"text"
);
const attachments = JSON.parse(fileData);
if (attachments.error) {
throw new Error(attachments.error);
}

await this.onUpload(attachments);
},

async onUpload(attachments) {
const self = this;
const attachmentIds = attachments.map((a) => a.id);
const ctx = this.props.context;
const controllerID = this.actionService.currentController.jsId;

if (!attachmentIds.length) {
this.notification.add(_t("An error occurred during the upload"));
return;
}

// Search the correct directory_id value according to the domain
let directory_id = false;
if (this.props.domain) {
Expand All @@ -133,37 +104,22 @@ export function createFileUploadExtension() {
});
}

const attachment_datas = await this.orm.call(
"dms.file",
"get_dms_files_from_attachments",
[],
{attachment_ids: attachmentIds}
);

const attachments_args = [];

attachment_datas.forEach((attachment_data) => {
attachments_args.push({
name: attachment_data.name,
content: attachment_data.datas,
mimetype: attachment_data.mimetype,
directory_id,
});
});
const params = {
csrf_token: odoo.csrf_token,
ufile: [...this.fileInput.el.files],
directory_id: directory_id,
};

this.orm
.call("dms.file", "create", [attachments_args], {
context: ctx,
})
.then(() => {
self.actionService.restore(controllerID);
})
.catch((error) => {
self.notification.add(error.data.message, {
type: "danger",
});
self.actionService.restore(controllerID);
});
const fileData = await this.http.post(
"/web/binary/upload_dms_file",
params,
"text"
);
const attachments = JSON.parse(fileData);
if (attachments.error) {
throw new Error(attachments.error);
}
self.actionService.restore(controllerID);
},
};
}
34 changes: 6 additions & 28 deletions dms_field/static/src/views/dms_list/dms_list_controller.esm.js
Original file line number Diff line number Diff line change
Expand Up @@ -490,40 +490,18 @@ export function getDMSListControllerObject() {
const params = {
csrf_token: odoo.csrf_token,
ufile: [...files],
model: "dms.file",
id: 0,
directory_id: directoryId,
};
const fileData = await this.http.post(
"/web/binary/upload_attachment",
"/web/binary/upload_dms_file",
params,
"text"
);
const attachments = JSON.parse(fileData);
if (attachments.error) {
throw new Error(attachments.error);
const dms_files = JSON.parse(fileData);
if (dms_files.error) {
throw new Error(dms_files.error);
}
const attachmentIds = attachments.map((a) => a.id);
if (!attachmentIds.length) {
return "no_attachments";
}
const attachment_datas = await this.orm.call(
"dms.file",
"get_dms_files_from_attachments",
[],
{
attachment_ids: attachmentIds,
}
);
const attachments_args = [];
attachment_datas.forEach((attachment_data) => {
attachments_args.push({
name: attachment_data.name,
content: attachment_data.datas,
mimetype: attachment_data.mimetype,
directory_id: directoryId,
});
});
return this.orm.call("dms.file", "create", [attachments_args]);
return dms_files.map((a) => a.id);
},
};
}
Expand Down
Loading