Selaa lähdekoodia

chore(typing): Add typing, style fixes

This was going to be a fix at first. Until I realised it couldn't...so I
removed the changes and kept the things back that helped me debug the
issue
version-14
Gavin D'souza 3 vuotta sitten
vanhempi
commit
5503e18817
5 muutettua tiedostoa jossa 52 lisäystä ja 39 poistoa
  1. +17
    -15
      frappe/core/doctype/communication/email.py
  2. +10
    -5
      frappe/core/doctype/communication/mixins.py
  3. +4
    -6
      frappe/email/doctype/email_account/email_account.py
  4. +19
    -12
      frappe/email/doctype/email_queue/email_queue.py
  5. +2
    -1
      frappe/website/utils.py

+ 17
- 15
frappe/core/doctype/communication/email.py Näytä tiedosto

@@ -1,29 +1,32 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# License: MIT. See LICENSE

import frappe
import json
from email.utils import formataddr
from frappe.core.utils import get_parent_doc
from frappe.utils import (get_url, get_formatted_email, cint, list_to_str,
validate_email_address, split_emails, parse_addr, get_datetime)
from frappe.email.email_body import get_message_id
from typing import TYPE_CHECKING, Dict

import frappe
import frappe.email.smtp
import time
from frappe import _
from frappe.utils.background_jobs import enqueue
from frappe.email.email_body import get_message_id
from frappe.utils import (cint, get_datetime, get_formatted_email,
list_to_str, split_emails, validate_email_address)

if TYPE_CHECKING:
from frappe.core.doctype.communication.communication import Communication


OUTGOING_EMAIL_ACCOUNT_MISSING = _("""
Unable to send mail because of a missing email account.
Please setup default Email Account from Setup > Email > Email Account
""")


@frappe.whitelist()
def make(doctype=None, name=None, content=None, subject=None, sent_or_received = "Sent",
sender=None, sender_full_name=None, recipients=None, communication_medium="Email", send_email=False,
print_html=None, print_format=None, attachments='[]', send_me_a_copy=False, cc=None, bcc=None,
flags=None, read_receipt=None, print_letterhead=True, email_template=None, communication_type=None,
ignore_permissions=False):
ignore_permissions=False) -> Dict[str, str]:
"""Make a new communication.

:param doctype: Reference DocType.
@@ -56,7 +59,7 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
cc = list_to_str(cc) if isinstance(cc, list) else cc
bcc = list_to_str(bcc) if isinstance(bcc, list) else bcc

comm = frappe.get_doc({
comm: "Communication" = frappe.get_doc({
"doctype":"Communication",
"subject": subject,
"content": content,
@@ -93,12 +96,13 @@ def make(doctype=None, name=None, content=None, subject=None, sent_or_received =
send_me_a_copy=send_me_a_copy, print_letterhead=print_letterhead)

emails_not_sent_to = comm.exclude_emails_list(include_sender=send_me_a_copy)

return {
"name": comm.name,
"emails_not_sent_to": ", ".join(emails_not_sent_to or [])
"emails_not_sent_to": ", ".join(emails_not_sent_to)
}

def validate_email(doc):
def validate_email(doc: "Communication") -> None:
"""Validate Email Addresses of Recipients and CC"""
if not (doc.communication_type=="Communication" and doc.communication_medium == "Email") or doc.flags.in_receive:
return
@@ -114,8 +118,6 @@ def validate_email(doc):
for email in split_emails(doc.bcc):
validate_email_address(email, throw=True)

# validate sender

def set_incoming_outgoing_accounts(doc):
from frappe.email.doctype.email_account.email_account import EmailAccount
incoming_email_account = EmailAccount.find_incoming(


+ 10
- 5
frappe/core/doctype/communication/mixins.py Näytä tiedosto

@@ -1,3 +1,4 @@
from typing import List
import frappe
from frappe import _
from frappe.core.utils import get_parent_doc
@@ -194,14 +195,18 @@ class CommunicationEmailMixin:
return _("Leave this conversation")
return ''

def exclude_emails_list(self, is_inbound_mail_communcation=False, include_sender=False):
def exclude_emails_list(self, is_inbound_mail_communcation=False, include_sender=False) -> List:
"""List of mail id's excluded while sending mail.
"""
all_ids = self.get_all_email_addresses(exclude_displayname=True)
final_ids = self.mail_recipients(is_inbound_mail_communcation = is_inbound_mail_communcation) + \
self.mail_bcc(is_inbound_mail_communcation = is_inbound_mail_communcation) + \
self.mail_cc(is_inbound_mail_communcation = is_inbound_mail_communcation, include_sender=include_sender)
return set(all_ids) - set(final_ids)

final_ids = (
self.mail_recipients(is_inbound_mail_communcation=is_inbound_mail_communcation)
+ self.mail_bcc(is_inbound_mail_communcation=is_inbound_mail_communcation)
+ self.mail_cc(is_inbound_mail_communcation=is_inbound_mail_communcation, include_sender=include_sender)
)

return list(set(all_ids) - set(final_ids))

def get_assignees(self):
"""Get owners of the reference document.


