diff --git a/README.rst b/README.rst index 1282550..fe2c149 100644 --- a/README.rst +++ b/README.rst @@ -368,7 +368,9 @@ Big thanks to people who helped develop this library: `edkedk99 `_, `UlisseMini `_, `Nicarex `_, -`RanjithNair1980 `_ +`RanjithNair1980 `_, +`NickC-NZ `_, +`mweinelt `_ Donate ------ diff --git a/docs/release_notes.rst b/docs/release_notes.rst index 308030b..ce3caea 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -1,3 +1,8 @@ +0.50.0 +====== +* Fix MailboxLoginError was never raise +* ParamConverter.convert now order search keys by alphabet - guarantees a repeatable result for query builder + 0.49.1 ====== * Fix support for python 3.5 diff --git a/imap_tools/__init__.py b/imap_tools/__init__.py index 9cae9ec..e60eef5 100644 --- a/imap_tools/__init__.py +++ b/imap_tools/__init__.py @@ -10,4 +10,4 @@ from .utils import EmailAddress from .errors import * -__version__ = '0.49.1' +__version__ = '0.50.0' diff --git a/imap_tools/mailbox.py b/imap_tools/mailbox.py index 1c783c9..b789aae 100644 --- a/imap_tools/mailbox.py +++ b/imap_tools/mailbox.py @@ -43,8 +43,9 @@ def _get_mailbox_client(self) -> imaplib.IMAP4: raise NotImplementedError def login(self, username: str, password: str, initial_folder: Optional[str] = 'INBOX') -> 'BaseMailBox': - login_result = self.box.login(username, password) + login_result = self.box._simple_command('LOGIN', username, self.box._quote(password)) # noqa check_command_status(login_result, MailboxLoginError) + self.box.state = 'AUTH' # logic from self.box.login self.folder = self.folder_manager_class(self) if initial_folder is not None: self.folder.set(initial_folder) diff --git a/imap_tools/query.py b/imap_tools/query.py index bb13fdf..1ab70eb 100644 --- a/imap_tools/query.py +++ b/imap_tools/query.py @@ -2,7 +2,7 @@ import datetime import itertools import functools -from collections import OrderedDict, UserString +from collections import UserString from typing import Iterable, Optional, Dict, Any, List, Union from .consts import SHORT_MONTH_NAMES @@ -86,7 +86,7 @@ def __init__( for val in converted_strings: if not any(isinstance(val, t) for t in (str, UserString)): raise TypeError('Unexpected type "{}" for converted part, str like obj expected'.format(type(val))) - unconverted_dict = OrderedDict({k: v for k, v in locals().items() if k in SEARCH_KEYS and v is not None}) + unconverted_dict = {k: v for k, v in locals().items() if k in SEARCH_KEYS and v is not None} self.converted_params = ParamConverter(unconverted_dict).convert() if not any((self.converted_strings, self.converted_params)): raise ValueError('{} expects params'.format(self.__class__.__name__)) @@ -154,7 +154,7 @@ def convert(self) -> List[str]: :return: params in IMAP format """ converted = [] - for key, raw_val in self.params.items(): + for key, raw_val in sorted(self.params.items(), key=lambda x: x[0]): for val in self._gen_values(key, raw_val): convert_func = getattr(self, 'convert_{}'.format(key), None) if not convert_func: diff --git a/tests/messages/plain_emails/raw_email_multiple_from.eml b/tests/messages/plain_emails/raw_email_multiple_from.eml deleted file mode 100644 index 6a9fbad..0000000 --- a/tests/messages/plain_emails/raw_email_multiple_from.eml +++ /dev/null @@ -1,30 +0,0 @@ -Delivered-To: tim@powerupdev.com -Return-Path: -To: tim@powerupdev.com concierge@powerupdev.com -From: tim@powerupdev.com concierge@powerupdev.com -Subject: /home/svn/public/minebox revision 214 -Reply-to: tim@powerupdev.com concierge@powerupdev.com -Message-Id: <20071022234523.5BD8E86D2@mangaverde.net> -Date: Mon, 22 Oct 2007 23:45:23 +0000 (UTC) - -

recordkick 2007-10-22 23:45:23 +0000 (Mon, 22 Oct 2007)

test -subversion
-


