email.headerregistry: Đối tượng tiêu đề tùy chỉnh

Source code: Lib/email/headerregistry.py


Added in version 3.6: [1]

Tiêu đề được thể hiện bằng các lớp con tùy chỉnh của str. Lớp cụ thể được sử dụng để thể hiện một tiêu đề nhất định được xác định bởi header_factory của policy có hiệu lực khi các tiêu đề được tạo. Phần này ghi lại header_factory cụ thể được gói email triển khai để xử lý các email tuân thủ RFC 5322, không chỉ cung cấp các đối tượng tiêu đề tùy chỉnh cho các loại tiêu đề khác nhau mà còn cung cấp cơ chế mở rộng để các ứng dụng thêm các loại tiêu đề tùy chỉnh của riêng chúng.

Khi sử dụng bất kỳ đối tượng chính sách nào bắt nguồn từ EmailPolicy, tất cả các tiêu đề đều được tạo bởi HeaderRegistry và có BaseHeader là lớp cơ sở cuối cùng của chúng. Mỗi lớp tiêu đề có một lớp cơ sở bổ sung được xác định theo loại tiêu đề. Ví dụ: nhiều tiêu đề có lớp UnstructuredHeader làm lớp cơ sở khác. Lớp thứ hai chuyên biệt cho tiêu đề được xác định theo tên của tiêu đề, sử dụng bảng tra cứu được lưu trữ trong HeaderRegistry. Tất cả điều này được quản lý một cách minh bạch cho chương trình ứng dụng thông thường, nhưng các giao diện được cung cấp để sửa đổi hành vi mặc định để các ứng dụng phức tạp hơn sử dụng.

Các phần bên dưới trước tiên ghi lại các lớp cơ sở tiêu đề và các thuộc tính của chúng, tiếp theo là API để sửa đổi hành vi của HeaderRegistry và cuối cùng là các lớp hỗ trợ được sử dụng để thể hiện dữ liệu được phân tích cú pháp từ các tiêu đề có cấu trúc.

class email.headerregistry.BaseHeader(name, value)

namevalue được chuyển tới BaseHeader từ lệnh gọi header_factory. Giá trị chuỗi của bất kỳ đối tượng tiêu đề nào là value được giải mã hoàn toàn thành unicode.

Lớp cơ sở này định nghĩa các thuộc tính chỉ đọc sau:

name

Tên của tiêu đề (phần trường trước ':'). Đây chính xác là giá trị được chuyển trong lệnh gọi header_factory cho name; nghĩa là trường hợp được bảo tồn.

defects

Một bộ phiên bản HeaderDefect báo cáo bất kỳ vấn đề tuân thủ RFC nào được tìm thấy trong quá trình phân tích cú pháp. Gói email cố gắng hoàn thiện việc phát hiện các vấn đề về tuân thủ. Xem mô-đun errors để biết thảo luận về các loại lỗi có thể được báo cáo.

max_count

Số lượng tiêu đề tối đa của loại này có thể có cùng name. Giá trị None có nghĩa là không giới hạn. Giá trị BaseHeader cho thuộc tính này là None; dự kiến ​​các lớp tiêu đề chuyên dụng sẽ ghi đè giá trị này nếu cần.

BaseHeader cũng cung cấp phương thức sau, được gọi bằng mã thư viện email và nói chung không nên được gọi bởi các chương trình ứng dụng:

fold(*, policy)

Trả về một chuỗi chứa các ký tự linesep theo yêu cầu để gấp tiêu đề một cách chính xác theo policy. Một cte_type của 8bit sẽ được xử lý như thể nó là 7bit, vì các tiêu đề không được chứa dữ liệu nhị phân tùy ý. Nếu utf8False, dữ liệu không phải ASCII sẽ được mã hóa RFC 2047.

Bản thân BaseHeader không thể được sử dụng để tạo đối tượng tiêu đề. Nó xác định một giao thức mà mỗi tiêu đề chuyên biệt hợp tác để tạo ra đối tượng tiêu đề. Cụ thể, BaseHeader yêu cầu lớp chuyên biệt cung cấp classmethod() có tên parse. Phương pháp này được gọi như sau:

