11"""Definition of Data classes."""
2- from typing import List , NamedTuple
2+ import logging
3+ from typing import List , NamedTuple , Optional , Type , Set
34
45import email
56from pydantic import BaseModel , Extra
67
8+ logger = logging .getLogger (__name__ )
9+
710
811class DataPart (NamedTuple ):
912 """Simplest data unit to be parsed."""
@@ -23,16 +26,26 @@ def add_data_part(self, data_type: str, data_content: bytes):
2326 self .data_parts .append (DataPart (data_type , data_content ))
2427
2528 @classmethod
26- def init (cls , data_type : str , data_content : bytes ):
29+ def init_from_raw (
30+ cls : Type ["NotificationData" ], data_type : str , data_content : bytes
31+ ) -> Optional ["NotificationData" ]:
2732 """Initialize the data_parts with only one DataPart object."""
28- return cls (data_parts = [DataPart (data_type , data_content )])
33+ try :
34+ return cls (data_parts = [DataPart (data_type , data_content )])
35+ except Exception : # pylint: disable=broad-except
36+ logger .exception ("Error found initializing data raw: %s, %s" , data_type , data_content )
37+ return None
2938
3039 @classmethod
31- def init_from_email_bytes (cls , raw_email_bytes : bytes ):
40+ def init_from_email_bytes (cls : Type [ "NotificationData" ] , raw_email_bytes : bytes ) -> Optional [ "NotificationData" ] :
3241 """Initialize the data_parts from an email defined as raw bytes.."""
33- raw_email_string = raw_email_bytes .decode ("utf-8" )
34- email_message = email .message_from_string (raw_email_string )
35- return cls .init_from_emailmessage (email_message )
42+ try :
43+ raw_email_string = raw_email_bytes .decode ("utf-8" )
44+ email_message = email .message_from_string (raw_email_string )
45+ return cls .init_from_emailmessage (email_message )
46+ except Exception : # pylint: disable=broad-except
47+ logger .exception ("Error found initializing data from email raw bytes: %s" , raw_email_bytes )
48+ return None
3649
3750 @classmethod
3851 def walk_email (cls , email_message , data_parts ):
@@ -53,13 +66,17 @@ def walk_email(cls, email_message, data_parts):
5366 data_parts .add (DataPart (part .get_content_type (), part .get_payload (decode = True )))
5467
5568 @classmethod
56- def init_from_emailmessage (cls , email_message ):
69+ def init_from_emailmessage (cls : Type [ "NotificationData" ] , email_message ) -> Optional [ "NotificationData" ] :
5770 """Initialize the data_parts from an email.message.Email object."""
58- data_parts = set ()
59- cls .walk_email (email_message , data_parts )
71+ try :
72+ data_parts : Set [DataPart ] = set ()
73+ cls .walk_email (email_message , data_parts )
6074
61- # Adding extra headers that are interesting to be parsed
62- data_parts .add (DataPart ("email-header-subject" , email_message ["Subject" ].encode ()))
63- # TODO: Date could be used to extend the "Stamp" time of a notification when not available, but we need a parser
64- data_parts .add (DataPart ("email-header-date" , email_message ["Date" ].encode ()))
65- return cls (data_parts = list (data_parts ))
75+ # Adding extra headers that are interesting to be parsed
76+ data_parts .add (DataPart ("email-header-subject" , email_message ["Subject" ].encode ()))
77+ # TODO: Date could be used to extend the "Stamp" time of a notification when not available, but we need a parser
78+ data_parts .add (DataPart ("email-header-date" , email_message ["Date" ].encode ()))
79+ return cls (data_parts = list (data_parts ))
80+ except Exception : # pylint: disable=broad-except
81+ logger .exception ("Error found initializing data from email message: %s" , email_message )
82+ return None
0 commit comments