email.headerregistry: اشیاء سرآیند سفارشی¶
کد منبع: Lib/email/headerregistry.py
اضافه شده در نسخهی 3.6: [1]
سرآیندها با زیرکلاسهای سفارشی از str نمایش داده میشوند. کلاس خاصی که برای نمایش یک سرآیند مشخص به کار میرود، توسط header_factory از policy که در زمان ایجاد سرآیندها معتبر است، تعیین میشود. این بخش header_factory خاصی را مستند میکند که توسط بسته email برای مدیریت پیامهای ایمیل منطبق با RFC 5322 پیادهسازی شده است و نهتنها اشیای سرآیند سفارشی برای انواع مختلف سرآیند فراهم میکند، بلکه سازوکار توسعهای برای برنامهها فراهم میکند تا انواع سرآیند سفارشی خود را اضافه کنند.
هنگام استفاده از هر یک از اشیاء سیاست مشتقشده از EmailPolicy، تمام سرآیندها توسط HeaderRegistry تولید میشوند و BaseHeader را بهعنوان آخرین کلاس پایه خود دارند. هر کلاس سرآیند یک کلاس پایه اضافی دارد که بر اساس نوع سرآیند تعیین میشود. برای مثال، بسیاری از سرآیندها کلاس UnstructuredHeader را بهعنوان کلاس پایه دیگر خود دارند. کلاس دوم تخصصی برای یک سرآیند، با استفاده از جدول جستجویی که در HeaderRegistry ذخیرهشده است، بر اساس نام سرآیند تعیین میشود. همه این موارد برای برنامه کاربردی معمول بهصورت شفاف مدیریت میشوند، اما رابطهایی برای تغییر رفتار پیشفرض جهت استفاده در برنامههای پیچیدهتر فراهم شدهاند.
بخشهای زیر ابتدا کلاسهای پایهی سرآیند و ویژگیهای آنها را مستند میکنند، سپس به API برای تغییر رفتار HeaderRegistry میپردازند، و در نهایت کلاسهای پشتیبانی مورد استفاده برای بازنمایی دادههای تجزیهشده از سرآیندهای ساختاریافته را پوشش میدهند.
- class email.headerregistry.BaseHeader(name, value)¶
name and value are passed to
BaseHeaderfrom theheader_factorycall. The string value of any header object is the value fully decoded to a string.این کلاس پایه، ویژگیهای فقطخواندنی زیر را تعریف میکند:
- name¶
نام سرآیند (بخش فیلد پیش از ':'). این دقیقاً همان مقداری است که بهعنوان name در فراخوانی
header_factoryارسال شده است؛ یعنی بزرگی و کوچکی حروف حفظ میشود.
- defects¶
یک تاپل از نمونههای
HeaderDefectکه هر مشکل انطباق با RFC را که در حین تجزیه یافت میشود، گزارش میکنند. بستهی email تلاش میکند در تشخیص مسائل انطباق کامل باشد. برای بحثی در مورد انواع نقصهایی که ممکن است گزارش شوند، ماژولerrorsرا ببینید.
- max_count¶
حداکثر تعداد سرآیندهای این نوع که میتوانند
nameیکسانی داشته باشند. مقدارNoneبه معنای نامحدود است. مقدار این ویژگی درBaseHeaderبرابرNoneاست؛ انتظار میرود کلاسهای سرآیند تخصصی این مقدار را در صورت نیاز بازنویسی کنند.
BaseHeaderهمچنین متد زیر را ارائه میدهد، که توسط کد کتابخانه ایمیل فراخوانی میشود و بهطور کلی نباید توسط برنامههای کاربردی فراخوانی شود:- fold(*, policy)¶
رشتهای حاوی نویسههای
linesepبهمیزان لازم برای تا کردن صحیح سرآیند مطابق policy برمیگرداند.cte_typeبا مقدار8bitبهصورت7bitدر نظر گرفته میشود، زیرا سرآیندها نمیتوانند حاوی دادههای دودویی دلخواه باشند. اگرutf8برابرFalseباشد، دادههای غیر ASCII طبق RFC 2047 کدگذاری میشوند.
BaseHeaderبهتنهایی نمیتواند برای ایجاد یک شیء سرآیند به کار رود. این کلاس پروتکلی را تعریف میکند که هر سرآیند تخصصی برای ایجاد شیء سرآیند با آن همکاری میکند. بهطور مشخص،BaseHeaderالزام میکند که کلاس تخصصی یکclassmethod()به نامparseفراهم کند. این متد بهصورت زیر فراخوانی میشود:parse(string, kwds)
kwdsis a dictionary containing one pre-initialized key,defects.defectsis an empty list. The parse method should append any detected defects to this list. On return, thekwdsdictionary must contain values for at least the keysdecoded,defectsandparse_tree.decodedshould be the string value for the header (that is, the header value fully decoded to a string).parse_treeis set to the parse tree obtained from parsing the header. The parse method should assume that string may contain content-transfer-encoded parts, but should correctly handle all valid Unicode characters as well so that it can parse un-encoded header values.سپس
__new__BaseHeaderنمونهی سرآیند را ایجاد میکند و متدinitآن را فراخوانی میکند. کلاس تخصصی تنها در صورتی لازم است یک متدinitارائه کند که بخواهد ویژگیهای اضافی، فراتر از آنچه خودBaseHeaderفراهم میکند، تنظیم کند. چنین متدinitباید به این صورت باشد:def init(self, /, *args, **kw): self._myattr = kw.pop('myattr') super().init(*args, **kw)
یعنی هر چیز اضافی که کلاس تخصصی در دیکشنری
kwdsقرار میدهد باید حذف و مدیریت شود، و محتوای باقیماندهیkw(وargs) به متدinitازBaseHeaderارسال شود.
- class email.headerregistry.UnstructuredHeader¶
یک سرآیند «بدون ساختار»، نوع پیشفرض سرآیند در RFC 5322 است. هر سرآیندی که سینتکس مشخصی نداشته باشد، بدون ساختار تلقی میشود. یک نمونه کلاسیک از سرآیند بدون ساختار، سرآیند Subject است.
In RFC 5322, an unstructured header is a run of arbitrary text in the ASCII character set. RFC 2047, however, has an RFC 5322 compatible mechanism for encoding non-ASCII text as ASCII characters within a header value. When a value containing encoded words is passed to the constructor, the
UnstructuredHeaderparser converts such encoded words into a string, following the RFC 2047 rules for unstructured text. The parser uses heuristics to attempt to decode certain non-compliant encoded words. Defects are registered in such cases, as well as defects for issues such as invalid characters within the encoded words or the non-encoded text.این نوع سرآیند، هیچ ویژگی اضافهای ارائه نمیدهد.
- class email.headerregistry.DateHeader¶
RFC 5322 قالب بسیار مشخصی را برای تاریخها در سرآیندهای ایمیل تعیین میکند. پارسر
DateHeaderآن قالب تاریخ و همچنین تعدادی از صورتهای متفاوت را که گاهی «در عمل» یافت میشوند، تشخیص میدهد.این نوع سرآیند، ویژگیهای اضافی زیر را فراهم میکند:
- datetime¶
اگر مقدار سرآیند بتواند بهعنوان یک تاریخ معتبر در یکی از قالبها تشخیص داده شود، این ویژگی شامل یک نمونه
datetimeخواهد بود که نشاندهنده آن تاریخ است. اگر منطقه زمانی تاریخ ورودی بهصورت-0000مشخص شده باشد (که نشان میدهد در UTC است اما حاوی اطلاعاتی درباره منطقه زمانی منبع نیست)، آنگاهdatetimeیکdatetimeساده خواهد بود. اگر یک آفست منطقه زمانی مشخص یافت شود (از جمله+0000)، آنگاهdatetimeشامل یکdatetimeآگاه خواهد بود که ازdatetime.timezoneبرای ثبت آفست منطقه زمانی استفاده میکند.
مقدار
decodedسرآیند با قالببندیdatetimeمطابق قواعد RFC 5322 تعیین میشود؛ یعنی، بهصورت زیر تنظیم میشود:email.utils.format_datetime(self.datetime)
هنگام ایجاد یک
DateHeader، value میتواند نمونهای ازdatetimeباشد. این بدان معناست که، برای مثال، کد زیر معتبر است و همان کاری را که انتظار میرود انجام میدهد:msg['Date'] = datetime(2011, 7, 15, 21)
از آنجا که این یک
datetimeساده (naive) است، بهعنوان یک مهر زمانی UTC تفسیر میشود و مقدار حاصل دارای منطقه زمانی-0000خواهد بود. بسیار مفیدتر آن است که از تابعlocaltime()در ماژولutilsاستفاده کنید:msg['Date'] = utils.localtime()
این مثال سرآیند تاریخ را با استفاده از آفست منطقهی زمانی (timezone offset) فعلی، روی زمان و تاریخ فعلی تنظیم میکند.
- class email.headerregistry.AddressHeader¶
سرآیندهای نشانی یکی از پیچیدهترین انواع سرآیندهای ساختاریافته هستند. کلاس
AddressHeaderیک رابط عام برای هر سرآیند نشانی ارائه میدهد.این نوع سرآیند، ویژگیهای اضافی زیر را فراهم میکند:
- groups¶
یک تاپل از اشیای
Groupکه نشانیها و گروههای یافتشده در مقدار سرآیند را کدگذاری میکنند. نشانیهایی که بخشی از یک گروه نیستند، در این فهرست بهصورتGroupsهای تکنشانی بازنمایی میشوند کهdisplay_nameآنهاNoneاست.
- addresses¶
تاپلی از اشیای
Addressکه همهی نشانیهای منفردِ موجود در مقدار سرایند را کدگذاری میکنند. اگر مقدار سرایند شامل گروهی باشد، نشانیهای منفردِ آن گروه در نقطهای که گروه در مقدار ظاهر میشود، در فهرست گنجانده میشوند (یعنی فهرست نشانیها به یک فهرست یکبعدی «تختشده» تبدیل میشود).
The
decodedvalue of the header will have all encoded words decoded to a string.idnaencoded domain names are also decoded to a string. Thedecodedvalue is set by joining thestrvalue of the elements of thegroupsattribute with', '.میتوان از فهرستی از اشیاء
AddressوGroupدر هر ترکیبی برای تنظیم مقدار یک سرآیند نشانی استفاده کرد. اشیاءGroupکهdisplay_nameآنهاNoneاست، بهعنوان نشانیهای منفرد تعبیر میشوند؛ این امر امکان میدهد یک فهرست نشانی با حفظ گروهها، با استفاده از فهرستی که از ویژگیgroupsسرآیند مبدأ به دست میآید، کپی شود.
- class email.headerregistry.SingleAddressHeader¶
زیرکلاسی از
AddressHeaderکه یک ویژگی اضافی میافزاید:- address¶
تنها نشانی کدگذاریشده توسط مقدار سرآیند. اگر مقدار سرآیند در واقع شامل بیش از یک نشانی باشد (که تحت
policyپیشفرض، نقض RFC خواهد بود)، دسترسی به این ویژگی منجر بهValueErrorخواهد شد.
بسیاری از کلاسهای فوق همچنین دارای یک گونهی Unique هستند (برای مثال، UniqueUnstructuredHeader). تنها تفاوت این است که در گونهی Unique، max_count روی ۱ تنظیم شده است.
- class email.headerregistry.MIMEVersionHeader¶
در واقع تنها یک مقدار معتبر برای سرآیند MIME-Version وجود دارد، و آن
1.0است. برای سازگاری با آینده، این کلاس سرآیند از سایر شمارههای نسخه معتبر نیز پشتیبانی میکند. اگر یک شماره نسخه مقدار معتبری مطابق RFC 2045 داشته باشد، شیء سرآیند برای ویژگیهای زیر مقادیر غیرNoneخواهد داشت:- version¶
شماره نسخه بهصورت یک رشته، با حذف هرگونه فضای سفید و/یا کامنت.
- major¶
شماره نسخه اصلی بهصورت عدد صحیح
- minor¶
شماره نسخه فرعی بهصورت عدد صحیح
- class email.headerregistry.ParameterizedMIMEHeader¶
همه سرآیندهای MIME با پیشوند 'Content-' شروع میشوند. هر سرآیند خاص، مقدار معینی دارد که در ذیل کلاس مربوط به آن سرآیند توضیح داده شده است. برخی نیز میتوانند فهرستی از پارامترهای تکمیلی را بپذیرند که قالب مشترکی دارند. این کلاس بهعنوان پایهای برای همه سرآیندهای MIME که پارامتر میپذیرند، عمل میکند.
- params¶
یک دیکشنری که نامهای پارامتر را به مقادیر پارامتر نگاشت میکند.
- class email.headerregistry.ContentTypeHeader¶
یک کلاس
ParameterizedMIMEHeaderکه سرآیند Content-Type را مدیریت میکند.- content_type¶
رشتهی نوع محتوا، در قالب
maintype/subtype.
- maintype¶
- subtype¶
- class email.headerregistry.ContentDispositionHeader¶
یک کلاس
ParameterizedMIMEHeaderکه سرآیند Content-Disposition را مدیریت میکند.- content_disposition¶
تنها مقادیر معتبرِ رایج،
inlineوattachmentهستند.
- class email.headerregistry.ContentTransferEncodingHeader¶
سرآیند Content-Transfer-Encoding را مدیریت میکند.
- class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)¶
این کارخانهای است که
EmailPolicyبهطور پیشفرض از آن استفاده میکند.HeaderRegistryبا استفاده از base_class و یک کلاس تخصصی بازیابیشده از رجیستری که در اختیار دارد، بهصورت پویا کلاسی را میسازد که برای ایجاد یک نمونه سرآیند استفاده میشود. هنگامی که یک نام سرآیند معین در رجیستری وجود نداشته باشد، کلاس مشخصشده توسط default_class بهعنوان کلاس تخصصی استفاده میشود. هنگامی که use_default_map برابرTrueباشد (مقدار پیشفرض)، نگاشت استاندارد نامهای سرآیند به کلاسها در حین مقداردهی اولیه به رجیستری کپی میشود. base_class همیشه آخرین کلاس در فهرست__bases__کلاس ساختهشده است.نگاشتهای پیشفرض عبارتند از:
- subject:
UniqueUnstructuredHeader
- date:
UniqueDateHeader
- resent-date:
DateHeader
- orig-date:
UniqueDateHeader
- sender:
UniqueSingleAddressHeader
- resent-sender:
SingleAddressHeader
- to:
UniqueAddressHeader
- resent-to:
AddressHeader
- cc:
UniqueAddressHeader
- resent-cc:
AddressHeader
- bcc:
UniqueAddressHeader
- resent-bcc:
AddressHeader
- from:
UniqueAddressHeader
- resent-from:
AddressHeader
- reply-to:
UniqueAddressHeader
- mime-version:
MIMEVersionHeader
- content-type:
ContentTypeHeader
- content-disposition:
ContentDispositionHeader
- content-transfer-encoding:
ContentTransferEncodingHeader
- message-id:
MessageIDHeader
HeaderRegistryمتدهای زیر را دارد:- map_to_type(self, name, cls)¶
name نام سرآیندی است که باید نگاشت شود. این نام در رجیستری به حروف کوچک تبدیل میشود. cls کلاس تخصصی است که به همراه base_class، برای ایجاد کلاسی به کار میرود که سرآیندهای منطبق با name را نمونهسازی میکند.
- __getitem__(name)¶
یک کلاس را برای مدیریت ایجاد سرآیند name بسازید و برگردانید.
- __call__(name, value)¶
سرآیند اختصاصی مرتبط با name را از رجیستری بازیابی میکند (اگر name در رجیستری وجود نداشته باشد، از default_class استفاده میشود) و آن را با base_class ترکیب میکند تا کلاسی تولید شود، سازندهی کلاس ساختهشده را با همان فهرست آرگومانها فراخوانی میکند و در نهایت نمونهی کلاس ایجادشده از این طریق را برمیگرداند.
کلاسهای زیر کلاسهایی هستند که برای نمایش دادههای تجزیهشده از سرآیندهای ساختیافته استفاده میشوند و بهطور کلی یک برنامه کاربردی میتواند از آنها برای ساخت مقادیر ساختیافته جهت انتساب به سرآیندهای مشخص استفاده کند.
- class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)¶
کلاسی که برای نمایش یک نشانی ایمیل استفاده میشود. شکل کلی یک نشانی به این صورت است:
[display_name] <username@domain>
یا:
username@domain
که هر بخش باید با قواعد سینتکسی خاصی که در RFC 5322 تشریح شده است مطابقت داشته باشد.
As a convenience addr_spec can be specified instead of username and domain, in which case username and domain will be parsed from the addr_spec. An addr_spec must be a properly RFC quoted string; if it is not
Addresswill raise an error. Unicode characters are allowed and will be property encoded when serialized. However, per the RFCs, Unicode is not allowed in the username portion of the address.- display_name¶
بخش نام نمایشی نشانی، در صورت وجود، با حذف تمام علامتهای نقلقول. اگر نشانی نام نمایشی نداشته باشد، این ویژگی یک رشته خالی خواهد بود.
- username¶
بخش
usernameاز نشانی، با حذف تمام علامتهای نقلقول.
- domain¶
بخش
domainاز نشانی.
- addr_spec¶
بخش
username@domainاز نشانی، که بهدرستی در علامت نقلقول قرار گرفته است تا بهعنوان یک نشانی ساده (دومین شکل نشاندادهشده در بالا) استفاده شود. این ویژگی تغییرپذیر نیست.
- __str__()¶
مقدار
strشیء، نشانی نقلقولشده مطابق قواعد RFC 5322 است، اما بدون کدگذاری انتقال محتوا (Content Transfer Encoding) برای هیچیک از نویسههای غیر ASCII.
برای پشتیبانی از SMTP (RFC 5321)،
Addressیک حالت خاص را مدیریت میکند: اگرusernameوdomainهر دو رشته خالی (یاNone) باشند، مقدار رشتهایAddressبرابر<>است.
- class email.headerregistry.Group(display_name=None, addresses=None)¶
کلاسی که برای بازنمایی یک گروه نشانی استفاده میشود. شکل کلی یک گروه نشانی به این صورت است:
display_name: [address-list];
برای سهولت در پردازش فهرستهایی از نشانیها که شامل ترکیبی از گروهها و نشانیهای تکی هستند، میتوان از
Groupهمچنین برای نمایش نشانیهای تکی که بخشی از یک گروه نیستند استفاده کرد؛ برای این کار display_name را رویNoneتنظیم کنید و فهرستی از نشانی تکی را بهعنوان addresses ارائه دهید.- display_name¶
display_nameگروه. اگر این مقدارNoneباشد و دقیقاً یکAddressدرaddressesوجود داشته باشد، آنگاهGroupنشاندهندهی یک نشانی واحد است که در گروهی نیست.
- __str__()¶
مقدار
strیکGroupمطابق RFC 5322 قالببندی میشود، اما بدون اعمال کدگذاری انتقال محتوا (Content Transfer Encoding) بر هیچیک از نویسههای غیر ASCII. اگرdisplay_nameوجود نداشته باشد و تنها یکAddressدر فهرستaddressesوجود داشته باشد، مقدارstrبرابر باstrهمانAddressتنها خواهد بود.
پانویسها