目录


1 POP

POP(Post Office Protocol,邮局协议):用于电子邮件的接收。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。POP最大的优点是简单(执行邮件fetch,delete),这同时也是它最大的缺点(无法辨别已下载的邮件,即客户端和服务器的同步;IMPA可以解决这个问题)。

IMAP在POP基础上提供更多的功能,本文简单介绍POP。对于IMAP的介绍,请见这里

如今最流行的POP版本是3,因此我们常默认POP就是POP3。

Python的21.14 poplib的是对POP3协议的client实现,主要提供连接POP server,mailbox信息收集,下载messages,删除server原始message等4个功能。

1.1 Pop Server Compatibility

POP服务端的实现在POP标准里并没有指明,因此对于如何同步非常模糊,有些POP服务端只有当你下载才认为是已读,有些即使下载也不认为是已读。因此在使用POP3的时候要格外小心。

Network Data & Error Summary

1.2 Connecting and Authenticating

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import getpass, poplib, sys

def main():
    if len(sys.argv) !=3:
        print("usage: {} hostname username".format(sys.argv[0]))
        sys.exit(2)

    hostname, username = sys.argv[1:]
    p = poplib.POP3(hostname)
    try:
        p.user(username)
        p.pass_(getpass.getpass())

    except poplib.error_proto as e:
        print("Login fail: {}".format(e))

    else:
        print("Your message: {}".format(p.stat()))
    finally:
        p.quit()
        
if __name__=="__main__":
    main()

1.3 Obtaining Mailbox Information

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import getpass, poplib, sys

def main():
    if len(sys.argv) != 3:
        print('usage: %s hostname username' % sys.argv[0])
        exit(2)
    hostname, username = sys.argv[1:]
    passwd = getpass.getpass()
    p = poplib.POP3_SSL(hostname)
    try:
        p.user(username)
        p.pass_(passwd)
    except poplib.error_proto as e:
        print("Login failed:", e)
    else:
        response, listings, octet_count = p.list()
        if not listings:
            print("No messages")
        for listing in listings:
            number, size = listing.decode('ascii').split()
            print("Message %s has %s bytes" % (number, size))
    finally:
        p.quit()
if __name__ == '__main__':
    main()

1.4 Downloading and Deleting Messages

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import email, getpass, poplib, sys

def main():
    if len(sys.argv) != 3:
        print('usage: %s hostname username' % sys.argv[0])
        exit(2)

  	hostname, username = sys.argv[1:]
    passwd = getpass.getpass()
    p = poplib.POP3_SSL(hostname)
    try:
        p.user(username)
        p.pass_(passwd)
    except poplib.error_proto as e:
        print("Login failed:", e)
    else:
        visit_all_listings(p)
    finally:
p.quit()
def visit_all_listings(p):
    response, listings, octets = p.list()
    for listing in listings:
        visit_listing(p, listing)
def visit_listing(p, listing):
    number, size = listing.decode('ascii').split()
    print('Message', number, '(size is', size, 'bytes):')
    print()
    response, lines, octets = p.top(number, 0)
    document = '\n'.join( line.decode('ascii') for line in lines )
    message = email.message_from_string(document)
    for header in 'From', 'To', 'Subject', 'Date':
        if header in message:
            print(header + ':', message[header])
    print()
    print('Read this message [ny]?')
    answer = input()
    if answer.lower().startswith('y'):
        response, lines, octets = p.retr(number)
        document = '\n'.join( line.decode('ascii') for line in lines )
        message = email.message_from_string(document)
        print('-' * 72)
        for part in message.walk():
            if part.get_content_type() == 'text/plain':
                print(part.get_payload())
                print('-' * 72)
    print()
    print('Delete this message [ny]?')
    answer = input()
    if answer.lower().startswith('y'):
        p.dele(number)
        print('Deleted.')
if __name__ == '__main__':
    main()

2 总结

Network Data & Error Summary

4 参考资料


Share Post

Twitter Google+

Shunmian

The only programmers in a position to see all the differences in power between the various languages are those who understand the most powerful one.