From b53a1e683766423f22474f970f7b2e512d6146f6 Mon Sep 17 00:00:00 2001 From: zevav Date: Wed, 25 Jul 2018 08:22:04 -0400 Subject: [PATCH 1/5] Added missing documentation for all supported query keyword arguments. Fixes #124. --- README.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 2d4c5ca..1a8cf0e 100644 --- a/README.rst +++ b/README.rst @@ -45,6 +45,12 @@ Usage # Unread messages unread_messages = imbox.messages(unread=True) + # Flagged messages + unread_messages = imbox.messages(flagged=True) + + # Un-flagged messages + unread_messages = imbox.messages(unflagged=True) + # Messages sent FROM messages_from = imbox.messages(sent_from='martin@amon.cx') @@ -60,11 +66,12 @@ Usage # Messages received on a specific date messages_from = imbox.messages(date__on=datetime.date(2013, 7, 30)) + # Messages whose subjects contain a string + messages_from = imbox.messages(subject='Christmas') + # Messages from a specific folder messages_folder = imbox.messages(folder='Social') - - for uid, message in all_messages: # Every message is an object with the following keys From b4cb03e14525842ba1a5d69abaf8cc9e848d44f0 Mon Sep 17 00:00:00 2001 From: zevav Date: Wed, 25 Jul 2018 08:24:05 -0400 Subject: [PATCH 2/5] added Pycharm directory to .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 6f171cb..de2db09 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ nosetests.xml example.* example.py + +# PyCharm +.idea/ From 71942a69e8638004c99d41772176c6257ccd397b Mon Sep 17 00:00:00 2001 From: zevav Date: Wed, 25 Jul 2018 08:27:40 -0400 Subject: [PATCH 3/5] fixed var names in documentation of query keywords --- README.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index 1a8cf0e..42b9e47 100644 --- a/README.rst +++ b/README.rst @@ -46,31 +46,31 @@ Usage unread_messages = imbox.messages(unread=True) # Flagged messages - unread_messages = imbox.messages(flagged=True) + flagged_messages = imbox.messages(flagged=True) # Un-flagged messages - unread_messages = imbox.messages(unflagged=True) + unflagged_messages = imbox.messages(unflagged=True) # Messages sent FROM - messages_from = imbox.messages(sent_from='martin@amon.cx') + messages_from_martin = imbox.messages(sent_from='martin@amon.cx') # Messages sent TO - messages_from = imbox.messages(sent_to='martin@amon.cx') + messages_to_martin = imbox.messages(sent_to='martin@amon.cx') # Messages received before specific date - messages_from = imbox.messages(date__lt=datetime.date(2013, 7, 31)) + messages_received_before_20130731 = imbox.messages(date__lt=datetime.date(2013, 7, 31)) # Messages received after specific date - messages_from = imbox.messages(date__gt=datetime.date(2013, 7, 30)) + messages_received_after_20130730 = imbox.messages(date__gt=datetime.date(2013, 7, 30)) # Messages received on a specific date - messages_from = imbox.messages(date__on=datetime.date(2013, 7, 30)) + messages_received_20130730 = imbox.messages(date__on=datetime.date(2013, 7, 30)) # Messages whose subjects contain a string - messages_from = imbox.messages(subject='Christmas') + messages_subject_christmas = imbox.messages(subject='Christmas') # Messages from a specific folder - messages_folder = imbox.messages(folder='Social') + messages_in_folder_social = imbox.messages(folder='Social') for uid, message in all_messages: # Every message is an object with the following keys From 6d527a2f1d26ee00b9ccf2320e11e45f6ce141cb Mon Sep 17 00:00:00 2001 From: zevav Date: Thu, 26 Jul 2018 15:24:20 -0400 Subject: [PATCH 4/5] added type hint stubs for all modules --- imbox/__init__.pyi | 58 ++++++++++++++++++++++++++++++++++++++++++++++ imbox/imap.pyi | 13 +++++++++++ imbox/parser.pyi | 0 imbox/query.pyi | 0 imbox/utils.pyi | 0 5 files changed, 71 insertions(+) create mode 100644 imbox/__init__.pyi create mode 100644 imbox/imap.pyi create mode 100644 imbox/parser.pyi create mode 100644 imbox/query.pyi create mode 100644 imbox/utils.pyi diff --git a/imbox/__init__.pyi b/imbox/__init__.pyi new file mode 100644 index 0000000..1979263 --- /dev/null +++ b/imbox/__init__.pyi @@ -0,0 +1,58 @@ +import datetime +from email._policybase import Policy +from imaplib import IMAP4, IMAP4_SSL +from inspect import Traceback +from ssl import SSLContext +from typing import Optional, Union, List, Tuple, Generator + +from imbox.parser import Struct + + +class Imbox: + + def __init__(self, hostname: str, username: Optional[str], password: Optional[str], ssl: bool, + port: Optional[int], ssl_context: Optional[SSLContext], policy: Optional[Policy], starttls: bool): ... + + def __enter__(self) -> 'Imbox': ... + + def __exit__(self, type: Exception, value: str, traceback: Traceback) -> None: ... + + def logout(self) -> None: ... + + def mark_seen(self, uid: bytes) -> None: ... + + def mark_flag(self, uid: bytes) -> None: ... + + def delete(self, uid: bytes) -> None: ... + + def copy(self, uid: bytes, destination_folder: Union[bytes, str]) -> Tuple[str, Union[list, List[None, bytes]]]: ... + + def move(self, uid: bytes, destination_folder: Union[bytes, str]) -> None: ... + + def messages(self, **kwargs: Union[bool, str, datetime.date]) -> 'Messages': ... + + def folders(self) -> Tuple[str, List[bytes]]: ... + + +class Messages: + + def __init__(self, + connection: Union[IMAP4, IMAP4_SSL], + parser_policy: Policy, + **kwargs: Union[bool, str, datetime.date]) -> None: ... + + def _fetch_email(self, uid: bytes) -> 'Struct': ... + + def _query_uids(self, **kwargs: Union[bool, str, datetime.date]) -> List[bytes]: ... + + def _fetch_email_list(self) -> Generator[Tuple[bytes, 'Struct']]: ... + + def __repr__(self) -> str: ... + + def __iter__(self) -> Generator[Tuple[bytes, 'Struct']]: ... + + def __next__(self) -> 'Messages': ... + + def __len__(self) -> int: ... + + def __getitem__(self, index) -> Union['Struct', List['Struct']]: ... diff --git a/imbox/imap.pyi b/imbox/imap.pyi new file mode 100644 index 0000000..16797a0 --- /dev/null +++ b/imbox/imap.pyi @@ -0,0 +1,13 @@ +from imaplib import IMAP4, IMAP4_SSL +from ssl import SSLContext +from typing import Optional, Union, Tuple, List + + +class ImapTransport: + + def __init__(self, hostname: str, port: Optional[int], ssl: bool, + ssl_context: Optional[SSLContext], starttls: bool) -> None: ... + + def list_folders(self) -> Tuple[str, List[bytes]]: ... + + def connect(self, username: str, password: str) -> Union[IMAP4, IMAP4_SSL]: ... diff --git a/imbox/parser.pyi b/imbox/parser.pyi new file mode 100644 index 0000000..e69de29 diff --git a/imbox/query.pyi b/imbox/query.pyi new file mode 100644 index 0000000..e69de29 diff --git a/imbox/utils.pyi b/imbox/utils.pyi new file mode 100644 index 0000000..e69de29 From dfca46886fdcaacb05834d59368d10fd076eb046 Mon Sep 17 00:00:00 2001 From: zevav Date: Thu, 26 Jul 2018 15:30:02 -0400 Subject: [PATCH 5/5] filled in stub files --- imbox/{__init__.pyi => imbox.pyi} | 31 ++----------------------------- imbox/messages.pyi | 28 ++++++++++++++++++++++++++++ imbox/parser.pyi | 30 ++++++++++++++++++++++++++++++ imbox/query.pyi | 7 +++++++ imbox/utils.pyi | 6 ++++++ 5 files changed, 73 insertions(+), 29 deletions(-) rename imbox/{__init__.pyi => imbox.pyi} (52%) create mode 100644 imbox/messages.pyi diff --git a/imbox/__init__.pyi b/imbox/imbox.pyi similarity index 52% rename from imbox/__init__.pyi rename to imbox/imbox.pyi index 1979263..ffa5bef 100644 --- a/imbox/__init__.pyi +++ b/imbox/imbox.pyi @@ -1,11 +1,8 @@ import datetime from email._policybase import Policy -from imaplib import IMAP4, IMAP4_SSL from inspect import Traceback from ssl import SSLContext -from typing import Optional, Union, List, Tuple, Generator - -from imbox.parser import Struct +from typing import Optional, Union, Tuple, List class Imbox: @@ -31,28 +28,4 @@ class Imbox: def messages(self, **kwargs: Union[bool, str, datetime.date]) -> 'Messages': ... - def folders(self) -> Tuple[str, List[bytes]]: ... - - -class Messages: - - def __init__(self, - connection: Union[IMAP4, IMAP4_SSL], - parser_policy: Policy, - **kwargs: Union[bool, str, datetime.date]) -> None: ... - - def _fetch_email(self, uid: bytes) -> 'Struct': ... - - def _query_uids(self, **kwargs: Union[bool, str, datetime.date]) -> List[bytes]: ... - - def _fetch_email_list(self) -> Generator[Tuple[bytes, 'Struct']]: ... - - def __repr__(self) -> str: ... - - def __iter__(self) -> Generator[Tuple[bytes, 'Struct']]: ... - - def __next__(self) -> 'Messages': ... - - def __len__(self) -> int: ... - - def __getitem__(self, index) -> Union['Struct', List['Struct']]: ... + def folders(self) -> Tuple[str, List[bytes]]: ... \ No newline at end of file diff --git a/imbox/messages.pyi b/imbox/messages.pyi new file mode 100644 index 0000000..9c2fa32 --- /dev/null +++ b/imbox/messages.pyi @@ -0,0 +1,28 @@ +import datetime +from email._policybase import Policy +from imaplib import IMAP4, IMAP4_SSL +from typing import Union, List, Generator, Tuple + + +class Messages: + + def __init__(self, + connection: Union[IMAP4, IMAP4_SSL], + parser_policy: Policy, + **kwargs: Union[bool, str, datetime.date]) -> None: ... + + def _fetch_email(self, uid: bytes) -> 'Struct': ... + + def _query_uids(self, **kwargs: Union[bool, str, datetime.date]) -> List[bytes]: ... + + def _fetch_email_list(self) -> Generator[Tuple[bytes, 'Struct']]: ... + + def __repr__(self) -> str: ... + + def __iter__(self) -> Generator[Tuple[bytes, 'Struct']]: ... + + def __next__(self) -> 'Messages': ... + + def __len__(self) -> int: ... + + def __getitem__(self, index) -> Union['Struct', List['Struct']]: ... \ No newline at end of file diff --git a/imbox/parser.pyi b/imbox/parser.pyi index e69de29..bebbb21 100644 --- a/imbox/parser.pyi +++ b/imbox/parser.pyi @@ -0,0 +1,30 @@ +import datetime +from email._policybase import Policy +from email.message import Message +from imaplib import IMAP4_SSL +import io +from typing import Union, Dict, List, KeysView, Tuple, Optional + + +class Struct: + def __init__(self, **entries: Union[ + str, datetime.datetime, Dict[str, str], list, List[Dict[str, str]] + ]) -> None: ... + + def keys(self) -> KeysView: ... + + def __repr__(self) -> str: ... + +def decode_mail_header(value: str, default_charset: str) -> str: ... + +def get_mail_addresses(message: Message, header_name: str) -> List[Dict[str, str]]: ... + +def decode_param(param: str) -> Tuple[str, str]: ... + +def parse_attachment(message_part: Message) -> Optional[Dict[str, Union[int, str, io.BytesIO]]]: ... + +def decode_content(message: Message) -> str: ... + +def fetch_email_by_uid(uid: bytes, connection: IMAP4_SSL, parser_policy: Optional[Policy]) -> Struct: ... + +def parse_email(raw_email: bytes, policy: Optional[Policy]) -> Struct: ... diff --git a/imbox/query.pyi b/imbox/query.pyi index e69de29..91734b9 100644 --- a/imbox/query.pyi +++ b/imbox/query.pyi @@ -0,0 +1,7 @@ +import datetime +from typing import Union + + +def format_date(date: Union[str, datetime.date]) -> str: ... + +def build_search_query(**kwargs: Union[bool, str, datetime.date]) -> str: ... diff --git a/imbox/utils.pyi b/imbox/utils.pyi index e69de29..0f1f136 100644 --- a/imbox/utils.pyi +++ b/imbox/utils.pyi @@ -0,0 +1,6 @@ +from typing import Optional, Union + + +def str_encode(value: Union[str, bytes], encoding: Optional[str], errors: str) -> str: ... + +def str_decode(value: Union[str, bytes], encoding: Optional[str], errors: str) -> Union[str, bytes]: ...