email.header: سرآیندهای بین‌المللی‌سازی‌شده

کد منبع: Lib/email/header.py


این ماژول بخشی از API ایمیل قدیمی (Compat32) است. در API کنونی، کدگذاری و کدگشایی سرآیند‌ها به‌صورت شفاف توسط API دیکشنری‌مانند کلاس EmailMessage انجام می‌شود. علاوه بر استفاده در کد قدیمی، این ماژول می‌تواند در برنامه‌هایی که نیاز دارند مجموعه‌های نویسه‌ای را که هنگام کدگذاری سرآیند‌ها استفاده می‌شوند به‌طور کامل کنترل کنند، مفید باشد.

متن باقی‌مانده در این بخش، مستندات اصلی ماژول است.

RFC 2822 استاندارد پایه‌ای است که قالب پیام‌های ایمیل را توصیف می‌کند. این استاندارد برگرفته از استاندارد قدیمی‌تر RFC 822 است که در زمانی به‌طور گسترده‌ای استفاده می‌شد که بیشتر ایمیل‌ها فقط از نویسه‌های ASCII تشکیل شده بودند. RFC 2822 مشخصاتی است که با این فرض نوشته شده است که ایمیل فقط شامل نویسه‌های ASCII هفت‌بیتی است.

البته، از آن‌جا که ایمیل در سراسر جهان گسترش یافته است، بین‌المللی شده است، به‌طوری که اکنون می‌توان از مجموعه‌نویسه‌های مختص هر زبان در پیام‌های ایمیل استفاده کرد. استاندارد پایه همچنان نیاز دارد که پیام‌های ایمیل فقط با نویسه‌های ASCII هفت‌بیتی منتقل شوند، بنابراین RFCهای متعددی نوشته شده‌اند که نحوه‌ی کدگذاری ایمیل حاوی نویسه‌های غیر ASCII به قالب سازگار با RFC 2822 را توصیف می‌کنند. این RFCها شامل RFC 2045، RFC 2046، RFC 2047 و RFC 2231 هستند. بسته‌ی email از این استانداردها در ماژول‌های email.header و email.charset پشتیبانی می‌کند.

اگر می‌خواهید نویسه‌های غیر ASCII را در سرآیندهای ایمیل خود بگنجانید، مثلاً در فیلدهای Subject یا To، باید از کلاس Header استفاده کنید و فیلد را در شیء Message به نمونه‌ای از Header اختصاص دهید، به‌جای آن‌که برای مقدار سرآیند از یک رشته استفاده کنید. کلاس Header را از ماژول email.header ایمپورت کنید. برای مثال:

>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'

Notice here how we wanted the Subject field to contain a non-ASCII character? We did this by creating a Header instance and passing in the character set to use when encoding it. When the subsequent Message instance was flattened, the Subject field was properly RFC 2047 encoded. MIME-aware mail readers would show this header using the embedded ISO-8859-1 character.

در اینجا توضیح کلاس Header آمده است:

class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')

یک سرآیند سازگار با MIME ایجاد کنید که بتواند حاوی رشته‌هایی در مجموعه‌نویسه‌های مختلف باشد.

آرگومان اختیاری s، مقدار اولیه‌ی سرآیند است. اگر None (پیش‌فرض) باشد، مقدار اولیه‌ی سرآیند تنظیم نمی‌شود. می‌توانید بعداً با فراخوانی‌های متد append() به سرآیند اضافه کنید. s ممکن است یک نمونه از bytes یا str باشد، اما برای معناییات، مستندات append() را ببینید.

charset اختیاری دو هدف دارد: این آرگومان همان معنای آرگومان charset در متد append() را دارد. همچنین مجموعه نویسه‌ی پیش‌فرض را برای تمام فراخوانی‌های بعدی append() که در آن‌ها آرگومان charset ذکر نشده است، تنظیم می‌کند. اگر charset در سازنده ارائه نشود (پیش‌فرض)، مجموعه نویسه‌ی us-ascii هم به‌عنوان مجموعه نویسه اولیه‌ی s و هم به‌عنوان پیش‌فرض برای فراخوانی‌های بعدی append() استفاده می‌شود.

