Skip to content
Open
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
118 changes: 118 additions & 0 deletions mail_drop_target/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

==========================
Drag & drop emails to Odoo
==========================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:e919dcef6dab8ff8aaa3381bae42c978fa61e3c9bbc7a8c5cca62e850cfb2525
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fmail-lightgray.png?logo=github
:target: https://github.com/OCA/mail/tree/17.0/mail_drop_target
:alt: OCA/mail
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/mail-17-0/mail-17-0-mail_drop_target
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/mail&target_branch=17.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module was written to allow users to drag&drop emails from their
desktop to Odoo.

It supports as well RFC822 .eml files as Outlook .msg (those only if `an
extra library <https://github.com/mattgwwalker/msg-extractor>`__ is
installed) files.

When the mail is dropped to an odoo record, it will automatically send a
notification of that new message that has been added to all the existing
followers. It is possible to disable this notification.

**Table of contents**

.. contents::
:local:

Usage
=====

To use this module, you need to:

1. save your emails on the desktop / somewhere in the file system
2. drag them to your browser, and drop them on the chatter of the record
you want to attach your email to

Known issues / Roadmap
======================

- most mail clients won't allow you to drag mails directly from the mail
client, you'll need some plugin for that
- for corporate environments, it might be feasible to support imap URLs
and get the mail in question on the server side

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/mail/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/mail/issues/new?body=module:%20mail_drop_target%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* Therp BV

Contributors
------------

- Holger Brunn <hbrunn@therp.nl>
- Enric Tobella <etobella@creublanca.es>
- Lois Rilo <lois.rilo@forgeflow.com>
- Nguyen Minh Chien <chien@trobz.com>
- Prabhu Appalapuri<prabhu.appalapuri@samsa-it.de>
- Artiom Kichojal<Artiom.Kichojal@samsa-it.de>

Other credits
-------------

*The migration of this module from 16.0 to 17.0 was financially
supported by SAMSA-IT*\ The migration of this module from 15.0 to 16.0
was financially supported by Camptocamp

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

