10.23.2011

mogmail with Python version 2.1

Python版mogmail バージョン2.1

以前作成した、こちらのスクリプトを改良。
http://mogproject.blogspot.com/2011/10/mogmail-with-python-version-20.html

・JISのデコードに失敗した機種依存文字については、一旦SJISに変換してから
 cp932 でデコードすれば正しく表示されることがわかった。
・JISからSJISの変換については、結局自前で実装することに。

mogmail.py

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python
# Copyright (c) 2011 Mog Project. All rights reserved.
# Version: 2.1, Updated: 2011/10/23
 
import poplib
import email
from email.header import decode_header
from email.utils import parsedate_tz
from email.utils import mktime_tz
import sys
import time
 
POP3_SERVER = 'POP3-Server'
POP3_PORT = 110
POP3_USERNAME = 'UserName'
POP3_PASSWORD = 'Password'
SHOW_LENGTH = 5
 
def jis_to_sjis(jis):
  esc_seq = # pair of (sequense, is_double_bytes)
      ('\x1b(B', False),  # ASCII
      ('\x1b(J', False),  # JIS X 0201-1976 Roman Set
      ('\x1b(I', False),  # JIS X 0201-1976 Katakana
      ('\x1b$@', True),  # JIS X 0208-1978 (old JIS kanji)
      ('\x1b$B', True),  # JIS X 0208-1983 (new JIS kanji)
      ('\x1b&@\x1b$B', True),  # JIS X 0208-1990
      ('\x1b$(D', True# JIS X 0212-1990
      )
  chunks = []
  pos = 0
  flg = False
  while pos < len(jis):
    for seq, is_double_bytes in esc_seq:
      if jis[pos:].startswith(seq):
        flg = is_double_bytes
        pos += len(seq)
        break
    else:
      if flg:
        hi, lo = ord(jis[pos]), ord(jis[pos + 1])
        if hi & 1:
          hi = ((hi + 1) >> 1) + 0x70
          lo += 0x1f
        else:
          hi = (hi >> 1) + 0x70
          lo += 0x7d
        if hi >= 0xa0: hi += 0x40
        if lo >= 0x7f: lo += 1
        chunks.append(chr(hi) + chr(lo))
        pos += 2
      else:
        chunks.append(jis[pos])
        pos += 1
  return ''.join(chunks)
 
class Parser(object):
  def __init__(self, msg):
    self.msg = msg
  def date(self):
    return time.localtime(mktime_tz(parsedate_tz(self.msg['date'])))
  def from_(self): return self.get_item('from')
  def subject(self): return self.get_item('subject')
  def get_item(self, key):
    uchunks = []
    decoded_seq = decode_header(self.msg[key].replace('"', ''))
    for s, charset in decoded_seq:
      if not charset: charset = 'us-ascii'
 
      # If charset is iso-2022-jp(jis), convert to cp932(sjis)
      #   for platform dependent characters.
      if charset == 'iso-2022-jp':
        s = jis_to_sjis(s)
        charset = 'cp932'
      uchunks.append(unicode(s, charset, 'ignore'))
    return u''.join(uchunks).encode(sys.stdout.encoding)
 
def main():
  pop3 = poplib.POP3(POP3_SERVER, POP3_PORT)
  try:
    pop3.apop(POP3_USERNAME, POP3_PASSWORD)
    msg_cnt = pop3.stat()[0]
    if not msg_cnt: print 'No message.'
    for i in range(msg_cnt, max(msg_cnt - SHOW_LENGTH, 0), -1):
      p = Parser(email.message_from_string('\n'.join(pop3.top(i, 0)[1])))
      print time.strftime('[%m/%d %H:%M]', p.date()),
      print '%s\n  %s' % (p.from_(), p.subject())
  except poplib.error_proto, detail:
    print 'POP3 Protocol Error:', detail
  finally:
    pop3.quit()
 
if __name__ == '__main__':
  main()

0 件のコメント:

コメントを投稿