# File: mailbox.py # Purpose: pop3 inbox class import socket import string import gtk import cPickle from pyneheaders import * import mail_recv from mail_recv import * import mail_send from mail_send import * from superbox import * import boxformats import boxformats.configbox from ptk.big_edit_box import * import pynei18n from boxtypes.net_exceptions import * import msgfilter import personality import ptk.personalitybox import ptk.misc_widgets class mailbox(superbox): """ Pop3 inbox. """ def get_flags(self): flags = BOX_ISDELETEABLE | BOX_MAKE_NEW_MSG | \ BOX_REPLY_SINGLE | BOX_REPLY_GROUP | \ BOX_REPLY_FORWARD | BOX_DEL_MESSAGE | \ BOX_IMPORT_TO if self.recv_type != mail_recv.MAIL_RECV_NONE: return flags | BOX_UPDATE_METHOD else: return flags def save(self, user): tosave = {} def _saveme(key, tosave=tosave, self=self): tosave[key] = self.__dict__[key] _saveme("uid") _saveme("name") _saveme("opts") _saveme("recv_type") _saveme("send_type") _saveme("recv_conf") _saveme("send_conf") _saveme("personalities") _saveme("default_personality") _saveme("collection_threads") _saveme("expire_after") _saveme("export_format") _saveme("collect_policy") _saveme("filters") _saveme("num_unread") f = open(self.uid+".fol", "w") cPickle.dump(ver_stamp, f, 1) cPickle.dump("MAILBOX", f, 1) cPickle.dump(tosave, f, 1) f.close() def __init__(self, user, uid): self.load(user, uid) def load(self, user, uid): """ Create new pop inbox. """ self.load_box (user, uid) def _ifmissing(key, value, self=self): if not self.__dict__.has_key(key): self.__dict__[key] = value _ifmissing("uid", uid) _ifmissing("name", _("Mailbox")) _ifmissing("opts", 0) _ifmissing("recv_type", mail_recv.MAIL_RECV_POP3) _ifmissing("send_type", mail_send.MAIL_SEND_SMTP) _ifmissing("recv_conf", { "server": "pop.someisp.com", "port": 110, "username": "", "password": "", "auth": 0 } ) _ifmissing("send_conf", { "server": "smtp.someisp.com", "port": 25, "username": "", "password": "", "auth": 0 } ) # Keys in user.personalities dict _ifmissing("personalities", []) # Add a default personality if not self.__dict__.has_key("default_personality"): p = personality.personality(self.name+" default") p.uid = user.get_personality_uid() user.personalities[p.uid] = p self.personalities.append(p.uid) self.default_personality = p.uid _ifmissing("collection_threads", 1) _ifmissing("expire_after", None) _ifmissing("export_format", (boxformats.BF_FLATFILEBOX, None)) # server things _ifmissing("collect_policy", (SERVER_DELETE, "")) _ifmissing("filters", []) _ifmissing("num_unread", 0) # sub-folders self.contents = [] self.startup(user) def startup(self, user): """ Get an io module for loading/saving articles """ i = self.export_format[0] # this is a pretty piece of code :-) bf_class = boxformats.__dict__[boxformats.__all__[i]]. \ __dict__[boxformats.__all__[i]] self._io = bf_class(user, self) # get recv and send server types i = self.recv_type self.recv_server = mail_recv.__dict__[mail_recv.__all__[i]] i = self.send_type self.send_server = mail_send.__dict__[mail_send.__all__[i]] self.messages = self._io.get_contents() def getstats(self): """ Returns message to be put in 'items' field of mailbox view. """ #return (len(self.messages),) return (str (self.num_unread) + " ("+ str(len(self.messages)) + ")",) def get_menu(self): """ This folder type specific options. """ return [] def menu_chosen(self, _a, choice): return def get_connection(self, recv=0, no_connection=0): """ Return a connection object. if pop=0: smtp, pop=1: pop3. """ if recv == 0: # establish smtp connection c = self.send_server.get_connection(self.send_conf) return c else: # establish pop3 connection c = self.recv_server.get_connection(self.recv_conf, no_connection) return c def setup(self, user, parent_win): """ Configure a mailbox. """ import msgfilter win = gtk.Window() win.set_title(self.name+" "+_("Setup")) win.set_transient_for(parent_win) box = gtk.VBox() box.set_border_width(5) win.add(box) box.show() notebook = gtk.Notebook() notebook.set_tab_pos(gtk.POS_TOP) box.pack_start(notebook) notebook.show() # First page: Misc settings box1 = gtk.VBox(spacing=5) settings_box0 = big_edit_box( self, ( ("name", _("Name:"), VAR_TYPE_STRING, 0, 0), ("expire_after", _("Expire after (days):"), VAR_TYPE_INTEGER, 0, None), ("collection_threads", _("Download threads:"), VAR_TYPE_INTEGER, 0, 4), ("opts", _("Thread messages"), VAR_TYPE_PACKED_BIT_BOOLEAN, 0, OPT_THREAD) ) ) box1.pack_start(settings_box0, expand=False) settings_box0.show() policybox = msgfilter.policy_editbox(self) box1.pack_start(policybox, expand=False) policybox.show() def _update_buttons (): self.send_config_button.set_sensitive (self.send_server.setup != None) self.recv_config_button.set_sensitive (self.recv_server.setup != None) def _change_send_server(item, self=self): type = mail_send.__all__[send_combo.get_active ()] # if changed if mail_send.__all__.index(type) != self.send_type: self.send_type = mail_send.__all__.index(type) self.send_server = mail_send.__dict__[mail_send.__all__[self.send_type]] self.send_server.fix_defaults(self.send_conf) _update_buttons () def _config_send_server(_button, self=self): self.send_server.setup(self, self.send_conf, win) def _config_recv_server(_button, self=self): self.recv_server.setup(self, self.recv_conf, win) def _change_recv_server(item, self=self): type = mail_recv.__all__[recv_combo.get_active ()] # if changed if mail_recv.__all__.index(type) != self.recv_type: self.recv_type = mail_recv.__all__.index(type) self.recv_server = mail_recv.__dict__[mail_recv.__all__[self.recv_type]] self.recv_server.fix_defaults(self.recv_conf) _update_buttons () table = gtk.Table(3,2) table.set_row_spacings(5) table.set_col_spacings(5) box1.pack_start(table, expand=False) table.show() label = gtk.Label(_("Send server")) table.attach(label, 0,1, 0,1) label.show() send_combo = gtk.combo_box_new_text () for i in range (0, len (mail_send.__all__)): send_combo.append_text (mail_send.names[i]) send_combo.set_active (self.send_type) send_combo.connect ("changed", _change_send_server) table.attach (send_combo, 1,2, 0,1) send_combo.show () self.send_config_button = gtk.Button(_("Configure")) self.send_config_button.connect("clicked", _config_send_server) table.attach(self.send_config_button, 2,3, 0,1) self.send_config_button.show() label = gtk.Label(_("Receive server")) table.attach(label, 0,1, 1,2) label.show() recv_combo = gtk.combo_box_new_text () for i in range (0, len (mail_recv.names)): recv_combo.append_text (mail_recv.names[i]) recv_combo.set_active (self.recv_type) recv_combo.connect ("changed", _change_recv_server) table.attach (recv_combo, 1,2, 1,2) recv_combo.show () self.recv_config_button = gtk.Button(_("Configure")) self.recv_config_button.connect("clicked", _config_recv_server) table.attach(self.recv_config_button, 2,3, 1,2) self.recv_config_button.show() _update_buttons () label = gtk.Label(_("Settings")) notebook.append_page(box1, label) box1.show() # 2nd page: personalities label = gtk.Label(_("Personalities")) personbox = ptk.personalitybox.personalitybox(self, user, win) notebook.append_page(personbox, label) personbox.show() # 3rd page: mail filters label = gtk.Label(_("Filters")) filterbox = msgfilter.filters_editlist(self, user) notebook.append_page(filterbox, label) filterbox.show() # 4th page: storage method label = gtk.Label(_("Mailbox Format")) formatbox = boxformats.configbox.configbox(self, user, win) notebook.append_page(formatbox, label) formatbox.show() def save_changes(_button, filterbox=filterbox, self=self, \ user=user, win=win, settings_box0 = settings_box0, \ policybox = policybox, personbox = personbox): # Extract info settings_box0.apply_changes() policybox.apply_changes() filterbox.apply_changes() personbox.apply_changes() # update folder list self.changed = 1 # Save changes to disk self.save(user) user.update() def save_changes_close(_button, win=win, save_changes=save_changes): save_changes(_button) win.destroy() def _cancel(_button, win=win): win.destroy() # Seperator between entry boxes and buttons separator = gtk.HSeparator() box.pack_start(separator, expand=False) separator.show() # Buttons at bottom buttonbox = ptk.misc_widgets.MyButtonBox() box.pack_start(buttonbox, expand=False) buttonbox.show() button = gtk.Button(stock="gtk-ok") button.connect("clicked", save_changes_close) buttonbox.pack_end(button, expand=False) button.show() button = gtk.Button(stock="gtk-apply") button.connect("clicked", save_changes) buttonbox.pack_end(button, expand=False) button.show() button = gtk.Button(stock="gtk-cancel") button.connect("clicked", _cancel) buttonbox.pack_end(button, expand=False) button.show() win.show() def update(self, user, progressbar): """ Collect mail from server. """ import copy self.locked = 1 # If no server is designated abort collection if self.recv_type == mail_recv.MAIL_RECV_NONE: del self.locked progressbar.finished() return usermsg = self.name+": "+_("Connecting to %s...") % self.recv_conf["server"] progressbar.log_msg(usermsg) progressbar.bar_msg(usermsg) def logfunc(msg, progressbar=progressbar): progressbar.log_msg(msg) progressbar.bar_msg(msg) num_threads = self.collection_threads try: # Connect to server servers = [ self.get_connection(recv=1) ] for i in range(1, num_threads): servers.append( self.get_connection(recv=1, no_connection=1) ) except timeout_exception, e: logfunc(_("Error downloading %s: %s") % (self.name, str(e.args))) progressbar.bar_enable(False) progressbar.bar_pos(0.0) progressbar.finished() del self.locked return except auth_exception, e: logfunc(_("%s login incorrect") % self.name) progressbar.bar_enable(False) progressbar.bar_pos(0.0) progressbar.finished() del self.locked return # store nice listy thing of messages to collect self.pending_msgs = servers[0].get_msg_list() nummsgs = len( self.pending_msgs ) articles = [] for i in self.pending_msgs.keys(): articles.append(i) def incfunc(self=self, progressbar=progressbar, start_num=nummsgs, articles=articles): """ Update progress bar. """ num_left = len(articles) if start_num == 0: progressbar.bar_pos(0.0) else: progressbar.bar_pos((start_num-num_left)/float(start_num)) progressbar.bar_msg("%d/%d of " % ((start_num-num_left), start_num) + self.name) # Start collecting incfunc() self.recv_collect_threaded(user, servers, msgfilter.filter_collect, logfunc, incfunc, articles) for i in servers: i.close_connection() self.changed = 1 progressbar.bar_enable(False) progressbar.bar_pos(0.0) progressbar.finished() user.queue_action(ACT_UPDATE) del self.pending_msgs del self.locked