This module is part of the `OCA/mail <https://github.com/OCA/mail/tree/17.0/mail_drop_target>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
6 changes: 6 additions & 0 deletions mail_drop_target/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).


from . import controllers
from . import models
20 changes: 20 additions & 0 deletions mail_drop_target/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
{
"name": "Drag & drop emails to Odoo",
"version": "17.0.1.0.0",
"author": "Therp BV,Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Discuss",
"website": "https://github.com/OCA/mail",
"summary": "Attach emails to Odoo by dragging them from your desktop",
"depends": ["mail"],
"external_dependencies": {"python": ["extract_msg", "cryptography<37"]},
"data": ["views/res_config_settings_views.xml"],
"assets": {
"web.assets_backend": [
"mail_drop_target/static/src/core/common/thread_service_patch.esm.js",
"mail_drop_target/static/src/js/attachment_upload_service.esm.js",
],
},
}
3 changes: 3 additions & 0 deletions mail_drop_target/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import discuss
51 changes: 51 additions & 0 deletions mail_drop_target/controllers/discuss.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright Nguyen Minh Chien (chien@trobz.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

from odoo import http
from odoo.exceptions import AccessError, UserError
from odoo.http import request
from odoo.tools.translate import _

from odoo.addons.mail.controllers.attachment import AttachmentController


class DiscussControllerInherit(AttachmentController):
@http.route("/mail/attachment/upload", methods=["POST"], type="http", auth="public")
def mail_attachment_upload(
self, ufile, thread_id, thread_model, is_pending=False, **kwargs
):
if not is_pending or is_pending == "false":
# Add this point, make sure the message related to the uploaded
# file does exist.
resp = self.mail_attachment_upload_email(ufile, thread_id, thread_model)
if resp:
return resp

return super().mail_attachment_upload(
ufile, thread_id, thread_model, is_pending, **kwargs
)

def mail_attachment_upload_email(self, ufile, thread_id, thread_model):
channel_member = request.env["discuss.channel.member"]
if thread_model == "mail.channel":
channel_member = request.env[
"discuss.channel.member"
]._get_as_sudo_from_request_or_raise(
request=request, channel_id=int(thread_id)
)

try:
mail_resp = channel_member.env["ir.attachment"].read_mail_file_content(
ufile.filename, ufile.read(), int(thread_id), thread_model
)
ufile.seek(0)
if not mail_resp:
return False
responseData = {"email_upload": 1}
except AccessError:
responseData = {
"error": _("You are not allowed to upload an attachment here.")
}
except UserError as err:
responseData = {"error": str(err)}
return request.make_json_response(responseData)
94 changes: 94 additions & 0 deletions mail_drop_target/i18n/it.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * mail_drop_target
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 17.0+e\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-10-04 09:42+0000\n"
"PO-Revision-Date: 2024-10-04 09:42+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"

#. module: mail_drop_target
#: model:ir.model,name:mail_drop_target.model_ir_attachment
msgid "Attachment"
msgstr "Allegato"

#. module: mail_drop_target
#: model:ir.model,name:mail_drop_target.model_res_config_settings
msgid "Config Settings"
msgstr "Impostazioni di configurazione"

#. module: mail_drop_target
#: model_terms:ir.ui.view,arch_db:mail_drop_target.res_config_settings_view_form_mail_drop_target
msgid "Disable Mail Drag&Drop Notification"
msgstr "Disabilita notifica e-mail trascina&rilascia"

#. module: mail_drop_target
#: model:ir.model.fields,field_description:mail_drop_target.field_res_config_settings__disable_notify_mail_drop_target
msgid "Disable Notification followers on mail dropped to a Thread"
msgstr "Disabilita notifica chi segue per e-mail inserita in una discussione"

#. module: mail_drop_target
#: model:ir.model,name:mail_drop_target.model_mail_thread
msgid "Email Thread"
msgstr "Discussione e-mail"

#. module: mail_drop_target
#. odoo-javascript
#: code:addons/mail_drop_target/static/src/js/attachment_upload_service.js:0
#, python-format
msgid "File too large"
msgstr ""

#. module: mail_drop_target
#. odoo-python
#: code:addons/mail_drop_target/models/mail_thread.py:0
#, python-format
msgid "Install the msg-extractor library to handle .msg files"
msgstr "Installare la libreria msg-extractor per festire i file .msg"

#. module: mail_drop_target
#. odoo-javascript
#: code:addons/mail_drop_target/static/src/js/attachment_upload_service.js:0
#, python-format
msgid "Server error"
msgstr ""

#. module: mail_drop_target
#. odoo-python
#: code:addons/mail_drop_target/models/mail_thread.py:0
#, python-format
msgid "This message is already imported."
msgstr "Questo messaggio è già stato importato."

#. module: mail_drop_target
#: model_terms:ir.ui.view,arch_db:mail_drop_target.res_config_settings_view_form_mail_drop_target
msgid ""
"When a user drops an email into an existing thread the followers of the "
"thread will not be notified."
msgstr ""

#. module: mail_drop_target
#: model:ir.model.fields,help:mail_drop_target.field_res_config_settings__disable_notify_mail_drop_target
msgid ""
"When this setting is set, when a user drops an email into an existing thread"
" the followers of the thread will not be notified. This sets an "
"ir.config.parameter mail_drop_target.disable_notify"
msgstr ""
"Quanto è attiva questa impostazione, quando un utente rilascia una e.mail in"
" una discussione esistente, chi segue la discussione non verrà avvisato. "
"Questo imposta un ir.config.parameter in mail_drop_target.disable_notify"

#. module: mail_drop_target
#. odoo-python
#: code:addons/mail_drop_target/controllers/discuss.py:0
#, python-format
msgid "You are not allowed to upload an attachment here."
msgstr "Non si ha l'autorizzazione per caricare qui un allegato."
5 changes: 5 additions & 0 deletions mail_drop_target/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import ir_attachment
from . import mail_thread
from . import res_config_settings
49 changes: 49 additions & 0 deletions mail_drop_target/models/ir_attachment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright Nguyen Minh Chien (chien@trobz.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).

import base64
import os

from odoo import api, models


class IrAttachment(models.Model):
_inherit = "ir.attachment"

def _get_email_file_extensions(self):
return ["msg", "eml"]

def _process_email_file_msg(self, res_obj, raw_content):
if not hasattr(res_obj, "message_process_msg"):
return False
message = base64.b64encode(raw_content)
thread_id = res_obj.message_process_msg(
res_obj._name, message, thread_id=res_obj.id
)
return thread_id

@api.model
def _process_email_file_default(self, res_obj, raw_content):
if not hasattr(res_obj, "message_drop"):
return False
message = raw_content
thread_id = res_obj.message_drop(res_obj._name, message, thread_id=res_obj.id)
return thread_id

def read_mail_file_content(self, file_name, raw_content, res_id, res_model):
file_extensions = self._get_email_file_extensions()
name_lst = os.path.splitext(file_name)
file_extension = name_lst[-1].lower().replace(".", "")
if not file_extension or file_extension not in file_extensions:
return False

res_obj = self.env[res_model].browse(res_id)
if not res_obj:
return False

handler = f"_process_email_file_{file_extension}"
if not hasattr(self, handler):
handler = "_process_email_file_default"

res = getattr(self, handler)(res_obj, raw_content)
return res
Loading