RIFF¤ WEBPVP8 ˜ ðÑ *ôô>‘HŸK¥¤"§£±¨àð �PNG ��� IHDR���0���0����`n���� cHRM��z&��������������u0���`��:���p��Q<���bKGD�������������tIME� 6���� AIDATX��]pU����{��{�G�n$$@ -�-jВAک��P��1O���j��:cU|hg�}�C�ʋU�:�A A�����|$$$������}�^}8i *�د�?w�9gݵ��:{��F"��&��4� �@��@q_����Ow��9<<|�ԩ�;w���"�#GV�^}Ճ7�|s˖-{��|��G�-[��R�Q�aőTR)� �2!�e�63��X�U������{��Z�m۶�^}�5����}����v�R��J�J,�$� B�$Ф")�i��D�9+䜆B.�qf�үÇoذaժU�i>��so����a^���۷����3�<�ꫯnݺ��"���\���gn0�h��B�i� hR��,W*�e�65��LS�ر�0ēO>���755���ι@O?��ҥK������:::����1��X�9S�%�'�I���$��Sg�ڥ3'zF/� ��Z�8ES6WZ#�.�\��P�R�2����-[�,_�|�`�j�Xl6M���b�Z�* �jҟ0��҉B""� y22r�ܹ�CG�;���{7nn��ma���������2S���� <��x�⡡�|p.Pw��x��y�C�=��O� ��CB}�ӵ����?�wq`8�e����{+Չɱ�\{&�LL������vww��]��?q��Y�������P(���vuu9���S?w���ݻ�v<���mш ��D�DR&�j�X�����y�>���dyg�7��b��s�p��E���BDR� t����������=w�\�[;:[&._�Dlڸv�]��u�驚�/Y�a�����d�%��*)1� �V\G���[F]����X���i����J:z�N�9�?xϭ+X�V|���U�n� �g���hҜ�b�aҢ^��j�f�ZV�K��w.�ؾp�}{� �/e��{O�o�����R�8���i� !jB`�3n;Mw.=7�S�'��F�yW��x�}LXNfz�����b�p�b�bq~�����s�4�H�2��q^�r��n���\aFf4�����n�c��Q�n�X�,����ӑҤd5DDDd9'd��,�l��.���)?��������#}C�k����ܖq����m�a��y��8D���,K)�I�$I�8NE�aH)�|�VCDƘ��DF0D@M�"3�+�����Kcú��+n}��-�k:W�K������3ƄRʌ��m۞��q�9WJ���d�0�,�8��ٶ�⦈B�h���䩡�eDCj&$ �1�Y��\�>{~`�M����ͷt�#?VZ'@D²l"�,+�ɤc0�r��R*��X��n�_kMD�1"""ι�:%X��� $�b:i�b4�X<�/"r�����[Vo��T��0V�i���sΓ$IG���4M�c�R�eq��QS�+5{�{�,��a"��D�2�CҐ(I`CS�s�ʥ�R&�p�����۴(�N���e�sq�Ғ|%�����k�=�0S3@�`�i9�K��Պ�0T�Y��ؼD*��DE��2�gO�bŷrY����z�T��R�҉҆SX�Tϑ����/�Zi�eL��X��jdx䏿�eَ���7��П"?�����0y����<��R�N8�\X9ӥx ��^�L�l�ކ��u����/���Q�B�^p�f��\3��]�INƑ�L�"--�r�!8?���Rp~����v��|�M��$����_M�����GgF�/U�^�^p�Dk�ٲ�vM� ����L$�eGʓ01*���Two��f��#���ޱ��7��!5rdy"D��V���\ט��[y�f���@���Um����2w\�fg_z�y���v|`$_ow402�|���c��Zt��J��Yw���b8+L����R�t߉O�xS���'�L��`/lY�� ���Z;f�nX���f��$�<���Ϩ�J��z"�y��%�qzz��(B��Y�@D�)�uS���<�\.[�����*T(�8v�̗����rrr2I�� N5w����^k=�}�:�S�yӌ��ً+�����NY碧f����0)��h. �R����4�Ա�>�X,:����c�0�0�Rn6���mii�MW*�j��i�I�0�,ˊ���È�8���j�$I�hkk�`||�B!b��l6�8Ncc��U��<���1f�&"FQdYV�B�b���j3�>�!��j>���g���g��RD����8���r�08�u�7��]3������~�,b�P���%tEXtdate:create�2025-02-07T10:02:54+00:00� t����%tEXtdate:modify�2025-02-07T10:02:54+00:00�P�6���(tEXtdate:timestamp�2025-02-07T10:02:54+00:00�E������IEND�B`�
| Server IP : 128.227.220.250 / Your IP : 216.73.216.35 Web Server : Apache/2.4.64 (Unix) OpenSSL/1.0.2k-fips PHP/7.4.33 System : Linux dumont.ece.ufl.edu 3.10.0-1160.95.1.el7.x86_64 #1 SMP Mon Jul 24 13:59:37 UTC 2023 x86_64 User : daemon ( 2) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/lib64/python3.6/email/ |
Upload File : |
import binascii
import email.charset
import email.message
import email.errors
from email import quoprimime
class ContentManager:
def __init__(self):
self.get_handlers = {}
self.set_handlers = {}
def add_get_handler(self, key, handler):
self.get_handlers[key] = handler
def get_content(self, msg, *args, **kw):
content_type = msg.get_content_type()
if content_type in self.get_handlers:
return self.get_handlers[content_type](msg, *args, **kw)
maintype = msg.get_content_maintype()
if maintype in self.get_handlers:
return self.get_handlers[maintype](msg, *args, **kw)
if '' in self.get_handlers:
return self.get_handlers[''](msg, *args, **kw)
raise KeyError(content_type)
def add_set_handler(self, typekey, handler):
self.set_handlers[typekey] = handler
def set_content(self, msg, obj, *args, **kw):
if msg.get_content_maintype() == 'multipart':
# XXX: is this error a good idea or not? We can remove it later,
# but we can't add it later, so do it for now.
raise TypeError("set_content not valid on multipart")
handler = self._find_set_handler(msg, obj)
msg.clear_content()
handler(msg, obj, *args, **kw)
def _find_set_handler(self, msg, obj):
full_path_for_error = None
for typ in type(obj).__mro__:
if typ in self.set_handlers:
return self.set_handlers[typ]
qname = typ.__qualname__
modname = getattr(typ, '__module__', '')
full_path = '.'.join((modname, qname)) if modname else qname
if full_path_for_error is None:
full_path_for_error = full_path
if full_path in self.set_handlers:
return self.set_handlers[full_path]
if qname in self.set_handlers:
return self.set_handlers[qname]
name = typ.__name__
if name in self.set_handlers:
return self.set_handlers[name]
if None in self.set_handlers:
return self.set_handlers[None]
raise KeyError(full_path_for_error)
raw_data_manager = ContentManager()
def get_text_content(msg, errors='replace'):
content = msg.get_payload(decode=True)
charset = msg.get_param('charset', 'ASCII')
return content.decode(charset, errors=errors)
raw_data_manager.add_get_handler('text', get_text_content)
def get_non_text_content(msg):
return msg.get_payload(decode=True)
for maintype in 'audio image video application'.split():
raw_data_manager.add_get_handler(maintype, get_non_text_content)
def get_message_content(msg):
return msg.get_payload(0)
for subtype in 'rfc822 external-body'.split():
raw_data_manager.add_get_handler('message/'+subtype, get_message_content)
def get_and_fixup_unknown_message_content(msg):
# If we don't understand a message subtype, we are supposed to treat it as
# if it were application/octet-stream, per
# tools.ietf.org/html/rfc2046#section-5.2.4. Feedparser doesn't do that,
# so do our best to fix things up. Note that it is *not* appropriate to
# model message/partial content as Message objects, so they are handled
# here as well. (How to reassemble them is out of scope for this comment :)
return bytes(msg.get_payload(0))
raw_data_manager.add_get_handler('message',
get_and_fixup_unknown_message_content)
def _prepare_set(msg, maintype, subtype, headers):
msg['Content-Type'] = '/'.join((maintype, subtype))
if headers:
if not hasattr(headers[0], 'name'):
mp = msg.policy
headers = [mp.header_factory(*mp.header_source_parse([header]))
for header in headers]
try:
for header in headers:
if header.defects:
raise header.defects[0]
msg[header.name] = header
except email.errors.HeaderDefect as exc:
raise ValueError("Invalid header: {}".format(
header.fold(policy=msg.policy))) from exc
def _finalize_set(msg, disposition, filename, cid, params):
if disposition is None and filename is not None:
disposition = 'attachment'
if disposition is not None:
msg['Content-Disposition'] = disposition
if filename is not None:
msg.set_param('filename',
filename,
header='Content-Disposition',
replace=True)
if cid is not None:
msg['Content-ID'] = cid
if params is not None:
for key, value in params.items():
msg.set_param(key, value)
# XXX: This is a cleaned-up version of base64mime.body_encode (including a bug
# fix in the calculation of unencoded_bytes_per_line). It would be nice to
# drop both this and quoprimime.body_encode in favor of enhanced binascii
# routines that accepted a max_line_length parameter.
def _encode_base64(data, max_line_length):
encoded_lines = []
unencoded_bytes_per_line = max_line_length // 4 * 3
for i in range(0, len(data), unencoded_bytes_per_line):
thisline = data[i:i+unencoded_bytes_per_line]
encoded_lines.append(binascii.b2a_base64(thisline).decode('ascii'))
return ''.join(encoded_lines)
def _encode_text(string, charset, cte, policy):
lines = string.encode(charset).splitlines()
linesep = policy.linesep.encode('ascii')
def embedded_body(lines): return linesep.join(lines) + linesep
def normal_body(lines): return b'\n'.join(lines) + b'\n'
if cte==None:
# Use heuristics to decide on the "best" encoding.
try:
return '7bit', normal_body(lines).decode('ascii')
except UnicodeDecodeError:
pass
if (policy.cte_type == '8bit' and
max(len(x) for x in lines) <= policy.max_line_length):
return '8bit', normal_body(lines).decode('ascii', 'surrogateescape')
sniff = embedded_body(lines[:10])
sniff_qp = quoprimime.body_encode(sniff.decode('latin-1'),
policy.max_line_length)
sniff_base64 = binascii.b2a_base64(sniff)
# This is a little unfair to qp; it includes lineseps, base64 doesn't.
if len(sniff_qp) > len(sniff_base64):
cte = 'base64'
else:
cte = 'quoted-printable'
if len(lines) <= 10:
return cte, sniff_qp
if cte == '7bit':
data = normal_body(lines).decode('ascii')
elif cte == '8bit':
data = normal_body(lines).decode('ascii', 'surrogateescape')
elif cte == 'quoted-printable':
data = quoprimime.body_encode(normal_body(lines).decode('latin-1'),
policy.max_line_length)
elif cte == 'base64':
data = _encode_base64(embedded_body(lines), policy.max_line_length)
else:
raise ValueError("Unknown content transfer encoding {}".format(cte))
return cte, data
def set_text_content(msg, string, subtype="plain", charset='utf-8', cte=None,
disposition=None, filename=None, cid=None,
params=None, headers=None):
_prepare_set(msg, 'text', subtype, headers)
cte, payload = _encode_text(string, charset, cte, msg.policy)
msg.set_payload(payload)
msg.set_param('charset',
email.charset.ALIASES.get(charset, charset),
replace=True)
msg['Content-Transfer-Encoding'] = cte
_finalize_set(msg, disposition, filename, cid, params)
raw_data_manager.add_set_handler(str, set_text_content)
def set_message_content(msg, message, subtype="rfc822", cte=None,
disposition=None, filename=None, cid=None,
params=None, headers=None):
if subtype == 'partial':
raise ValueError("message/partial is not supported for Message objects")
if subtype == 'rfc822':
if cte not in (None, '7bit', '8bit', 'binary'):
# http://tools.ietf.org/html/rfc2046#section-5.2.1 mandate.
raise ValueError(
"message/rfc822 parts do not support cte={}".format(cte))
# 8bit will get coerced on serialization if policy.cte_type='7bit'. We
# may end up claiming 8bit when it isn't needed, but the only negative
# result of that should be a gateway that needs to coerce to 7bit
# having to look through the whole embedded message to discover whether
# or not it actually has to do anything.
cte = '8bit' if cte is None else cte
elif subtype == 'external-body':
if cte not in (None, '7bit'):
# http://tools.ietf.org/html/rfc2046#section-5.2.3 mandate.
raise ValueError(
"message/external-body parts do not support cte={}".format(cte))
cte = '7bit'
elif cte is None:
# http://tools.ietf.org/html/rfc2046#section-5.2.4 says all future
# subtypes should be restricted to 7bit, so assume that.
cte = '7bit'
_prepare_set(msg, 'message', subtype, headers)
msg.set_payload([message])
msg['Content-Transfer-Encoding'] = cte
_finalize_set(msg, disposition, filename, cid, params)
raw_data_manager.add_set_handler(email.message.Message, set_message_content)
def set_bytes_content(msg, data, maintype, subtype, cte='base64',
disposition=None, filename=None, cid=None,
params=None, headers=None):
_prepare_set(msg, maintype, subtype, headers)
if cte == 'base64':
data = _encode_base64(data, max_line_length=msg.policy.max_line_length)
elif cte == 'quoted-printable':
# XXX: quoprimime.body_encode won't encode newline characters in data,
# so we can't use it. This means max_line_length is ignored. Another
# bug to fix later. (Note: encoders.quopri is broken on line ends.)
data = binascii.b2a_qp(data, istext=False, header=False, quotetabs=True)
data = data.decode('ascii')
elif cte == '7bit':
# Make sure it really is only ASCII. The early warning here seems
# worth the overhead...if you care write your own content manager :).
data.encode('ascii')
elif cte in ('8bit', 'binary'):
data = data.decode('ascii', 'surrogateescape')
msg.set_payload(data)
msg['Content-Transfer-Encoding'] = cte
_finalize_set(msg, disposition, filename, cid, params)
for typ in (bytes, bytearray, memoryview):
raw_data_manager.add_set_handler(typ, set_bytes_content)