phân tích  pháp (chuỗi, kwds)

kwds là một từ điển chứa một khóa được khởi tạo trước, defects. defects là một danh sách trống. Phương pháp phân tích cú pháp sẽ thêm bất kỳ lỗi nào được phát hiện vào danh sách này. Đổi lại, từ điển kwds must chứa các giá trị cho ít nhất các khóa decodeddefects. decoded phải là giá trị chuỗi cho tiêu đề (nghĩa là giá trị tiêu đề được giải mã hoàn toàn thành unicode). Phương pháp phân tích cú pháp phải giả định rằng string có thể chứa các phần được mã hóa truyền nội dung, nhưng cũng phải xử lý chính xác tất cả các ký tự unicode hợp lệ để có thể phân tích các giá trị tiêu đề chưa được mã hóa.

Sau đó, __new__ của BaseHeader sẽ tạo phiên bản tiêu đề và gọi phương thức init của nó. Lớp chuyên biệt chỉ cần cung cấp phương thức init nếu nó muốn đặt các thuộc tính bổ sung ngoài các thuộc tính do chính BaseHeader cung cấp. Phương thức init như vậy sẽ trông như thế này:

def init(self, /, *args, **kw):
    self._myattr = kw.pop('myattr')
    super().init(*args, **kw)

Nghĩa là, bất kỳ nội dung bổ sung nào mà lớp chuyên biệt đưa vào từ điển kwds đều phải bị xóa và xử lý, đồng thời nội dung còn lại của kw (và args) được chuyển sang phương thức BaseHeader init.

class email.headerregistry.UnstructuredHeader

Tiêu đề "không có cấu trúc" là loại tiêu đề mặc định trong RFC 5322. Bất kỳ tiêu đề nào không có cú pháp cụ thể đều được coi là không có cấu trúc. Ví dụ cổ điển về tiêu đề không có cấu trúc là tiêu đề Subject.

Trong RFC 5322, tiêu đề không có cấu trúc là một chuỗi văn bản tùy ý trong bộ ký tự ASCII. Tuy nhiên, RFC 2047 có cơ chế tương thích với RFC 5322 để mã hóa văn bản không phải ASCII thành các ký tự ASCII trong giá trị tiêu đề. Khi một value chứa các từ được mã hóa được chuyển đến hàm tạo, trình phân tích cú pháp UnstructuredHeader sẽ chuyển đổi các từ được mã hóa đó thành unicode, tuân theo các quy tắc RFC 2047 cho văn bản phi cấu trúc. Trình phân tích cú pháp sử dụng phương pháp phỏng đoán để cố gắng giải mã một số từ được mã hóa không tuân thủ. Các lỗi được ghi lại trong những trường hợp như vậy cũng như các lỗi liên quan đến các vấn đề như ký tự không hợp lệ trong các từ được mã hóa hoặc văn bản không được mã hóa.

Loại tiêu đề này không cung cấp thuộc tính bổ sung.

class email.headerregistry.DateHeader

RFC 5322 chỉ định một định dạng rất cụ thể cho ngày tháng trong tiêu đề email. Trình phân tích cú pháp DateHeader nhận dạng định dạng ngày tháng đó, cũng như nhận dạng một số dạng biến thể đôi khi được tìm thấy "trong tự nhiên".

Loại tiêu đề này cung cấp các thuộc tính bổ sung sau:

datetime

Nếu giá trị tiêu đề có thể được nhận dạng là ngày hợp lệ ở dạng này hay dạng khác thì thuộc tính này sẽ chứa phiên bản datetime đại diện cho ngày đó. Nếu múi giờ của ngày đầu vào được chỉ định là -0000 (cho biết nó nằm trong UTC nhưng không chứa thông tin về múi giờ nguồn), thì datetime sẽ là datetime ngây thơ. Nếu tìm thấy chênh lệch múi giờ cụ thể (bao gồm +0000), thì datetime sẽ chứa datetime nhận biết sử dụng datetime.timezone để ghi lại chênh lệch múi giờ.