Modified:
-trunk/README
-===================================================================
---- trunk/README\t2007-10-22
-23:41:34 UTC (rev 213)
-+++ trunk/README\t2007-10-22 23:45:23 UTC (rev 214)
-@@ -1,5 +1,5 @@
- == Welcome
-to Rails
--Test
-+Tedst
- Rails is a web-application and persistence framework that includes everything
- needed
-to create database-backed web-applications according to the
- Model-View-Control pattern of separation. This pattern
-splits the view (also
-
-
-
diff --git a/tests/messages_data/plain_emails/raw_email_multiple_from.py b/tests/messages_data/plain_emails/raw_email_multiple_from.py deleted file mode 100644 index d72e04c..0000000 --- a/tests/messages_data/plain_emails/raw_email_multiple_from.py +++ /dev/null @@ -1,22 +0,0 @@ -import datetime -from imap_tools import EmailAddress - -DATA = dict( - subject='/home/svn/public/minebox revision 214', - from_='tim@powerupdev.comconcierge', - to=('tim@powerupdev.comconcierge', '@powerupdev.com'), - cc=(), - bcc=(), - reply_to=('tim@powerupdev.comconcierge', '@powerupdev.com'), - date=datetime.datetime(2007, 10, 22, 23, 45, 23, tzinfo=datetime.timezone.utc), - date_str='Mon, 22 Oct 2007 23:45:23 +0000 (UTC)', - text='

recordkick 2007-10-22 23:45:23 +0000 (Mon, 22 Oct 2007)

test\r\nsubversion
\r\n


Modified:\r\ntrunk/README\r\n===================================================================\r\n--- trunk/README\\t2007-10-22\r\n23:41:34 UTC (rev 213)\r\n+++ trunk/README\\t2007-10-22 23:45:23 UTC (rev 214)\r\n@@ -1,5 +1,5 @@\r\n == Welcome\r\nto Rails\r\n-Test\r\n+Tedst\r\n Rails is a web-application and persistence framework that includes everything\r\n needed\r\nto create database-backed web-applications according to the\r\n Model-View-Control pattern of separation. This pattern\r\nsplits the view (also\r\n\r\n\r\n
\r\n', - html='', - headers={'delivered-to': ('tim@powerupdev.com',), 'return-path': ('',), 'to': ('tim@powerupdev.com concierge@powerupdev.com',), 'from': ('tim@powerupdev.com concierge@powerupdev.com',), 'subject': ('/home/svn/public/minebox revision 214',), 'reply-to': ('tim@powerupdev.com concierge@powerupdev.com',), 'message-id': ('<20071022234523.5BD8E86D2@mangaverde.net>',), 'date': ('Mon, 22 Oct 2007 23:45:23 +0000 (UTC)',)}, - attachments=[], - from_values=EmailAddress('', 'tim@powerupdev.comconcierge', 'tim@powerupdev.comconcierge'), - to_values=(EmailAddress('', 'tim@powerupdev.comconcierge', 'tim@powerupdev.comconcierge'), EmailAddress('', '@powerupdev.com', '@powerupdev.com')), - cc_values=(), - bcc_values=(), - reply_to_values=(EmailAddress('', 'tim@powerupdev.comconcierge', 'tim@powerupdev.comconcierge'), EmailAddress('', '@powerupdev.com', '@powerupdev.com')), -) \ No newline at end of file diff --git a/tests/test_query.py b/tests/test_query.py index 4639902..a716e32 100644 --- a/tests/test_query.py +++ b/tests/test_query.py @@ -93,7 +93,7 @@ def test_logic_operators(self): '(OR OR OR ON 1-Oct-2019 ON 10-Oct-2019 ON 15-Oct-2019 ON 20-Oct-2019)') self.assertEqual( A(OR(from_='from@ya.ru', text='"the text"'), NOT(OR(A(answered=False), A(new=True))), to='to@ya.ru'), - '((OR TEXT "\\"the text\\"" FROM "from@ya.ru") NOT ((OR (UNANSWERED) (NEW))) TO "to@ya.ru")') + '((OR FROM "from@ya.ru" TEXT "\\"the text\\"") NOT ((OR (UNANSWERED) (NEW))) TO "to@ya.ru")') def test_header(self): header = H('key1', 'val1')