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
31 changes: 17 additions & 14 deletions simplegmail/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

class Attachment(object):
"""
The Attachment class for attachments to emails in your Gmail mailbox. This
The Attachment class for attachments to emails in your Gmail mailbox. This
class should not be manually instantiated.

Args:
Expand All @@ -22,6 +22,7 @@ class should not be manually instantiated.
filename: The filename associated with the attachment.
filetype: The mime type of the file.
data: The raw data of the file. Default None.
headers: A dict of header name/value pairs of the attachment. Default {}.

Attributes:
_service (googleapiclient.discovery.Resource): The Gmail service object.
Expand All @@ -31,9 +32,10 @@ class should not be manually instantiated.
filename (str): The filename associated with the attachment.
filetype (str): The mime type of the file.
data (bytes): The raw data of the file.
headers (dict): A dict of header name/value pairs of the attachment.

"""

def __init__(
self,
service: 'googleapiclient.discovery.Resource',
Expand All @@ -42,7 +44,8 @@ def __init__(
att_id: str,
filename: str,
filetype: str,
data: Optional[bytes] = None
data: Optional[bytes] = None,
headers: Optional[dict] = {}
) -> None:
self._service = service
self.user_id = user_id
Expand All @@ -51,17 +54,18 @@ def __init__(
self.filename = filename
self.filetype = filetype
self.data = data
self.headers = headers

def download(self) -> None:
"""
Downloads the data for an attachment if it does not exist.

Raises:
googleapiclient.errors.HttpError: There was an error executing the
googleapiclient.errors.HttpError: There was an error executing the
HTTP request.

"""

if self.data is not None:
return

Expand All @@ -79,18 +83,18 @@ def save(
) -> None:
"""
Saves the attachment. Downloads file data if not downloaded.

Args:
filepath: where to save the attachment. Default None, which uses
filepath: where to save the attachment. Default None, which uses
the filename stored.
overwrite: whether to overwrite existing files. Default False.

Raises:
FileExistsError: if the call would overwrite an existing file and
FileExistsError: if the call would overwrite an existing file and
overwrite is not set to True.

"""

if filepath is None:
filepath = self.filename

Expand All @@ -105,4 +109,3 @@ def save(

with open(filepath, 'wb') as f:
f.write(self.data)

18 changes: 16 additions & 2 deletions simplegmail/gmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ def _build_message_from_ref(
elif part['part_type'] == 'attachment':
attm = Attachment(self.service, user_id, msg_id,
part['attachment_id'], part['filename'],
part['filetype'], part['data'])
part['filetype'], part['data'], part['headers'])
attms.append(attm)

return Message(self.service, self.creds, user_id, msg_id,
Expand Down Expand Up @@ -782,12 +782,26 @@ def _evaluate_message_payload(
if not filename:
filename = 'unknown'

headers = {}
for hdr in payload['headers']:
name = hdr['name']
value = hdr['value']
if name in headers:
# Allow for duplicate header names, per page 20 of RFC 5322:
# https://www.rfc-editor.org/rfc/rfc5322#section-3.6
if not isinstance(headers[name], list):
headers[name] = [headers[name]]
headers[name].append(value)
continue
headers[name] = value

obj = {
'part_type': 'attachment',
'filetype': payload['mimeType'],
'filename': filename,
'attachment_id': att_id,
'data': None
'data': None,
'headers': headers
}

if attachments == 'reference':
Expand Down