Giá trị decoded của tiêu đề được xác định bằng cách định dạng datetime theo quy tắc RFC 5322; nghĩa là, nó được đặt thành:

email.utils.format_datetime(self.datetime)

Khi tạo một DateHeader, value có thể là phiên bản datetime. Ví dụ: điều này có nghĩa là đoạn mã sau hợp lệ và thực hiện những gì người ta mong đợi

msg['Date'] = datetime(2011, 7, 15, 21)

Bởi vì đây là một datetime ngây thơ nên nó sẽ được hiểu là dấu thời gian UTC và giá trị kết quả sẽ có múi giờ là -0000. Hữu ích hơn nhiều là sử dụng chức năng localtime() từ mô-đun utils

msg['Date'] = utils.localtime()

Ví dụ này đặt tiêu đề ngày thành ngày và giờ hiện tại bằng cách sử dụng phần bù múi giờ hiện tại.

class email.headerregistry.AddressHeader

Tiêu đề địa chỉ là một trong những loại tiêu đề có cấu trúc phức tạp nhất. Lớp AddressHeader cung cấp giao diện chung cho bất kỳ tiêu đề địa chỉ nào.

Loại tiêu đề này cung cấp các thuộc tính bổ sung sau:

groups

Một bộ đối tượng Group mã hóa các địa chỉ và nhóm được tìm thấy trong giá trị tiêu đề. Các địa chỉ không thuộc nhóm được thể hiện trong danh sách này dưới dạng một địa chỉ Groupsdisplay_nameNone.

addresses

Một bộ đối tượng Address mã hóa tất cả các địa chỉ riêng lẻ từ giá trị tiêu đề. Nếu giá trị tiêu đề chứa bất kỳ nhóm nào, thì các địa chỉ riêng lẻ trong nhóm sẽ được đưa vào danh sách tại điểm mà nhóm xuất hiện trong giá trị (nghĩa là danh sách địa chỉ được "làm phẳng" thành danh sách một chiều).

Giá trị decoded của tiêu đề sẽ có tất cả các từ được mã hóa được giải mã thành unicode. Tên miền được mã hóa idna cũng được giải mã thành unicode. Giá trị decoded được đặt bởi joining giá trị str của các phần tử thuộc thuộc tính groups', '.

Danh sách các đối tượng AddressGroup trong bất kỳ sự kết hợp nào có thể được sử dụng để đặt giá trị của tiêu đề địa chỉ. Các đối tượng Groupdisplay_nameNone sẽ được hiểu là các địa chỉ đơn lẻ, cho phép sao chép danh sách địa chỉ với các nhóm nguyên vẹn bằng cách sử dụng danh sách thu được từ thuộc tính groups của tiêu đề nguồn.

class email.headerregistry.SingleAddressHeader

Một lớp con của AddressHeader có thêm một thuộc tính bổ sung:

address

Địa chỉ duy nhất được mã hóa bởi giá trị tiêu đề. Nếu giá trị tiêu đề thực sự chứa nhiều hơn một địa chỉ (điều này sẽ vi phạm RFC theo policy mặc định), việc truy cập thuộc tính này sẽ dẫn đến ValueError.

Nhiều lớp trên cũng có biến thể Unique (ví dụ: UniqueUnstructuredHeader). Điểm khác biệt duy nhất là ở biến thể Unique, max_count được đặt thành 1.

class email.headerregistry.MIMEVersionHeader

Thực sự chỉ có một giá trị hợp lệ cho tiêu đề MIME-Version và đó là 1.0. Để kiểm chứng trong tương lai, lớp tiêu đề này hỗ trợ các số phiên bản hợp lệ khác. Nếu số phiên bản có giá trị hợp lệ cho mỗi RFC 2045 thì đối tượng tiêu đề sẽ có các giá trị không phải None cho các thuộc tính sau:

version

