# Various utility functions for pyne import gtk import gobject import pynei18n import binascii import os.path import ptk.misc_widgets import cStringIO def string_line_wrap (s, wrap_len): """ Strong mangling is not one of my string points... """ pos = 0 line = "" # hack - we want to wrap anything _over_ wrap_len wrap_len = wrap_len + 1 o = cStringIO.StringIO () while pos < len(s): # cut 'wrap_len' chunk, or up to next '\n' nl = s[pos:pos+wrap_len].rfind ("\n") if nl != -1: nl = nl + 1 o.write (s[pos:pos+nl]) pos = pos + nl if pos != len(s): # strip leading whitespace of next line # if we exposed one while pos < len(s) and s[pos].isspace(): pos = pos + 1 continue line = s[pos:pos+wrap_len] if (pos+wrap_len) > len(s): pos = len(s) else: pos = pos + wrap_len # now go back if we sliced a word apart if pos != len(s) and (not line[-1].isspace ()): end = len(line) - 1 while (not line[end].isspace()) and end > 0: end = end - 1 if end != 0: # yay! snip snip snip. pos = pos - (len(line) - end - 1) line = line[:end+1] o.write (line) if pos != len(s): # strip leading whitespace of next line # if we exposed one while pos < len(s) and s[pos].isspace(): pos = pos + 1 if pos != len(s): o.write ("\n") o.seek (0) return o.read () # We need to clean up shitty 8-bit ascii # XXX really should change encoding according to msg def _u(s): return unicode(s, encoding="ISO-8859-1", errors="replace") # Decode filein to fileout, parsing each line with lineparsefunc. # We return what we have done so far if lineparsefunc raises exception. def line_decoder(filein, fileout, lineparsefunc): # when we find data then black lines mean finish, but not before started = 0 try: line_no = 0 while 1: line_no = line_no + 1 line = filein.readline() if not line: break if line == "\n" and started == 1: break started = 1 s = lineparsefunc(line) fileout.write(s) except Exception, e: print "Error decoding attachment: %s (line %d)" % (str(e), line_no) def days_between(date1, date2): """ Return days between these 2 dates. Dates should be in seconds. """ return int((date1-date2)/86400) def split_address(sendstr): """ Parses the sender name such as: "Bob Bobson" to tuple: ("Bob Bobson", "") """ email = "" temp = sendstr # Strip "'s temp = temp.replace ("\"", "") # Remove email addr x = temp.find ("<") if x >= 0: email = temp[x+1:-1] temp = temp[0:x] # Strip whitespace temp = temp.strip () # it's possible we have that silly "address@some.com (User Name)" format x = temp.find("@") if x != -1 and temp.find("(") != -1: temp = temp[ temp.find("(")+1 : temp.find(")") ] email = sendstr[ 0: sendstr.find("(")-1] # Email only types if temp == "": return (email, email) else: return (temp, email) # Apply a function to a list of mailboxes, and any mailboxes # they may contain. # XXX Any !=None returns will be returned in a list def recurse_apply(folders, function, returns=None): if returns == None: returns = [] for x in folders: temp = function(x) if temp != None: returns.append(temp) if x.__dict__.has_key("contents"): recurse_apply(x.contents, function, returns) return returns # File selection helper functions class _FileSelection(gtk.FileSelection): def __init__(self, modal=True): gtk.FileSelection.__init__(self) self.connect("destroy", self.quit) self.connect("delete_event", self.quit) if modal: gtk.grab_add(self) self.cancel_button.connect('clicked', self.quit) self.ok_button.connect('clicked', self.ok_cb) self.ret = None def quit(self, *args): self.hide() self.destroy() gtk.main_quit() def ok_cb(self, b): self.ret = self.get_filename() self.quit() def modal_file_sel_box(title="Browse", modal=False): win = _FileSelection(modal=modal) win.set_title(title) win.show() gtk.mainloop() return win.ret def col_picker(ok_callback, message=_("Select a colour"), col=None, parent_win=None): """ Col should be a string '#rrggbb' """ dialog = gtk.ColorSelectionDialog(message) if parent_win: dialog.set_transient(parent_win) if col: dialog.colorsel.set_current_color( dialog.get_colormap().alloc_color(col) ) dialog.help_button.hide() def _close(_w): dialog.destroy() def _apply(_w): col = dialog.colorsel.get_current_color() dialog.destroy() ok_callback("#%02x%02x%02x" % (col.red/256, col.green/256, col.blue/256)) dialog.cancel_button.connect("clicked", _close) dialog.ok_button.connect("clicked", _apply) class UserChooseBox: def __init__(self, user, compare_func, ok_func, title=_("Select a mailbox"), parent_win=None): """ Allow the user to select from all boxes that return match when examined with 'compare_func'. Function 'ok_func' will be called when one is selected with argument: selected box. """ win = gtk.Window() win.set_title(title) if parent_win: win.set_transient_for (parent_win) box1 = gtk.VBox(spacing=5) box1.set_border_width(5) win.add(box1) box1.show() # make list of outbox name, uid def _get_mailboxes(folder, cmp=compare_func): if cmp(folder): return (folder.name, folder.uid) #if isinstance(folder, mailbox): # if folder.send_type != mail_send.MAIL_SEND_NONE: # # only mailboxes with smtp server. # return (folder.name, folder.uid) outboxes = recurse_apply(user.contents, _get_mailboxes) if len(outboxes) == 0: info_box(_("Error"), _("You need to have a mailbox\nto send mail :-)")) return # just one mailbox. use it. if len(outboxes) == 1: from_folder = user.get_folder_by_uid(outboxes[0][1]) win.destroy() ok_func(from_folder) return self.outbox_list = gtk.TreeView() cell = gtk.CellRendererText () col = gtk.TreeViewColumn (_("Send using mailbox:"), cell, text=0) self.outbox_list.append_column (col) self.selected_outbox = None model = gtk.ListStore (gobject.TYPE_STRING, gobject.TYPE_STRING) self.outbox_list.set_model (model) for obox in outboxes: iter = model.append () model.set (iter, 0, obox[0], 1, obox[1]) def _select_outbox(widget, event): selected = widget.get_path_at_pos (int (event.x), int (event.y)) if selected == None: return model = self.outbox_list.get_model () iter = model.get_iter (selected[0]) # invisible field gives uid of box self.selected_outbox = model.get_value (iter, 1) if event.type == gtk.gdk._2BUTTON_PRESS: folder = user.get_folder_by_uid(self.selected_outbox) win.destroy() ok_func(folder) self.outbox_list.connect("button_press_event", _select_outbox) box1.pack_start(self.outbox_list) self.outbox_list.show() def _ok_func(_button): if self.selected_outbox == None: # please pick one... return folder = user.get_folder_by_uid(self.selected_outbox) win.destroy() ok_func(folder) def _cancel(_button, win=win): win.destroy() buttonbox = gtk.HBox(spacing=5) box1.pack_start(buttonbox, expand=False) buttonbox.show() button = gtk.Button(stock="gtk-cancel") button.connect("clicked", _cancel) buttonbox.pack_end(button, expand=False) button.show() button = gtk.Button(stock="gtk-ok") button.connect("clicked", _ok_func) buttonbox.pack_end(button, expand=False) button.show() win.show()