می‌توان حداکثر طول خط را به‌صورت صریح از طریق maxlinelen مشخص کرد. برای شکستن خط اول به طول کوتاه‌تر (برای در نظر گرفتن سرآیند فیلد که در s لحاظ نشده است، مثلاً Subject)، نام فیلد را در header_name وارد کنید. مقدار پیش‌فرض maxlinelen برابر ۷۸ است و مقدار پیش‌فرض header_name برابر None است، به این معنا که برای خط اولِ یک سرآیند طولانیِ شکسته‌شده در نظر گرفته نمی‌شود.

continuation_ws اختیاری باید فضای خالی برای تا کردن سطرهای (folding whitespace) سازگار با RFC 2822 باشد، و معمولاً یا یک فاصله است یا یک نویسه‌ی تب سخت (hard tab). این نویسه به ابتدای سطرهای ادامه افزوده می‌شود. مقدار پیش‌فرض continuation_ws یک نویسه‌ی فاصله است.

آرگومان اختیاری errors مستقیماً به متد append() ارسال می‌شود.

append(s, charset=None, errors='strict')

رشته‌ی s را به سرآیند MIME می‌افزاید.

charset اختیاری، در صورت داده شدن، باید نمونه‌ای از Charset (ببینید email.charset) یا نام یک مجموعه‌ی نویسه باشد، که به نمونه‌ای از Charset تبدیل خواهد شد. مقدار None (پیش‌فرض) به این معناست که charset داده‌شده در سازنده استفاده می‌شود.

s می‌تواند نمونه‌ای از bytes یا str باشد. اگر نمونه‌ای از bytes باشد، آنگاه charset کدگذاری آن رشته بایتی است، و اگر رشته نتواند با آن مجموعه نویسه کدگشایی شود، UnicodeError پرتاب خواهد شد.

اگر s نمونه‌ای از str باشد، آنگاه charset راهنمایی است که مجموعه نویسه‌های موجود در رشته را مشخص می‌کند.

در هر یک از این دو حالت، هنگام تولید سرآیندی مطابق با RFC 2822 با استفاده از قوانین RFC 2047، رشته با کدک خروجی مجموعه‌نویسه کدگذاری می‌شود. اگر رشته با کدک خروجی قابل کدگذاری نباشد، یک UnicodeError پرتاب خواهد شد.

اگر s یک رشته بایتی باشد، errors اختیاری به‌عنوان آرگومان errors به فراخوانی decode ارسال می‌شود.

encode(splitchars=';, \t', maxlinelen=None, linesep='\n')

کدگذاری یک سرآیند پیام در قالبی مطابق با RFC، احتمالاً با شکستن سطرهای طولانی و بسته‌بندی بخش‌های غیر ASCII در کدگذاری‌های base64 یا quoted-printable.

splitchars اختیاری، رشته‌ای است شامل نویسه‌هایی که الگوریتم شکستن باید در جریان شکستن عادی سطرهای سرایند، وزن بیشتری به آن‌ها بدهد. این موضوع، پشتیبانی بسیار تقریبی از «شکست‌های نحوی سطح بالاتر» در RFC 2822 است: هنگام شکستن سطرهای، نقاط شکستی که پیش از آن‌ها یک نویسه‌ی شکست قرار دارد، ترجیح داده می‌شوند و نویسه‌ها به همان ترتیبی که در رشته ظاهر می‌شوند، ترجیح داده می‌شوند. فاصله و تب می‌توانند در رشته گنجانده شوند تا مشخص شود که در صورت نبودن سایر نویسه‌های شکست در سطری که شکسته می‌شود، باید به کدام‌یک به‌عنوان نقطه‌ی شکست ترجیح داده شود. Splitchars بر سطرهای کدگذاری‌شده‌ی RFC 2047 تأثیری ندارد.