Số phiên bản ở dạng chuỗi, đã xóa mọi khoảng trắng và/hoặc nhận xét.

major

Số phiên bản chính dưới dạng số nguyên

minor

Số phiên bản phụ dưới dạng số nguyên

class email.headerregistry.ParameterizedMIMEHeader

Tất cả các tiêu đề MIME đều bắt đầu bằng tiền tố 'Content-'. Mỗi tiêu đề cụ thể có một giá trị nhất định, được mô tả trong lớp dành cho tiêu đề đó. Một số cũng có thể lấy danh sách các tham số bổ sung có định dạng chung. Lớp này đóng vai trò là cơ sở cho tất cả các tiêu đề MIME lấy tham số.

params

Một từ điển ánh xạ tên tham số tới các giá trị tham số.

class email.headerregistry.ContentTypeHeader

Lớp ParameterizedMIMEHeader xử lý tiêu đề Content-Type.

content_type

Chuỗi loại nội dung, có dạng maintype/subtype.

maintype
subtype
class email.headerregistry.ContentDispositionHeader

Lớp ParameterizedMIMEHeader xử lý tiêu đề Content-Disposition.

content_disposition

inlineattachment là những giá trị hợp lệ duy nhất được sử dụng phổ biến.

class email.headerregistry.ContentTransferEncodingHeader

Xử lý tiêu đề Content-Transfer-Encoding.

cte

Các giá trị hợp lệ là 7bit, 8bit, base64quoted-printable. Xem RFC 2045 để biết thêm thông tin.

class email.headerregistry.HeaderRegistry(base_class=BaseHeader, default_class=UnstructuredHeader, use_default_map=True)

Đây là nhà máy được EmailPolicy sử dụng theo mặc định. HeaderRegistry xây dựng lớp được sử dụng để tạo phiên bản tiêu đề một cách linh hoạt, sử dụng base_class và một lớp chuyên biệt được truy xuất từ ​​sổ đăng ký mà nó lưu giữ. Khi tên tiêu đề nhất định không xuất hiện trong sổ đăng ký, lớp do default_class chỉ định sẽ được sử dụng làm lớp chuyên biệt. Khi use_default_mapTrue (mặc định), ánh xạ tiêu chuẩn của tên tiêu đề tới các lớp sẽ được sao chép vào sổ đăng ký trong quá trình khởi tạo. base_class luôn là lớp cuối cùng trong danh sách __bases__ của lớp được tạo.

Các ánh xạ mặc định là:

chủ đề:

Tiêu đề không có cấu trúc duy nhất

ngày:

Tiêu đề ngày duy nhất

ngày gửi lại:

Tiêu đề ngày

ngày xuất xứ:

Tiêu đề ngày duy nhất

người gửi:

Tiêu đề địa chỉ duy nhất

người gửi gửi lại:

Tiêu đề địa chỉ đơn

để:

Tiêu đề địa chỉ duy nhất

bực bội với:

Tiêu đề địa chỉ

cc:

Tiêu đề địa chỉ duy nhất

bực bội-cc:

Tiêu đề địa chỉ

bcc:

Tiêu đề địa chỉ duy nhất

bực bội-bcc:

Tiêu đề địa chỉ

từ:

Tiêu đề địa chỉ duy nhất

bực bội từ:

Tiêu đề địa chỉ

trả lời:

Tiêu đề địa chỉ duy nhất

phiên bản mime:

Tiêu đề phiên bản MIME

loại nội dung:

Tiêu đề loại nội dung

bố trí nội dung:

Nội dungBố tríTiêu đề

mã hóa chuyển nội dung:

Tiêu đề mã hóa chuyển giao nội dung

id tin nhắn:

Tiêu đề tin nhắnID

HeaderRegistry có các phương pháp sau:

map_to_type(self, name, cls)

name là tên của tiêu đề được ánh xạ. Nó sẽ được chuyển đổi thành chữ thường trong sổ đăng ký. cls là lớp chuyên dụng được sử dụng cùng với base_class để tạo lớp dùng để khởi tạo các tiêu đề khớp với name.