+ 4
- 6
frappe/email/doctype/email_account/email_account.py Näytä tiedosto

@@ -1,5 +1,6 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
# License: MIT. See LICENSE

import email.utils
import functools
import imaplib
@@ -7,6 +8,7 @@ import socket
import time
from datetime import datetime, timedelta
from poplib import error_proto
from typing import List

import frappe
from frappe import _, are_emails_muted, safe_encode
@@ -82,9 +84,6 @@ class EmailAccount(Document):
if frappe.local.flags.in_patch or frappe.local.flags.in_test:
return

#if self.enable_incoming and not self.append_to:
# frappe.throw(_("Append To is mandatory for incoming mails"))

if (not self.awaiting_password and not frappe.local.flags.in_install
and not frappe.local.flags.in_patch):
if self.password or self.smtp_server in ('127.0.0.1', 'localhost'):
@@ -458,7 +457,7 @@ class EmailAccount(Document):
if exceptions:
raise Exception(frappe.as_json(exceptions))

def get_inbound_mails(self, test_mails=None):
def get_inbound_mails(self, test_mails=None) -> List[InboundMail]:
"""retrive and return inbound mails.

"""
@@ -625,7 +624,6 @@ class EmailAccount(Document):
if frappe.db.exists("Email Account", {"enable_automatic_linking": 1, "name": ('!=', self.name)}):
frappe.throw(_("Automatic Linking can be activated only for one Email Account."))


def append_email_to_sent_folder(self, message):
email_server = None
try:


+ 19
- 12
frappe/email/doctype/email_queue/email_queue.py Näytä tiedosto

@@ -20,6 +20,7 @@ from frappe.email.queue import get_unsubcribed_url, get_unsubscribe_message
from frappe.email.email_body import add_attachment, get_formatted_html, get_email
from frappe.utils import cint, split_emails, add_days, nowdate, cstr, get_hook_method
from frappe.email.doctype.email_account.email_account import EmailAccount
from frappe.query_builder.utils import DocType


MAX_RETRY_COUNT = 3
@@ -477,18 +478,24 @@ class QueueBuilder:

all_ids = list(set(self.recipients + self.cc))

EmailUnsubscribe = frappe.qb.DocType("Email Unsubscribe")

unsubscribed = (frappe.qb.from_(EmailUnsubscribe)
.select(EmailUnsubscribe.email)
.where(EmailUnsubscribe.email.isin(all_ids) &
(
(
(EmailUnsubscribe.reference_doctype == self.reference_doctype) & (EmailUnsubscribe.reference_name == self.reference_name)
) | EmailUnsubscribe.global_unsubscribe == 1
)
).distinct()
).run(pluck=True)
EmailUnsubscribe = DocType("Email Unsubscribe")

unsubscribed = (
frappe.qb.from_(EmailUnsubscribe).select(
EmailUnsubscribe.email
).where(
EmailUnsubscribe.email.isin(all_ids)
& (
(
(EmailUnsubscribe.reference_doctype == self.reference_doctype)
& (EmailUnsubscribe.reference_name == self.reference_name)
) | (
EmailUnsubscribe.global_unsubscribe == 1
)
)
).distinct()
).run(pluck=True)

self._unsubscribed_user_emails = unsubscribed or []
return self._unsubscribed_user_emails



+ 2
- 1
frappe/website/utils.py Näytä tiedosto

@@ -5,6 +5,7 @@ import mimetypes
import os
import re
from functools import wraps
from typing import Dict, Optional

import yaml
from six import iteritems
@@ -453,7 +454,7 @@ def cache_html(func):

return cache_html_decorator

def build_response(path, data, http_status_code, headers=None):
def build_response(path, data, http_status_code, headers: Optional[Dict] = None):
# build response
response = Response()
response.data = set_content_type(response, data, path)


Ladataan…
Peruuta
Tallenna