اگر داده شود، maxlinelen مقدار نمونه برای حداکثر طول خط را نادیده می‌گیرد.

linesep نویسه‌های استفاده‌شده برای جدا کردن سطرهای سرآیند تاشده را مشخص می‌کند. مقدار پیش‌فرض آن مفیدترین مقدار برای کد برنامه پایتون (\n) است، اما می‌توان \r\n را مشخص کرد تا سرآیندهایی با جداکننده‌های خط منطبق با RFC تولید شوند.

تغییر یافته در نسخه‌ی 3.2: آرگومان linesep افزوده شد.

کلاس Header همچنین تعدادی متد برای پشتیبانی از عملگرهای استاندارد و توابع توکار فراهم می‌کند.

__str__()

Returns an approximation of the Header as a string, using an unlimited line length. All pieces are decoded using the specified encoding and joined together appropriately. Any pieces with a charset of 'unknown-8bit' are decoded as ASCII using the 'replace' error handler.

تغییر یافته در نسخه‌ی 3.2: پشتیبانی از مجموعه‌نویسه‌ی 'unknown-8bit' افزوده شد.

__eq__(other)

این متد به شما امکان می‌دهد دو نمونه از Header را از نظر برابری مقایسه کنید.

__ne__(other)

این متد به شما امکان می‌دهد دو نمونه از Header را از نظر نابرابری مقایسه کنید.

ماژول email.header همچنین توابع کاربردی زیر را فراهم می‌کند.

email.header.decode_header(header)

یک مقدار سرآیند پیام را بدون تبدیل مجموعه نویسه کدگشایی کنید. مقدار سرآیند در header قرار دارد.

به دلایل تاریخی، این تابع ممکن است یکی از این دو مورد را برگرداند:

  1. فهرستی از جفت‌ها که شامل هر یک از بخش‌های کدگشایی‌شده‌ی سرآیند است، (decoded_bytes, charset)، که در آن decoded_bytes همیشه یک نمونه از bytes است و charset یکی از موارد زیر است:

    • رشته‌ای با حروف کوچک که شامل نام مجموعه‌ی نویسه‌ی مشخص‌شده است.

    • None برای بخش‌های کدگذاری‌نشده‌ی سرآیند.

  2. فهرستی به طول ۱ شامل یک جفت (string, None)، که در آن string همیشه نمونه‌ای از str است.

هنگامی که خطاهای کدگشایی خاصی رخ می‌دهند (برای مثال، یک استثنای کدگشایی base64)، ممکن است email.errors.HeaderParseError پرتاب شود.

در اینجا مثال‌هایی آمده است:

>>> from email.header import decode_header
>>> decode_header('=?iso-8859-1?q?p=F6stal?=')
[(b'p\xf6stal', 'iso-8859-1')]
>>> decode_header('unencoded_string')
[('unencoded_string', None)]
>>> decode_header('bar =?utf-8?B?ZsOzbw==?=')
[(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]

توجه

این تابع فقط برای سازگاری با نسخه‌های قدیمی‌تر وجود دارد. برای کد جدید، توصیه می‌کنیم از email.headerregistry.HeaderRegistry استفاده کنید.

email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')

یک نمونه Header را از دنباله‌ای از جفت‌ها، همان‌گونه که توسط decode_header() برگردانده می‌شود، ایجاد کنید.

decode_header() یک رشته مقدار سرآیند را می‌گیرد و دنباله‌ای از جفت‌ها در قالب (decoded_string, charset) برمی‌گرداند که charset نام مجموعه نویسه‌ها است.

این تابع یکی از آن دنباله‌های جفت‌ها را می‌گیرد و یک نمونه Header را برمی‌گرداند. آرگومان‌های اختیاری maxlinelen، header_name و continuation_ws همانند سازنده‌ی Header هستند.

توجه

این تابع فقط برای سازگاری با نسخه‌های قبلی وجود دارد و استفاده از آن در کد جدید توصیه نمی‌شود.