__getitem__(name)

Xây dựng và trả về một lớp để xử lý việc tạo tiêu đề name.

__call__(name, value)

Truy xuất tiêu đề chuyên dụng được liên kết với name từ sổ đăng ký (sử dụng default_class nếu name không xuất hiện trong sổ đăng ký) và kết hợp nó với base_class để tạo một lớp, gọi hàm tạo của lớp được xây dựng, chuyển cho nó cùng một danh sách đối số và cuối cùng trả về thể hiện của lớp được tạo từ đó.

Các lớp sau đây là các lớp được sử dụng để biểu diễn dữ liệu được phân tích cú pháp từ các tiêu đề có cấu trúc và nói chung có thể được chương trình ứng dụng sử dụng để xây dựng các giá trị có cấu trúc nhằm gán cho các tiêu đề cụ thể.

class email.headerregistry.Address(display_name='', username='', domain='', addr_spec=None)

Lớp được sử dụng để đại diện cho một địa chỉ email. Dạng chung của một địa chỉ là:

[display_name] <tên người dùng@domain>

hoặc:

tên người dùng @ tên miền

trong đó mỗi phần phải tuân theo các quy tắc cú pháp cụ thể được nêu trong RFC 5322.

Để thuận tiện, addr_spec có thể được chỉ định thay vì usernamedomain, trong trường hợp đó usernamedomain sẽ được phân tích cú pháp từ addr_spec. Một addr_spec phải là một chuỗi trích dẫn RFC chính xác; nếu không phải là Address sẽ báo lỗi. Các ký tự Unicode được cho phép và sẽ được mã hóa thuộc tính khi được tuần tự hóa. Tuy nhiên, theo RFC, unicode được phép not trong phần tên người dùng của địa chỉ.

display_name

Phần tên hiển thị của địa chỉ, nếu có, đã loại bỏ tất cả trích dẫn. Nếu địa chỉ không có tên hiển thị thì thuộc tính này sẽ là một chuỗi trống.

username

Phần username của địa chỉ, với tất cả trích dẫn đã bị xóa.

domain

Phần domain của địa chỉ.

addr_spec

Phần username@domain của địa chỉ, được trích dẫn chính xác để sử dụng làm địa chỉ trần (dạng thứ hai được hiển thị ở trên). Thuộc tính này không thể thay đổi được.

__str__()

Giá trị str của đối tượng là địa chỉ được trích dẫn theo quy tắc RFC 5322, nhưng không có Mã hóa chuyển nội dung của bất kỳ ký tự không phải ASCII nào.

Để hỗ trợ SMTP (RFC 5321), Address xử lý một trường hợp đặc biệt: nếu usernamedomain đều là chuỗi trống (hoặc None), thì giá trị chuỗi của Address<>.

class email.headerregistry.Group(display_name=None, addresses=None)

Lớp được sử dụng để đại diện cho một nhóm địa chỉ. Dạng chung của một nhóm địa chỉ là:

display_name: [danh sách địa chỉ];

Để thuận tiện cho việc xử lý danh sách địa chỉ bao gồm hỗn hợp các nhóm và địa chỉ đơn lẻ, Group cũng có thể được sử dụng để thể hiện các địa chỉ đơn lẻ không thuộc nhóm bằng cách đặt display_name thành None và cung cấp danh sách địa chỉ duy nhất là addresses.

display_name

Zz000zz của nhóm. Nếu đó là None và có chính xác một Address trong addresses thì Group đại diện cho một địa chỉ duy nhất không nằm trong một nhóm.

addresses

Một bộ đối tượng Address có thể trống đại diện cho các địa chỉ trong nhóm.

__str__()

Giá trị str của Group được định dạng theo RFC 5322 nhưng không có Mã hóa chuyển nội dung của bất kỳ ký tự không phải ASCII nào. Nếu display_name không có và có một Address duy nhất trong danh sách addresses, thì giá trị str sẽ giống với str của Address duy nhất đó.

Chú thích cuối trang