]> Pileus Git - ~andy/fetchmail/blob - contrib/PopDel.py
Fix typo repsonsible -> responsible.
[~andy/fetchmail] / contrib / PopDel.py
1 # PopDel.py  Copyright Richard Harris 2002
2 #
3 # author: Richard Harris (rover@emptydog.com)
4 # The author releases this file under the GPL
5 # license. See COPYING for specifics.
6 #
7 # See PopDel.manual for the use of this Python class.
8 #
9 # created: 01 May 2002
10 # last modified: 27 Apr 2006
11 #
12 # change log:
13 # Matthias Andree, April 2006:
14 #       Bump version to 0.1+jc2 and mark Joshua Crawford
15 #       as additional author.
16 #       Reformat ESR's change log entry
17 #       Note: emptydog.com is currently not registered.
18 # Joshua Crawford, April 2006:
19 #       Display From: address.
20 #       List every email, even if it has no Subject: header.
21 #         this also avoids indexing errors (that caused
22 #         deleting the wrong message)
23 # Joshua Crawford, November 2004:
24 #       Out of range error fixed.
25 #       Allow for all caps "SUBJECT:".
26 #       Display user and server name in messages.
27 #       Don't prompt for save if no changes.
28 #       Don't clear the screen until we're displaying a menu.
29 #       Check for invalid choice.
30 #       Check all arguments exist.
31 #       Check for errors in POP.
32 #       Return 1 on errors, 0 otherwise.
33 # Eric S. Raymond, January 2003:
34 #       Hacked to support message ranges.
35 #
36 import os, poplib, re, string, sys
37
38 class PopDel:
39         HDR = "\nPopDel - Delete messages from popmail - Ver. 0.1+jc2"
40         BYE = "\n  PopDel Ver.0.1+jc2 by Richard Harris and Joshua Crawford\n" +\
41 #                 "     site - http://emptydog.com/\n" +\
42                   "     email - Richard Harris <rover@emptydog.com>\n" +\
43                   "     email - Joshua Crawford <jgcrawford@gmail.com>\n"
44         PROMPT1 = "Choose message number to delete or 'q' to quit: "
45         PROMPT2 = "Quit or abort: "
46         CHOICES = ["Save changes and quit.",
47                            "Abort and make no deletions."]
48         
49         def __init__(self):
50                 self.done = 0
51                 self.dirty = 0
52                 return
53
54         # get user to choose an element from thing
55         def query(self, thing, prompt):
56                 length = len(thing)
57                 choice = [length+1]
58                 for i in range(0, length):
59                         print '(' + `i +  1` + ') ' + thing[i]
60                 while filter(lambda x: x > length, choice):
61                         choice = raw_input(prompt)
62                         if (choice == 'q'):
63                                 self.done = 1
64                                 choice = [-1]
65                         else:
66                                 try:
67                                         choice = map(int, string.split(choice, "-"))
68                                 except:
69                                         choice = [length + 1]
70                                 if len(choice) > 1:
71                                         choice = range(choice[0], choice[1]+1)
72                 return choice
73
74         def run(self):
75                 #log in
76                 print self.HDR
77
78                 subjects = []
79
80                 if (len(sys.argv) < 4):
81                         print 'Usage: ' + sys.argv[0] + ' pop3.host.name username password'
82                         return 1
83
84                 try:
85                         M = poplib.POP3(sys.argv[1])
86                 except:
87                         print 'Could not reach ' + sys.argv[1]
88                         return 1
89                 try:
90                         M.user(sys.argv[2])
91                 except:
92                         print 'Bad username ' + sys.argv[2] + '@' + sys.argv[1]
93                         M.quit()
94                         return 1
95                 try:
96                         M.pass_(sys.argv[3])
97                 except:
98                         print 'Bad password for ' + sys.argv[2] + '@' + sys.argv[1]
99                         M.quit()
100                         return 1
101 #               M.set_debuglevel(1)
102                 try:
103                         messages = M.list()
104                 except:
105                         print 'Error reading listing for ' + sys.argv[2] + '@' + sys.argv[1]
106                         M.quit()
107                         return 1
108
109                 list = messages[1]
110                 if (len(list) == 0):
111                         M.quit()
112                         print '\nNo messages for ' + sys.argv[2] + '@' + sys.argv[1]
113                 else:
114                         for entry in list:
115                                 tokens = string.split(entry)
116                                 subject = '(no subject)'
117                                 address = '(no address)'
118                                 try:
119                                         head = M.top(int(tokens[0]), 32)
120                                 except:
121                                         print 'Error issuing TOP command for ' + sys.argv[2] + '@' + sys.argv[1]
122                                         if self.dirty:
123                                                 M.rset()
124                                         M.quit()
125                                         return 1
126                                 for line in head[1]:
127                                         if (string.find(string.upper(line), 'SUBJECT:') == 0):
128                                                 subject = line[9:]
129                                         if (string.find(string.upper(line), 'FROM:') == 0):
130                                                 line = line[6:]
131                                                 result = re.search(r'([^\t <>]*@[^\t <>]*)', line)
132                                                 if (result != None):
133                                                         address = result.expand(r'\1')
134                                 subj = address[:40] + ' [' + tokens[1] + 'o] ' + subject
135                                 subjects.append(subj)
136
137                         while not self.done:
138                                 os.system('clear')
139                                 print self.HDR
140                                 print '\nMessages for ' + sys.argv[2] + '@' + sys.argv[1] + ':'
141                                 msglist = self.query(subjects, self.PROMPT1)
142                                 print "Choice:", msglist
143                                 for msg in msglist:
144                                         if (msg > 0):
145                                                 try:
146                                                         M.dele(msg)
147                                                 except:
148                                                         print 'Error deleting message #' + `msg`
149                                                         if self.dirty:
150                                                                 M.rset()
151                                                         M.quit()
152                                                         return 1
153                                                 self.dirty = 1
154                                                 subjects[msg-1] = subjects[msg-1] + ' -X-'
155
156                         if not self.dirty:
157                                 M.quit()
158                         else:
159                                 print '\nExit Options:'
160                                 choice = self.query(self.CHOICES, self.PROMPT2)
161                                 print "Choice:", choice
162                                 if (choice == [1]):             # commit changes and quit
163                                         M.quit()
164                                 else:                           # reset and quit
165                                         M.rset()
166                                         M.quit()
167
168                 print self.BYE
169                 return
170
171 #-----------------main
172 obj = PopDel()
173 sys.exit(obj.run())