email.generator: تولید اسناد MIME¶
کد منبع: Lib/email/generator.py
یکی از رایجترین وظایف، تولید نسخهی تخت (سریالشده) پیام ایمیلی است که توسط یک ساختار شیء پیام نمایش داده میشود. اگر بخواهید پیام خود را از طریق smtplib.SMTP.sendmail() ارسال کنید، یا پیام را در کنسول چاپ کنید، باید این کار را انجام دهید. دریافت یک ساختار شیء پیام و تولید یک بازنمایی سریالشده، وظیفهی کلاسهای تولیدگر است.
مانند ماژول email.parser، شما محدود به کارکرد تولیدگر همراه نیستید؛ میتوانید خودتان یکی را از صفر بنویسید. با این حال، تولیدگر همراه میداند چگونه بیشتر پیامهای ایمیل را بهصورت سازگار با استانداردها تولید کند، باید پیامهای ایمیل MIME و غیر MIME را بهخوبی مدیریت کند، و بهگونهای طراحی شده است که عملیات تجزیه و تولید مبتنی بر بایت معکوس یکدیگر باشند، بهشرط آنکه برای هر دو از همان سیاست بدون تبدیل policy استفاده شود. یعنی تجزیهی جریان بایت سریالشده از طریق کلاس BytesParser و سپس تولید مجدد جریان بایت سریالشده با استفاده از BytesGenerator باید خروجیای کاملاً یکسان با ورودی تولید کند [1]. (از سوی دیگر، استفاده از تولیدگر روی یک EmailMessage که بهصورت برنامهای ساخته شده است ممکن است باعث ایجاد تغییراتی در شیء EmailMessage شود، زیرا مقادیر پیشفرض پر میشوند.)
میتوان از کلاس Generator برای تبدیل یک پیام به یک نمایش سریالسازیشدهی متنی (در مقابل دودویی) استفاده کرد، اما از آنجا که یونیکد نمیتواند دادههای دودویی را مستقیماً بازنمایی کند، پیام ناگزیر با استفاده از روشهای استاندارد RFC ایمیل برای کدگذاری انتقال محتوا (Content Transfer Encoding) جهت کدگذاری پیامهای ایمیل برای انتقال بر روی کانالهایی که «8 bit clean» نیستند، به چیزی تبدیل میشود که فقط شامل نویسههای ASCII باشد.
برای پشتیبانی از پردازش بازتولیدپذیر پیامهای امضاشده با SMIME، Generator شکستن سرآیند (header folding) را برای بخشهای پیام از نوع multipart/signed و همه زیربخشها غیرفعال میکند.
- class email.generator.BytesGenerator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
یک شیء
BytesGeneratorبرمیگرداند که هر پیام ارائهشده به متدflatten()، یا هر متن کدگذاریشده با surrogateescape ارائهشده به متدwrite()را در file-like object outfp مینویسد. outfp باید از یک متدwriteپشتیبانی کند که دادههای دودویی را میپذیرد.اگر mangle_from_ اختیاری
Trueباشد، یک نویسه>در ابتدای هر خط از بدنه که با رشته دقیق"From "شروع میشود، قرار میگیرد، یعنیFromو بهدنبال آن یک فاصله در ابتدای خط. مقدار پیشفرض mangle_from_ برابر با مقدار تنظیمmangle_from_در policy است (که برای سیاستcompat32برابرTrueو برای همه سیاستهای دیگرFalseاست). mangle_from_ برای استفاده در مواردی در نظر گرفته شده است که پیامها در قالب mbox یونیکس ذخیره میشوند (ببینیدmailboxو WHY THE CONTENT-LENGTH FORMAT IS BAD).اگر maxheaderlen برابر
Noneنباشد، هر خط سرآیندای که طولانیتر از maxheaderlen باشد دوباره تا زده میشود، یا اگر0باشد، هیچ سرآیندای دوباره پیچیده نمیشود. اگر manheaderlen برابرNoneباشد (پیشفرض)، سرآیندها و سایر سطرهای پیام طبق تنظیمات policy پیچیده میشوند.اگر policy مشخص شده باشد، از آن سیاست برای کنترل تولید پیام استفاده میشود. اگر policy برابر
Noneباشد (پیشفرض)، از سیاست مرتبط با شیءMessageیاEmailMessageارسالشده بهflattenبرای کنترل تولید پیام استفاده میشود. برای جزئیات درباره اینکه policy چه چیزی را کنترل میکند،email.policyرا ببینید.اضافه شده در نسخهی 3.2.
تغییر یافته در نسخهی 3.3: کلیدواژهی policy افزوده شد.
تغییر یافته در نسخهی 3.6: رفتار پیشفرض پارامترهای mangle_from_ و maxheaderlen پیروی از سیاست است.
- flatten(msg, unixfrom=False, linesep=None)¶
نمایش متنی ساختار شیء پیام ریشهگرفته از msg را در پرونده خروجی مشخصشده هنگام ایجاد نمونه
BytesGeneratorچاپ میکند.اگر گزینهی
policyیعنیcte_typeبرابر8bitباشد (پیشفرض)، تمام سرآیندهای موجود در پیام اصلی تجزیهشده که تغییر نکردهاند، به خروجی کپی میشوند، بهگونهای که بایتهایی که بیت بالایی آنها تنظیمشده است، همانطور که در پیام اصلی بودهاند بازتولید شوند، و Content-Transfer-Encoding غیر ASCII هر بخش بدنهای که دارای آن است حفظ میشود. اگرcte_typeبرابر7bitباشد، بایتهایی که بیت بالایی آنها تنظیمشده است، در صورت نیاز با استفاده از یک Content-Transfer-Encoding سازگار با ASCII تبدیل میشوند. یعنی بخشهایی که Content-Transfer-Encoding غیر ASCII دارند (Content-Transfer-Encoding: 8bit)، به یک Content-Transfer-Encoding سازگار با ASCII تبدیل میشوند، و بایتهای غیر ASCII نامعتبر از نظر RFC در سرآیندها، با استفاده از مجموعهنویسهیunknown-8bitدر MIME کدگذاری میشوند، و بدین ترتیب، آنها را با RFC سازگار میکند.اگر unixfrom برابر
Trueباشد، جداکنندهی سرآیند پاکت (envelope header delimiter) که در قالب صندوق پستی یونیکس استفاده میشود (بهmailboxمراجعه کنید) پیش از نخستین سرآیند از سرآیندهای RFC 5322 شیء پیام ریشه درج میشود. اگر شیء ریشه سرآیند پاکت نداشته باشد، یک سرآیند پاکت استاندارد ایجاد میشود. مقدار پیشفرضFalseاست. توجه داشته باشید که برای زیربخشها، هرگز هیچ سرآیند پاکتی درج نمیشود.اگر linesep
Noneنباشد، از آن بهعنوان نویسه جداکننده میان تمام سطرهای پیام مسطحشده استفاده میشود. اگر linesepNoneباشد (پیشفرض)، از مقدار تعیینشده در policy استفاده میشود.
- clone(fp)¶
یک رونوشت (clone) مستقل از این نمونهی
BytesGeneratorبا دقیقاً همان تنظیمات گزینهها، و با fp بهعنوان outfp جدید برمیگرداند.
- write(s)¶
s را با کدک
ASCIIو هندلر خطایsurrogateescapeکدگذاری کنید و آن را به متد write از outfp که به سازندهیBytesGeneratorارسال شده است، بفرستید.
برای سهولت، EmailMessage متدهای as_bytes() و bytes(aMessage) (که به __bytes__() نیز شناخته میشود) را فراهم میکند، که تولید یک نمایش دودویی سریالشده از یک شیء پیام را ساده میکنند. برای جزئیات بیشتر، email.message را ببینید.
از آنجا که رشتهها نمیتوانند دادههای دودویی را نشان دهند، کلاس Generator باید هرگونه دادهی دودویی موجود در هر پیامی را که بهصورت مسطح درمیآورد، با تبدیل آن به یک Content-Transfer_Encoding سازگار با ASCII، به قالبی سازگار با ASCII تبدیل کند. با استفاده از اصطلاحات RFCهای ایمیل، میتوانید اینطور تصور کنید که Generator در حال سریالسازی به یک جریان ورودی/خروجی است که «8 bit clean» نیست. به بیان دیگر، بیشتر برنامهها خواهند خواست از BytesGenerator استفاده کنند، نه Generator.
- class email.generator.Generator(outfp, mangle_from_=None, maxheaderlen=None, *, policy=None)¶
یک شیء
Generatorبازگشت میدهد که هر پیام ارائهشده به متدflatten()، یا هر متن ارائهشده به متدwrite()را در file-like object outfp مینویسد. outfp باید از یک متدwriteپشتیبانی کند که دادههای رشتهای را میپذیرد.اگر mangle_from_ اختیاری
Trueباشد، یک نویسه>در ابتدای هر خط از بدنه که با رشته دقیق"From "شروع میشود، قرار میگیرد، یعنیFromو بهدنبال آن یک فاصله در ابتدای خط. مقدار پیشفرض mangle_from_ برابر با مقدار تنظیمmangle_from_در policy است (که برای سیاستcompat32برابرTrueو برای همه سیاستهای دیگرFalseاست). mangle_from_ برای استفاده در مواردی در نظر گرفته شده است که پیامها در قالب mbox یونیکس ذخیره میشوند (ببینیدmailboxو WHY THE CONTENT-LENGTH FORMAT IS BAD).اگر maxheaderlen برابر
Noneنباشد، هر خط سرآیندای که طولانیتر از maxheaderlen باشد دوباره تا زده میشود، یا اگر0باشد، هیچ سرآیندای دوباره پیچیده نمیشود. اگر manheaderlen برابرNoneباشد (پیشفرض)، سرآیندها و سایر سطرهای پیام طبق تنظیمات policy پیچیده میشوند.اگر policy مشخص شده باشد، از آن سیاست برای کنترل تولید پیام استفاده میشود. اگر policy برابر
Noneباشد (پیشفرض)، از سیاست مرتبط با شیءMessageیاEmailMessageارسالشده بهflattenبرای کنترل تولید پیام استفاده میشود. برای جزئیات درباره اینکه policy چه چیزی را کنترل میکند،email.policyرا ببینید.تغییر یافته در نسخهی 3.3: کلیدواژهی policy افزوده شد.
تغییر یافته در نسخهی 3.6: رفتار پیشفرض پارامترهای mangle_from_ و maxheaderlen پیروی از سیاست است.
- flatten(msg, unixfrom=False, linesep=None)¶
نمایش متنی ساختار شیء پیام که ریشه در msg دارد را به پرونده خروجی مشخصشده در زمان ایجاد نمونهی
Generatorچاپ میکند.اگر گزینهی
cte_typeدرpolicyبرابر8bitباشد، پیام بهگونهای تولید میشود که گویی این گزینه روی7bitتنظیم شده است. (این کار لازم است، زیرا رشتهها نمیتوانند بایتهای غیرASCII را بازنمایی کنند.) بایتهایی که بیت پرارزش آنها ۱ است، در صورت لزوم با استفاده از یک Content-Transfer-Encoding سازگار با ASCII تبدیل میشوند. یعنی بخشهایی که Content-Transfer-Encoding غیرASCII دارند (Content-Transfer-Encoding: 8bit) به یک Content-Transfer-Encoding سازگار با ASCII تبدیل میشوند و بایتهای غیرASCII نامعتبر از نظر RFC در سرآیندها با استفاده از مجموعه نویسهیunknown-8bitدر MIME کدگذاری میشوند، تا بدین ترتیب آنها مطابق RFC شوند.اگر unixfrom برابر
Trueباشد، جداکنندهی سرآیند پاکت (envelope header delimiter) که در قالب صندوق پستی یونیکس استفاده میشود (بهmailboxمراجعه کنید) پیش از نخستین سرآیند از سرآیندهای RFC 5322 شیء پیام ریشه درج میشود. اگر شیء ریشه سرآیند پاکت نداشته باشد، یک سرآیند پاکت استاندارد ایجاد میشود. مقدار پیشفرضFalseاست. توجه داشته باشید که برای زیربخشها، هرگز هیچ سرآیند پاکتی درج نمیشود.اگر linesep
Noneنباشد، از آن بهعنوان نویسه جداکننده میان تمام سطرهای پیام مسطحشده استفاده میشود. اگر linesepNoneباشد (پیشفرض)، از مقدار تعیینشده در policy استفاده میشود.تغییر یافته در نسخهی 3.2: پشتیبانی از کدگذاری مجدد بدنههای پیام
8bitو آرگومان linesep افزوده شد.
برای سهولت، EmailMessage متدهای as_string() و str(aMessage) (یا همان __str__()) را فراهم میکند، که تولید یک نمایش رشتهای قالببندیشده از یک شیء پیام را ساده میکنند. برای جزئیات بیشتر، email.message را ببینید.
ماژول email.generator همچنین یک کلاس مشتق، DecodedGenerator، ارائه میکند که مانند کلاس پایهی Generator است، با این تفاوت که بخشهای غیر text سریالسازی نمیشوند، بلکه در جریان خروجی بهوسیلهی رشتهای نمایش داده میشوند که حاصل از الگویی است که با اطلاعات مربوط به آن بخش پر شده است.
- class email.generator.DecodedGenerator(outfp, mangle_from_=None, maxheaderlen=None, fmt=None, *, policy=None)¶
مانند
Generatorعمل میکند، با این تفاوت که برای هر زیربخشی از پیامی که بهGenerator.flatten()داده میشود، اگر زیربخش از نوع اصلی text باشد، بار کدگشاییشدهی آن زیربخش را چاپ میکند، و اگر نوع اصلی text نباشد، بهجای چاپ آن، رشته fmt را با استفاده از اطلاعات آن بخش تکمیل میکند و رشتهی تکمیلشدهی حاصل را چاپ میکند.برای پر کردن fmt، دستور
fmt % part_infoرا اجرا کنید، که در آنpart_infoیک دیکشنری متشکل از کلیدها و مقدارهای زیر است:type-- نوع MIME کاملِ بخش غیرِ textmaintype-- نوع MIME اصلیِ بخش غیرِ textsubtype-- زیرنوع MIME برای بخش غیر textfilename-- نام پرونده بخش غیر textdescription-- توضیح مرتبط با بخش غیرtextencoding-- کدگذاری انتقال محتوا برای بخش غیر text
اگر fmt برابر
Noneباشد، از fmt پیشفرض زیر استفاده کنید:[بخش غیرمتنی (%(type)s) پیام حذف شد، نام پرونده %(filename)s]
آرگومانهای اختیاری _mangle_from_ و maxheaderlen همانند کلاس پایهی
Generatorهستند.
پانویسها