mailbox — 다양한 형식의 메일함 다루기
mailbox — 다양한 형식의 메일함 다루기
이 모듈은 디스크에 있는 메일함(mailbox)과 그 안의 메시지에 접근·조작하는 두 클래스 Mailbox와 Message를 정의해요. Mailbox는 키에서 메시지로의 딕셔너리류 매핑을 제공하고, Message는 email.message 모듈의 Message 클래스를 형식별 상태와 동작으로 확장해요. 지원되는 메일함 형식은 Maildir, mbox, MH, Babyl, MMDF예요.
출처: Python 표준 라이브러리
본문
Mailbox 객체
class mailbox.Mailbox — 검사하고 수정할 수 있는 메일함.
Mailbox 클래스는 인터페이스를 정의하며 직접 인스턴스화하지 않아요. 대신 형식별 하위 클래스가 Mailbox를 상속하고, 여러분 코드는 특정 하위 클래스를 인스턴스화해야 해요.
Mailbox 인터페이스는 딕셔너리와 같으며, 작은 키가 메시지에 대응해요. 키는 함께 쓰일 Mailbox 인스턴스가 발급하며 그 Mailbox 인스턴스에만 의미가 있어요. 키는 해당 메시지가 다른 메시지로 교체되는 등 수정돼도 계속 그 메시지를 식별해요.
메시지는 add()(집합류 메서드)로 Mailbox 인스턴스에 추가되고, del 문이나 remove(), discard()(집합류 메서드)로 제거돼요.
Mailbox 인터페이스 의미론은 딕셔너리와 몇 가지 주목할 만한 차이가 있어요. 메시지를 요청할 때마다 메일함의 현재 상태를 바탕으로 새 표현(보통 Message 인스턴스)이 만들어져요. 마찬가지로 메시지를 추가하면 제공된 표현의 내용이 복사돼요. 어느 경우에도 Mailbox 인스턴스는 메시지 표현에 대한 참조를 유지하지 않아요.
기본 Mailbox 이터레이터는 메시지 표현을 순회해요(기본 딕셔너리 이터레이터가 키를 순회하는 것과 달라요). 이터레이션 중 메일함 수정은 안전하고 잘 정의돼 있어요. 이터레이터가 만들어진 후 추가된 메시지는 그 이터레이터가 보지 못해요. 이터레이터가 내놓기 전에 제거된 메시지는 조용히 건너뛰지만, 이터레이터의 키를 사용하다 해당 메시지가 나중에 제거되면 KeyError가 발생할 수 있어요.
경고: 다른 프로세스가 동시에 변경할 수 있는 메일함을 수정할 때는 매우 조심하세요. 그런 작업에 가장 안전한 형식은 Maildir이에요. mbox 같은 단일 파일 형식으로 동시 쓰기는 피하세요. 메일함을 수정한다면, 파일의 메시지를 읽거나 메시지를 추가·삭제하기 전에
lock()과unlock()메서드로 반드시 잠가야 해요. 잠그지 않으면 메시지 유실이나 메일함 전체 손상 위험이 있어요.
Mailbox 인스턴스는 다음 메서드를 가져요.
add(message)— 메시지를 메일함에 추가하고 할당된 키를 반환해요. 매개변수message는 Message 인스턴스,email.message.Message인스턴스, 문자열, 바이트 문자열, 또는 파일류 객체(이진 모드로 열어야 함)일 수 있어요.message가 적절한 형식별 Message 하위 클래스의 인스턴스(예: mboxMessage 인스턴스인데 이것이 mbox 인스턴스인 경우)라면 그 형식별 정보가 사용돼요. 아니면 형식별 정보의 합리적 기본값이 사용돼요.버전 3.2에서 변경: 이진 입력 지원이 추가됨.
remove(key),__delitem__(key),discard(key)— 메일함에서key에 해당하는 메시지를 삭제해요. 그런 메시지가 없으면remove()나__delitem__()으로 호출했을 때는KeyError를 일으키고,discard()로 호출했을 때는 예외를 일으키지 않아요.discard()의 동작이 기본 메일함 형식이 다른 프로세스의 동시 수정을 지원할 때 선호될 수 있어요.__setitem__(key, message)—key에 해당하는 메시지를message로 교체해요. 이미key에 대응하는 메시지가 없으면KeyError를 일으켜요.add()와 마찬가지로message는 Message 인스턴스,email.message.Message인스턴스, 문자열, 바이트 문자열, 또는 파일류 객체일 수 있어요. 적절한 형식별 하위 클래스의 인스턴스면 그 형식별 정보가 사용되고, 아니면 현재key에 대응하는 메시지의 형식별 정보가 그대로 남아요.iterkeys()— 모든 키에 대한 이터레이터 반환.keys()—iterkeys()와 같지만 이터레이터가 아닌 리스트를 반환.itervalues(),__iter__()— 모든 메시지 표현에 대한 이터레이터 반환. 메시지는 Mailbox 인스턴스 초기화 시 커스텀 메시지 팩토리를 지정하지 않았다면 적절한 형식별 Message 하위 클래스의 인스턴스로 표현돼요.참고:
__iter__()의 동작은 키를 순회하는 딕셔너리와 달라요.values()—itervalues()와 같지만 리스트 반환.iteritems()—(key, message)쌍에 대한 이터레이터 반환. 여기서key는 키,message는 메시지 표현이에요.items()—iteritems()와 같지만 리스트 반환.get(key, default=None),__getitem__(key)—key에 해당하는 메시지의 표현 반환. 그런 메시지가 없으면get()으로 호출했을 때는default를 반환하고,__getitem__()으로 호출했을 때는KeyError를 일으켜요.get_message(key)—key에 해당하는 메시지의 표현을 적절한 형식별 Message 하위 클래스 인스턴스로 반환하거나, 그런 메시지가 없으면KeyError를 일으켜요.get_bytes(key)—key에 해당하는 메시지의 바이트 표현 반환, 없으면KeyError. (버전 3.2 추가.)get_string(key)—key에 해당하는 메시지의 문자열 표현 반환, 없으면KeyError. 메시지는email.message.Message로 처리되어 7bit 깨끗한 표현으로 변환돼요.get_file(key)—key에 해당하는 메시지의 파일류 표현 반환, 없으면KeyError. 파일류 객체는 이진 모드로 열린 것처럼 동작해요. 더 이상 필요 없으면 닫아야 해요.버전 3.2에서 변경: 파일 객체가 진짜 이진 파일이 됨(이전에는 텍스트 모드로 잘못 반환됨). 또한 파일류 객체가 컨텍스트 관리자 프로토콜을 지원해
with문으로 자동 닫을 수 있게 됨. 참고: 다른 메시지 표현과 달리 파일류 표현은 그것을 만든 Mailbox 인스턴스나 기본 메일함과 반드시 독립적인 건 아니에요. 각 하위 클래스가 더 구체적인 문서를 제공해요.__contains__(key)—key가 메시지에 대응하면True, 아니면False반환.__len__()— 메일함의 메시지 수 반환.clear()— 메일함의 모든 메시지를 삭제해요.pop(key, default=None)—key에 해당하는 메시지의 표현을 반환하고 메시지를 삭제해요. 그런 메시지가 없으면default반환.popitem()— 임의의(key, message)쌍을 반환하고 해당 메시지를 삭제해요. 메일함이 비어 있으면KeyError.update(arg)—arg는 키-메시지 매핑 또는(key, message)쌍의 iterable이어야 해요. 각 키·메시지에 대해__setitem__()을 쓴 것처럼 메시지를 설정해요.__setitem__()과 마찬가지로 각 키는 이미 메일함의 메시지에 대응해야 하며 아니면KeyError를 일으켜요. 따라서 일반적으로arg가 Mailbox 인스턴스인 것은 옳지 않아요.참고: 딕셔너리와 달리 키워드 인자는 지원되지 않아요.
flush()— 대기 중인 변경을 파일시스템에 써요. 일부 Mailbox 하위 클래스는 변경이 항상 즉시 적용되어flush()가 아무것도 하지 않지만, 그래도 이 메서드를 호출하는 습관을 들여야 해요.lock()— 메일함에 독점적 조언적(advisory) 잠금을 획득해 다른 프로세스가 수정하지 않도록 해요. 잠금을 얻지 못하면ExternalClashError를 일으켜요. 쓰이는 잠금 메커니즘은 메일함 형식에 따라 달라요. 내용을 수정하기 전에 항상 메일함을 잠가야 해요.unlock()— 메일함의 잠금이 있으면 해제해요.close()— 메일함을 플러시하고, 필요하면 잠금을 해제하며 열린 파일을 닫아요. 일부 하위 클래스는 아무것도 하지 않아요.
Maildir 객체
class mailbox.Maildir(dirname, factory=None, create=True) — Maildir 형식 메일함을 위한 Mailbox의 하위 클래스. 매개변수 factory는 파일류 메시지 표현(이진 모드로 열린 것처럼 동작)을 받아 커스텀 표현을 반환하는 callable 객체예요. factory가 None이면 MaildirMessage가 기본 메시지 표현으로 쓰여요. create가 True면 메일함이 없을 때 만들어요. create가 True이고 dirname 경로가 존재하면, 디렉터리 구조를 검증하지 않고 기존 maildir로 취급해요. 역사적 이유로 dirname이 path가 아니라 그렇게 명명됐어요.
Maildir은 qmail 메일 전송 에이전트를 위해 발명된 디렉터리 기반 메일함 형식으로, 지금은 다른 많은 프로그램이 지원해요. Maildir 메일함의 메시지는 공통 디렉터리 구조 안의 별도 파일에 저장돼요. 이 설계 덕분에 여러 무관한 프로그램이 데이터 손상 없이 Maildir 메일함에 접근·수정할 수 있어 파일 잠금이 필요 없어요.
Maildir 메일함은 tmp, new, cur 세 개의 하위 디렉터리를 담아요. 메시지는 잠시 tmp에 만들어졌다가 new로 옮겨져 전달을 완료해요. 메일 사용자 에이전트는 나중에 메시지를 cur로 옮기고 파일 이름에 덧붙는 특별한 "info" 섹션에 메시지 상태 정보를 저장할 수 있어요.
Courier 메일 전송 에이전트가 도입한 스타일의 폴더도 지원돼요. 이름의 첫 문자가 '.'이면 기본 메일함의 어떤 하위 디렉터리든 폴더로 간주돼요. 폴더 이름은 Maildir에서 앞의 '.' 없이 표현돼요. 각 폴더는 그 자체로 Maildir 메일함이지만 다른 폴더를 포함하면 안 돼요. 대신 '.'로 레벨을 구분해 논리적 중첩을 나타내요. 예: "Archived.2005.07".
-
colon— Maildir 사양은 특정 메시지 파일 이름에서 콜론(':')을 요구해요. 하지만 일부 운영체제는 파일 이름에 이 문자를 허용하지 않아요. 그런 운영체제에서 Maildir류 형식을 쓰려면 대신 쓸 다른 문자를 지정해야 해요. 느낌표('!')가 인기 있는 선택이에요. 예:import mailbox mailbox.Maildir.colon = '!'colon속성은 인스턴스별로도 설정할 수 있어요.버전 3.13에서 변경: Maildir은 이제 점으로 시작하는 파일을 무시해요.
Maildir 인스턴스는 Mailbox의 모든 메서드 외에 다음을 가져요.
-
list_folders()— 모든 폴더 이름의 리스트 반환. -
get_folder(folder)— 이름이folder인 폴더를 나타내는 Maildir 인스턴스 반환. 없으면NoSuchMailboxError. -
add_folder(folder)— 이름이folder인 폴더를 만들고 그것을 나타내는 Maildir 인스턴스 반환. -
remove_folder(folder)— 이름이folder인 폴더 삭제. 메시지를 담고 있으면NotEmptyError를 일으키고 삭제하지 않아요. -
clean()— 지난 36시간 동안 접근되지 않은 임시 파일을 메일함에서 삭제해요. Maildir 사양은 메일 읽기 프로그램이 가끔 이 작업을 하라고 권해요. -
get_flags(key)—key에 해당하는 메시지에 설정된 플래그를 문자열로 반환해요. 이는get_message(key).get_flags()와 같지만 메시지 파일을 열지 않아 훨씬 빨라요. 키를 순회하며 어떤 메시지가 가치 있는지 판단할 때 쓰세요. MaildirMessage 객체가 있다면 그get_flags()메서드를 쓰는 게 좋아요. 메시지의set_flags(),add_flag(),remove_flag()메서드로 만든 변경은 메일함의__setitem__()메서드가 호출될 때까지 여기에 반영되지 않기 때문이에요. (버전 3.13 추가.) -
set_flags(key, flags)—key에 해당하는 메시지에flags가 지정한 플래그를 설정하고 나머지는 모두 해제해요.some_mailbox.set_flags(key, flags)는 다음과 비슷하지만 빠르고, 메시지 파일을 열지 않아요.one_message = some_mailbox.get_message(key) one_message.set_flags(flags) some_mailbox[key] = one_message(버전 3.13 추가.)
-
add_flag(key, flag)—key에 해당하는 메시지에flag가 지정한 플래그를 다른 플래그는 바꾸지 않고 설정해요. 한 번에 여러 플래그를 추가하려면flag를 여러 문자로 된 문자열로 줄 수 있어요. (버전 3.13 추가.) -
remove_flag(key, flag)—key에 해당하는 메시지에서flag가 지정한 플래그를 다른 플래그는 바꾸지 않고 해제해요. (버전 3.13 추가.) -
get_info(key)—key에 해당하는 메시지의 info를 담은 문자열 반환.get_message(key).get_info()와 같지만 메시지 파일을 열지 않아 훨씬 빨라요. (버전 3.13 추가.) -
set_info(key, info)—key에 해당하는 메시지의 info를info로 설정해요. 다음과 비슷하지만 빠르고, 메시지 파일을 열지 않아요.one_message = some_mailbox.get_message(key) one_message.set_info(info) some_mailbox[key] = one_message(버전 3.13 추가.)
Maildir이 구현하는 일부 Mailbox 메서드는 특별한 언급이 필요해요.
add(message),__setitem__(key, message),update(arg)—경고: 이 메서드들은 현재 프로세스 ID를 바탕으로 고유한 파일 이름을 생성해요. 여러 스레드를 사용할 때, 스레드들이 이 메서드로 같은 메일함을 동시에 조작하지 않도록 조정하지 않으면 감지되지 않는 이름 충돌이 발생해 메일함이 손상될 수 있어요.
flush()— Maildir 메일함의 모든 변경은 즉시 적용되므로 이 메서드는 아무것도 하지 않아요.lock(),unlock()— Maildir 메일함은 잠금을 지원하지 않거나(요구하지 않아) 이 메서드들은 아무것도 하지 않아요.close()— Maildir 인스턴스는 열린 파일을 유지하지 않고 기본 메일함도 잠금을 지원하지 않으므로 아무것도 하지 않아요.get_file(key)— 호스트 플랫폼에 따라, 반환된 파일이 열려 있는 동안 기본 메시지를 수정하거나 제거하지 못할 수 있어요.
mbox 객체
class mailbox.mbox(path, factory=None, create=True) — mbox 형식 메일함을 위한 Mailbox의 하위 클래스. factory는 파일류 표현을 받아 커스텀 표현을 반환하는 callable이에요. None이면 mboxMessage가 기본 표현. create가 True면 없을 때 만들고, True이고 path가 존재하면 기존 mbox로 취급해요.
mbox 형식은 Unix 시스템에서 메일을 저장하는 고전적 형식이에요. mbox 메일함의 모든 메시지는 단일 파일에 저장되며, 각 메시지의 시작은 처음 5문자가 "From "인 줄로 표시돼요. 원본의 인지된 단점을 해결하려는 여러 mbox 변형이 존재해요. 호환성을 위해 mbox는 mboxo라고도 불리는 원본 형식을 구현해요. 즉 Content-Length 헤더는 있으면 무시되고, 메시지 본문 줄의 시작에 나타나는 "From "은 저장할 때 ">From "으로 변환되지만, 읽을 때 ">From "은 "From "으로 변환되지 않아요.
mbox가 구현하는 일부 Mailbox 메서드는 특별한 언급이 필요해요.
get_bytes(key, from_=False)— 참고: 이 메서드는 다른 클래스와 비교해 추가 매개변수(from_)가 있어요. mbox 파일 항목의 첫 줄은 Unix"From "줄이에요.from_이False면 첫 줄이 버려져요.get_file(key, from_=False)— mbox 인스턴스에서flush()나close()를 호출한 후 이 파일을 사용하면 예측할 수 없는 결과가 나오거나 예외가 발생할 수 있어요. (추가 매개변수from_있음. 첫 줄은 Unix"From "줄이고from_이False면 버려져요.)get_string(key, from_=False)— (추가 매개변수from_있음. 첫 줄 버려짐.)lock(),unlock()— 세 가지 잠금 메커니즘이 사용돼요: dot locking과, 가능하면flock()및lockf()시스템 호출.
MH 객체
class mailbox.MH(path, factory=None, create=True) — MH 형식 메일함을 위한 Mailbox의 하위 클래스. factory가 None이면 MHMessage가 기본 표현. create가 True면 없을 때 만듦.
MH는 메일 사용자 에이전트인 MH Message Handling System을 위해 발명된 디렉터리 기반 메일함 형식이에요. MH 메일함의 각 메시지는 자신만의 파일에 있어요. MH 메일함은 메시지 외에 다른 MH 메일함(폴더라고 함)을 담을 수 있고, 폴더는 무한히 중첩될 수 있어요. MH 메일함은 시퀀스(sequence)도 지원하는데, 이것은 메시지를 하위 폴더로 옮기지 않고 논리적으로 그룹화하는 이름 있는 목록이에요. 시퀀스는 각 폴더의 .mh_sequences라는 파일에 정의돼요.
MH 클래스는 MH 메일함을 조작하지만 mh의 모든 동작을 에뮬레이트하려 하진 않아요. 특히 mh가 상태와 설정을 저장하는 데 쓰는 context나 .mh_profile 파일을 수정하지도, 영향을 받지도 않아요.
버전 3.13에서 변경:
.mh_sequences파일이 없는 폴더를 지원함.
MH 인스턴스는 Mailbox의 모든 메서드 외에 다음을 가져요.
-
list_folders()— 모든 폴더 이름의 리스트 반환. -
get_folder(folder)— 이름이folder인 폴더를 나타내는 MH 인스턴스 반환, 없으면NoSuchMailboxError. -
add_folder(folder)— 폴더를 만들고 MH 인스턴스 반환. -
remove_folder(folder)— 폴더 삭제. 메시지를 담고 있으면NotEmptyError. -
get_sequences()— 시퀀스 이름을 키 목록으로 매핑한 딕셔너리 반환. 시퀀스가 없으면 빈 딕셔너리. -
set_sequences(sequences)—get_sequences()가 반환하는 것 같은, 이름→키 목록 딕셔너리인sequences를 바탕으로 메일함에 존재하는 시퀀스를 재정의해요. -
pack()— 번호 매김의 공백을 없애기 위해 필요한 대로 메일함의 메시지 이름을 바꿔요. 시퀀스 목록의 항목도 그에 맞게 갱신돼요.참고: 이미 발급된 키는 이 작업으로 무효화되므로 이후에 사용하면 안 돼요.
MH가 구현하는 일부 Mailbox 메서드의 특별한 언급:
remove(key),__delitem__(key),discard(key)— 이 메서드들은 메시지를 즉시 삭제해요. 이름 앞에 쉼표를 붙여 삭제 표시를 하는 MH 관례는 사용하지 않아요.lock(),unlock()— 세 가지 잠금 메커니즘 사용(dot locking, 그리고 가능하면flock()과lockf()). MH 메일함에서 메일함을 잠그는 것은.mh_sequences파일을 잠그는 것을 뜻하며, 영향을 주는 연산이 진행되는 동안에만 개별 메시지 파일도 잠가요.get_file(key)— 플랫폼에 따라, 반환된 파일이 열려 있는 동안 기본 메시지를 제거하지 못할 수 있어요.flush()— 모든 변경이 즉시 적용돼 아무것도 하지 않아요.close()— MH 인스턴스는 열린 파일을 유지하지 않으므로unlock()과 동등해요.
Babyl 객체
class mailbox.Babyl(path, factory=None, create=True) — Babyl 형식 메일함을 위한 Mailbox의 하위 클래스. factory가 None이면 BabylMessage가 기본 표현.
Babyl은 Emacs에 포함된 Rmail 메일 사용자 에이전트가 사용하는 단일 파일 메일함 형식이에요. 메시지의 시작은 Control-Underscore('\037')와 Control-L('\014') 두 문자를 담은 줄로 표시돼요. 메시지의 끝은 다음 메시지의 시작 또는, 마지막 메시지의 경우 Control-Underscore('\037') 문자를 담은 줄로 표시돼요.
Babyl 메일함의 메시지는 원본 헤더와 소위 보이는 헤더(visible headers) 두 세트의 헤더를 가져요. 보이는 헤더는 보통 원본 헤더의 부분집합으로, 더 매력적으로 다시 포맷되거나 축약된 것이에요. 각 메시지에는 메시지에 대한 추가 정보를 기록하는 레이블(짧은 문자열) 목록도 있고, 메일함에서 찾은 모든 사용자 정의 레이블의 목록은 Babyl options 섹션에 보관돼요.
Babyl 인스턴스는 Mailbox의 모든 메서드 외에 다음을 가져요.
get_labels()— 메일함에서 쓰인 모든 사용자 정의 레이블 이름의 리스트 반환.참고: 어떤 레이블이 존재하는지 판단할 때 Babyl options 섹션의 레이블 목록을 보지 않고 실제 메시지를 조사해요. 하지만 메일함이 수정될 때마다 Babyl 섹션은 갱신돼요.
Babyl이 구현하는 일부 Mailbox 메서드의 특별한 언급:
get_file(key)— Babyl 메일함에서는 메시지의 헤더가 본문과 연속적으로 저장되지 않아요. 파일류 표현을 만들려면 헤더와 본문을 파일과 동일한 API를 가진io.BytesIO인스턴스로 함께 복사해요. 결과적으로 파일류 객체는 기본 메일함과 진정으로 독립적이지만, 문자열 표현과 비교해 메모리를 아끼지는 않아요.lock(),unlock()— 세 가지 잠금 메커니즘 사용.
MMDF 객체
class mailbox.MMDF(path, factory=None, create=True) — MMDF 형식 메일함을 위한 Mailbox의 하위 클래스. factory가 None이면 MMDFMessage가 기본 표현.
MMDF는 메일 전송 에이전트인 Multichannel Memorandum Distribution Facility를 위해 발명된 단일 파일 메일함 형식이에요. 각 메시지는 mbox 메시지와 같은 형태지만, 앞뒤로 네 개의 Control-A('\001') 문자를 담은 줄로 둘러싸여 있어요. mbox 형식처럼 각 메시지의 시작은 처음 5문자가 "From "인 줄로 표시되지만, 저장할 때 추가적인 "From "은 ">From "으로 변환되지 않아요. 추가 메시지 구분 줄이 그런 발생을 다음 메시지의 시작으로 오인하지 않게 막아주기 때문이에요.
MMDF가 구현하는 일부 Mailbox 메서드의 특별한 언급:
get_bytes(key, from_=False),get_file(key, from_=False)— (다른 클래스와 비교해 추가 매개변수from_있음. 첫 줄은 Unix"From "줄이고from_이False면 버려져요.)get_file은 MMDF 인스턴스에서flush()나close()후 사용 시 예측 불가한 결과/예외가 날 수 있어요.lock(),unlock()— 세 가지 잠금 메커니즘 사용.
Message 객체
class mailbox.Message(message=None) — email.message 모듈의 Message의 하위 클래스. mailbox.Message의 하위 클래스는 메일함 형식별 상태와 동작을 추가해요. message가 생략되면 새 인스턴스가 기본의 빈 상태로 만들어져요. message가 email.message.Message 인스턴스면 내용이 복사되고, Message 인스턴스면 형식별 정보가 가능한 한 변환돼요. message가 문자열·바이트 문자열·파일이면 RFC 5322 준수 메시지를 담고 있어야 하며, 읽고 파싱돼요. 파일은 이진 모드로 열어야 하지만, 하위 호환을 위해 텍스트 모드 파일도 허용돼요.
하위 클래스가 제공하는 형식별 상태와 동작은 다양하지만, 일반적으로 특정 메일함에만 국한되지 않은 속성만 지원돼요(아마 그 속성들은 특정 메일함 형식에 국한되지만요). 예를 들어 단일 파일 메일함 형식의 파일 오프셋이나 디렉터리 기반 형식의 파일 이름은 원본 메일함에만 적용되므로 유지되지 않아요. 하지만 사용자가 메시지를 읽었는지, 중요 표시가 됐는지 같은 상태는 메시지 자체에 적용되므로 유지돼요.
Message 인스턴스를 Mailbox 인스턴스로 가져온 메시지를 나타내는 데 써야 한다는 요구는 없어요. 어떤 상황에서는 Message 표현을 생성하는 시간과 메모리가 허용되지 않을 수 있어요. 그런 상황을 위해 Mailbox 인스턴스는 문자열과 파일류 표현도 제공하고, 초기화 시 커스텀 메시지 팩토리를 지정할 수도 있어요.
MaildirMessage 객체
class mailbox.MaildirMessage(message=None) — Maildir 특정 동작을 가진 메시지. 매개변수 message는 Message 생성자와 같은 의미.
보통 메일 사용자 에이전트는 사용자가 메일함을 처음 열고 닫은 후 new 하위 디렉터리의 모든 메시지를 cur로 옮기며, 실제로 읽었는지와 무관하게 그 메시지들을 오래된 것으로 기록해요. cur의 각 메시지는 상태 정보를 저장하기 위해 파일 이름에 "info" 섹션이 추가돼 있어요. ("info" 섹션은 new의 메시지에도 추가하는 일부 메일 리더도 있어요.) "info" 섹션은 두 형태 중 하나를 취해요: "2," 다음에 표준화된 플래그 목록(예: "2,FR")이 오거나, "1," 다음에 소위 실험적 정보가 와요. Maildir 메시지의 표준 플래그는 다음과 같아요.
| 플래그 | 의미 | 설명 |
|---|---|---|
D |
Draft | 작성 중 |
F |
Flagged | 중요 표시됨 |
P |
Passed | 전달·재전송·반송됨 |
R |
Replied | 답장함 |
S |
Seen | 읽음 |
T |
Trashed | 나중에 삭제하도록 표시됨 |
MaildirMessage 인스턴스는 다음 메서드를 제공해요.
get_subdir()—"new"(메시지를new하위 디렉터리에 저장해야 하면) 또는"cur"(cur에 저장해야 하면) 반환.참고: 메시지는 보통 읽혔는지와 무관하게 메일함에 접근한 후
new에서cur로 옮겨져요."S" in msg.get_flags()가True면 메시지msg를 읽은 거예요.set_subdir(subdir)— 메시지를 저장할 하위 디렉터리를 설정해요.subdir은"new"또는"cur"여야 해요.get_flags()— 현재 설정된 플래그를 지정하는 문자열 반환. 메시지가 표준 Maildir 형식을 준수하면 결과는'D','F','P','R','S','T'각각이 0~1회 알파벳 순으로 이어진 것이다. 플래그가 없거나 "info"가 실험적 의미를 담고 있으면 빈 문자열 반환.set_flags(flags)—flags가 지정한 플래그를 설정하고 나머지는 모두 해제.add_flag(flag)— 다른 플래그는 바꾸지 않고flag가 지정한 플래그를 설정. 한 번에 여러 개를 추가하려면flag를 여러 문자 문자열로. 현재 "info"는 플래그가 아닌 실험적 정보를 담고 있든 말든 덮어써져요.remove_flag(flag)— 다른 플래그는 바꾸지 않고flag가 지정한 플래그를 해제. "info"가 플래그가 아닌 실험적 정보를 담고 있으면 현재 "info"는 수정되지 않아요.get_date()— 메시지의 전달 날짜를 epoch 이후 초를 나타내는 부동소수점 숫자로 반환.set_date(date)— 메시지의 전달 날짜를date(epoch 이후 초인 부동소수점)로 설정.get_info()— 메시지의 "info"를 담은 문자열 반환. 실험적(즉 플래그 목록이 아닌) "info"에 접근·수정할 때 유용해요.set_info(info)— "info"를info(문자열이어야 함)로 설정.
MaildirMessage 인스턴스가 mboxMessage 또는 MMDFMessage 인스턴스를 바탕으로 만들어지면 Status와 X-Status 헤더는 생략되고 다음 변환이 일어나요.
| 결과 상태 | mboxMessage 또는 MMDFMessage 상태 |
|---|---|
"cur" 하위 디렉터리 |
O 플래그 |
F 플래그 |
F 플래그 |
R 플래그 |
A 플래그 |
S 플래그 |
R 플래그 |
T 플래그 |
D 플래그 |
MaildirMessage 인스턴스가 MHMessage 인스턴스를 바탕으로 만들어지면 다음 변환이 일어나요.
| 결과 상태 | MHMessage 상태 |
|---|---|
"cur" 하위 디렉터리 |
"unseen" 시퀀스 |
"cur" 하위 디렉터리와 S 플래그 |
"unseen" 시퀀스 없음 |
F 플래그 |
"flagged" 시퀀스 |
R 플래그 |
"replied" 시퀀스 |
MaildirMessage 인스턴스가 BabylMessage 인스턴스를 바탕으로 만들어지면 다음 변환이 일어나요.
| 결과 상태 | BabylMessage 상태 |
|---|---|
"cur" 하위 디렉터리 |
"unseen" 레이블 |
"cur" 하위 디렉터리와 S 플래그 |
"unseen" 레이블 없음 |
P 플래그 |
"forwarded" 또는 "resent" 레이블 |
R 플래그 |
"answered" 레이블 |
T 플래그 |
"deleted" 레이블 |
mboxMessage 객체
class mailbox.mboxMessage(message=None) — mbox 특정 동작을 가진 메시지. 매개변수 message는 Message 생성자와 같은 의미.
mbox 메일함의 메시지는 단일 파일에 함께 저장돼요. 보낸 이의 봉투(envelope) 주소와 전달 시간은 보통 메시지 시작을 표시하는 데 쓰이는 "From "으로 시작하는 줄에 저장되지만, mbox 구현들 사이에서 이 데이터의 정확한 형식은 크게 달라요. 읽었는지, 중요 표시를 했는지 같은 메시지 상태를 나타내는 플래그는 보통 Status와 X-Status 헤더에 저장돼요.
mbox 메시지의 관례적 플래그는 다음과 같아요.
| 플래그 | 의미 | 설명 |
|---|---|---|
R |
Read | 읽음 |
O |
Old | MUA가 이전에 감지함 |
D |
Deleted | 나중에 삭제하도록 표시됨 |
F |
Flagged | 중요 표시됨 |
A |
Answered | 답장함 |
"R"와 "O" 플래그는 Status 헤더에, "D", "F", "A" 플래그는 X-Status 헤더에 저장돼요. 플래그와 헤더는 보통 언급된 순서로 나타나요.
mboxMessage 인스턴스는 다음 메서드를 제공해요.
get_from()— mbox 메일함에서 메시지의 시작을 표시하는"From "줄을 나타내는 문자열 반환. 앞의"From "과 끝의 개행은 제외돼요.set_from(from_, time_=None)—"From "줄을from_으로 설정해요.from_은 앞의"From "이나 끝의 개행 없이 지정해야 해요. 편의상time_을 지정할 수 있는데, 적절히 포맷되어from_에 덧붙여져요.time_이 지정되면time.struct_time인스턴스,time.strftime()에 넘기기 적합한 튜플, 또는True(지금time.gmtime()을 쓰려고)여야 해요.get_flags()— 현재 설정된 플래그를 지정하는 문자열 반환. 관례적 형식을 준수하면'R','O','D','F','A'각각이 다음 순서로 0~1회 이어진 것이다.set_flags(flags)—flags가 지정한 플래그를 설정하고 나머지 해제.flags는'R','O','D','F','A'각각이 0~여러 번 임의 순서로 이어진 것이어야 해요.add_flag(flag)— 다른 플래그는 바꾸지 않고 설정.remove_flag(flag)— 다른 플래그는 바꾸지 않고 해제.
mboxMessage 인스턴스가 MaildirMessage 인스턴스를 바탕으로 만들어지면 MaildirMessage 인스턴스의 전달 날짜를 바탕으로 "From " 줄이 생성되고 다음 변환이 일어나요.
| 결과 상태 | MaildirMessage 상태 |
|---|---|
R 플래그 |
S 플래그 |
O 플래그 |
"cur" 하위 디렉터리 |
D 플래그 |
T 플래그 |
F 플래그 |
F 플래그 |
A 플래그 |
R 플래그 |
mboxMessage 인스턴스가 MHMessage 인스턴스를 바탕으로 만들어지면:
| 결과 상태 | MHMessage 상태 |
|---|---|
R 플래그와 O 플래그 |
"unseen" 시퀀스 없음 |
O 플래그 |
"unseen" 시퀀스 |
F 플래그 |
"flagged" 시퀀스 |
A 플래그 |
"replied" 시퀀스 |
mboxMessage 인스턴스가 BabylMessage 인스턴스를 바탕으로 만들어지면:
| 결과 상태 | BabylMessage 상태 |
|---|---|
R 플래그와 O 플래그 |
"unseen" 레이블 없음 |
O 플래그 |
"unseen" 레이블 |
D 플래그 |
"deleted" 레이블 |
A 플래그 |
"answered" 레이블 |
mboxMessage 인스턴스가 MMDFMessage 인스턴스를 바탕으로 만들어지면 "From " 줄이 복사되고 모든 플래그가 직접 대응해요: R→R, O→O, D→D, F→F, A→A.
MHMessage 객체
class mailbox.MHMessage(message=None) — MH 특정 동작을 가진 메시지.
MH 메시지는 전통적인 의미의 표시나 플래그를 지원하지 않지만, 임의의 메시지를 논리적으로 그룹화한 시퀀스는 지원해요. 일부 메일 읽기 프로그램(표준 mh와 nmh는 아니지만)은 시퀀스를 다른 형식에서 플래그를 쓰는 것과 거의 같은 방식으로 사용해요.
| 시퀀스 | 설명 |
|---|---|
unseen |
읽지 않았지만 MUA가 이전에 감지함 |
replied |
답장함 |
flagged |
중요 표시됨 |
MHMessage 인스턴스는 다음 메서드를 제공해요.
get_sequences()— 이 메시지를 포함하는 시퀀스 이름의 리스트 반환.set_sequences(sequences)— 이 메시지를 포함하는 시퀀스 목록을 설정.add_sequence(sequence)— 이 메시지를 포함하는 시퀀스 목록에sequence추가.remove_sequence(sequence)— 이 메시지를 포함하는 시퀀스 목록에서sequence제거.
MHMessage 인스턴스가 MaildirMessage 인스턴스를 바탕으로 만들어지면:
| 결과 상태 | MaildirMessage 상태 |
|---|---|
"unseen" 시퀀스 |
S 플래그 없음 |
"replied" 시퀀스 |
R 플래그 |
"flagged" 시퀀스 |
F 플래그 |
MHMessage가 mboxMessage 또는 MMDFMessage를 바탕으로 만들어지면 Status와 X-Status 헤더가 생략되고:
| 결과 상태 | mboxMessage 또는 MMDFMessage 상태 |
|---|---|
"unseen" 시퀀스 |
R 플래그 없음 |
"replied" 시퀀스 |
A 플래그 |
"flagged" 시퀀스 |
F 플래그 |
MHMessage가 BabylMessage를 바탕으로 만들어지면:
| 결과 상태 | BabylMessage 상태 |
|---|---|
"unseen" 시퀀스 |
"unseen" 레이블 |
"replied" 시퀀스 |
"answered" 레이블 |
BabylMessage 객체
class mailbox.BabylMessage(message=None) — Babyl 특정 동작을 가진 메시지.
특정 메시지 레이블은 관례상 특별한 의미를 갖도록 정의되며 속성(attribute)이라고 불려요. 속성은 다음과 같아요.
| 레이블 | 설명 |
|---|---|
unseen |
읽지 않았지만 MUA가 이전에 감지함 |
deleted |
나중에 삭제하도록 표시됨 |
filed |
다른 파일이나 메일함으로 복사됨 |
answered |
답장함 |
forwarded |
전달됨 |
edited |
사용자가 수정함 |
resent |
재전송됨 |
기본적으로 Rmail은 보이는 헤더만 표시해요. 하지만 BabylMessage 클래스는 원본 헤더가 더 완전하기 때문에 그것을 사용해요. 원하면 보이는 헤더에 명시적으로 접근할 수 있어요.
BabylMessage 인스턴스는 다음 메서드를 제공해요.
get_labels()— 메시지의 레이블 리스트 반환.set_labels(labels)— 메시지의 레이블 목록을labels로 설정.add_label(label)— 레이블 목록에label추가.remove_label(label)— 레이블 목록에서label제거.get_visible()— 헤더가 메시지의 보이는 헤더이고 본문이 비어 있는 Message 인스턴스 반환.set_visible(visible)— 메시지의 보이는 헤더를message의 헤더와 같게 설정.visible은 Message 인스턴스,email.message.Message인스턴스, 문자열, 또는 파일류 객체(텍스트 모드로 열어야 함)여야 해요.update_visible()— BabylMessage 인스턴스의 원본 헤더가 수정돼도 보이는 헤더는 자동으로 대응되지 않아요. 이 메서드는 보이는 헤더를 다음과 같이 갱신해요: 대응하는 원본 헤더가 있는 각 보이는 헤더는 원본 헤더 값으로 설정되고, 대응하는 원본 헤더가 없는 보이는 헤더는 제거되며, 원본 헤더에는 있지만 보이는 헤더에 없는Date,From,Reply-To,To,CC,Subject중 어느 것이라도 보이는 헤더에 추가돼요.
BabylMessage가 MaildirMessage를 바탕으로 만들어지면:
| 결과 상태 | MaildirMessage 상태 |
|---|---|
"unseen" 레이블 |
S 플래그 없음 |
"deleted" 레이블 |
T 플래그 |
"answered" 레이블 |
R 플래그 |
"forwarded" 레이블 |
P 플래그 |
BabylMessage가 mboxMessage 또는 MMDFMessage를 바탕으로 만들어지면 Status와 X-Status 헤더가 생략되고:
| 결과 상태 | mboxMessage 또는 MMDFMessage 상태 |
|---|---|
"unseen" 레이블 |
R 플래그 없음 |
"deleted" 레이블 |
D 플래그 |
"answered" 레이블 |
A 플래그 |
BabylMessage가 MHMessage를 바탕으로 만들어지면:
| 결과 상태 | MHMessage 상태 |
|---|---|
"unseen" 레이블 |
"unseen" 시퀀스 |
"answered" 레이블 |
"replied" 시퀀스 |
MMDFMessage 객체
class mailbox.MMDFMessage(message=None) — MMDF 특정 동작을 가진 메시지.
mbox 메일함의 메시지처럼 MMDF 메시지는 "From "으로 시작하는 초기 줄에 보낸 이 주소와 전달 날짜를 담아 저장돼요. 마찬가지로 메시지 상태를 나타내는 플래그도 보통 Status와 X-Status 헤더에 저장돼요. MMDF 메시지의 관례적 플래그는 mbox 메시지와 동일해요: R(Read), O(Old), D(Deleted), F(Flagged), A(Answered). "R"와 "O"는 Status 헤더에, "D", "F", "A"는 X-Status 헤더에 저장돼요.
MMDFMessage 인스턴스는 mboxMessage가 제공하는 것과 동일한 다음 메서드를 제공해요.
get_from(),set_from(from_, time_=None)— 상세한 의미는 mboxMessage의get_from()/set_from()과 동일해요.get_flags(),set_flags(flags),add_flag(flag),remove_flag(flag)— 상세한 의미는 mboxMessage와 동일.
MMDFMessage가 MaildirMessage를 바탕으로 만들어지면 "From " 줄이 전달 날짜를 바탕으로 생성되고: R→S, O→"cur", D→T, F→F, A→R. MHMessage를 바탕으로: R+O→"unseen" 없음, O→"unseen", F→"flagged", A→"replied". BabylMessage를 바탕으로: R+O→"unseen" 없음, O→"unseen", D→"deleted", A→"answered". mboxMessage를 바탕으로 "From " 줄이 복사되고 모든 플래그가 직접 대응해요(R→R, O→O, D→D, F→F, A→A).
예외
mailbox 모듈은 다음 예외 클래스를 정의해요.
exception mailbox.Error— 다른 모든 모듈 특정 예외의 기반 클래스.exception mailbox.NoSuchMailboxError— 메일함이 예상되지만 찾을 수 없을 때 발생.create매개변수를False로 하고 존재하지 않는 경로로 Mailbox 하위 클래스를 인스턴스화하거나, 존재하지 않는 폴더를 열 때처럼.exception mailbox.NotEmptyError— 메일함이 비어 있지 않은데 비어 있어야 할 때 발생. 메시지를 담고 있는 폴더를 삭제할 때처럼.exception mailbox.ExternalClashError— 프로그램 통제 밖의 어떤 메일함 관련 조건이 진행을 못 하게 할 때 발생. 다른 프로그램이 이미 쥔 잠금을 얻지 못하거나, 고유하게 생성된 파일 이름이 이미 존재할 때처럼.exception mailbox.FormatError— 파일의 데이터를 파싱할 수 없을 때 발생. MH 인스턴스가 손상된.mh_sequences파일을 읽으려 할 때처럼.
예제
흥미로워 보이는 메일함의 모든 메시지 제목을 출력하는 간단한 예시예요.
import mailbox
for message in mailbox.mbox('~/mbox'):
subject = message['subject'] # Could possibly be None.
if subject and 'python' in subject.lower():
print(subject)
Babyl 메일함에서 MH 메일함으로 모든 메일을 복사하고, 변환할 수 있는 모든 형식별 정보를 변환하는 예시예요.
import mailbox
destination = mailbox.MH('~/Mail')
destination.lock()
for message in mailbox.Babyl('~/RMAIL'):
destination.add(mailbox.MHMessage(message))
destination.flush()
destination.unlock()
여러 메일링 리스트의 메일을 서로 다른 메일함으로 정렬하는 예시예요. 다른 프로그램의 동시 수정으로 인한 메일 손상, 프로그램 중단으로 인한 메일 유실, 메일함의 잘못된 메시지로 인한 조기 종료를 피하려고 신중하게 작성했어요.
import mailbox
import email.errors
list_names = ('python-list', 'python-dev', 'python-bugs')
boxes = {name: mailbox.mbox('~/email/%s' % name) for name in list_names}
inbox = mailbox.Maildir('~/Maildir', factory=None)
for key in inbox.iterkeys():
try:
message = inbox[key]
except email.errors.MessageParseError:
continue # The message is malformed. Just leave it.
for name in list_names:
list_id = message['list-id']
if list_id and name in list_id:
# Get mailbox to use
box = boxes[name]
# Write copy to disk before removing original.
# If there's a crash, you might duplicate a message, but
# that's better than losing a message completely.
box.lock()
box.add(message)
box.flush()
box.unlock()
# Remove original message
inbox.lock()
inbox.discard(key)
inbox.flush()
inbox.unlock()
break # Found destination, so stop looking.
for box in boxes.itervalues():
box.close()
더 알아보기
- email 모듈 — 메시지를 표현하고 조작함.