def __init__(self, cfg, accounts): self.MAIL_LIST_LIMIT = 10 # prevent flooding of the messaging tray self.mailcheck_lock = threading.Lock() self.mails = Mails(cfg, accounts) self.reminder = Reminder() self.pid = Pid() self.cfg = cfg # dict that tracks all notifications that need to be closed self.notifications = {} Notify.init(cfg.get('general', 'messagetray_label')) # initialize Notification
def sync(self, accounts): needs_rebuild = False # get mails from given accounts rcv_lst = Mails(self._cfg, accounts).get_mail() # group received mails by account tmp = {} for acc in accounts: tmp[acc.get_id()] = {} for mail in rcv_lst: tmp[mail.account_id][mail.id] = mail # compare current mails against received mails # and remove those that are gone (probably opened in mail client). for acc_id in self._mails_by_account.iterkeys(): if acc_id in tmp: del_ids = [] for mail_id in self._mails_by_account[acc_id].iterkeys(): if not (mail_id in tmp[acc_id]): del_ids.append(mail_id) needs_rebuild = True for mail_id in del_ids: del self._mails_by_account[acc_id][mail_id] # compare received mails against current mails # and add new mails. for acc_id in tmp: if not (acc_id in self._mails_by_account): self._mails_by_account[acc_id] = {} for mail_id in tmp[acc_id]: if not (mail_id in self._mails_by_account[acc_id]): self._mails_by_account[acc_id][mail_id] = tmp[acc_id][mail_id] needs_rebuild = True # rebuild and sort mail list if needs_rebuild: self._mail_list = [] for acc_id in self._mails_by_account: for mail_id in self._mails_by_account[acc_id]: self._mail_list.append(self._mails_by_account[acc_id][mail_id]) self._mail_list = Mails.sort_mails(self._mail_list, "desc") return self._mail_list
class MailChecker: def __init__(self, cfg, accounts): self.MAIL_LIST_LIMIT = 10 # prevent flooding of the messaging tray self.mailcheck_lock = threading.Lock() self.mails = Mails(cfg, accounts) self.reminder = Reminder() self.pid = Pid() self.cfg = cfg # dict that tracks all notifications that need to be closed self.notifications = {} Notify.init(cfg.get('general', 'messagetray_label')) # initialize Notification def check(self, firstcheck = False): with self.mailcheck_lock: print 'Checking email accounts at:', time.asctime() self.pid.kill() # kill all zombies if firstcheck: # Manual firststart self.reminder.load() self.mail_list = self.mails.get_mail('desc') # get all mails from all inboxes unseen_mails = [] new_mails = [] script_data = "" script_data_mailcount = 0 for mail in self.mail_list: if self.reminder.contains(mail.id): # mail was fetched before if self.reminder.unseen(mail.id): # mail was not marked as seen unseen_mails.append(mail) if firstcheck: # first check after startup new_mails.append(mail) else: # mail is fetched the first time unseen_mails.append(mail) new_mails.append(mail) script_data += ' "<%s> %s"' % (mail.sender, mail.subject) script_data_mailcount += 1 script_data = str(script_data_mailcount) + script_data if len(self.mail_list) == 0: # no mails (e.g. email client has been launched) -> close notifications for n in self.notifications.itervalues(): n.close() self.notifications = {} elif len(new_mails) > 0: if self.cfg.get('general', 'notification_mode') == '1': self.notify_summary(unseen_mails) else: self.notify_single(new_mails) if self.cfg.get('general', 'playsound') == '1': # play sound? gstplay(get_data_file(self.cfg.get('general', 'soundfile'))) self.reminder.save(self.mail_list) self.run_user_scripts("on_mail_check", script_data) # process user scripts sys.stdout.flush() # write stdout to log file return True def notify_summary(self, unseen_mails): summary = "" body = "" if len(self.notifications) == 0: self.notifications['0'] = self.get_notification(" ", None, None) # empty string will emit a gtk warning ubound = len(unseen_mails) if len(unseen_mails) <= self.MAIL_LIST_LIMIT else self.MAIL_LIST_LIMIT for i in range(ubound): body += unseen_mails[i].sender + ":\n<i>" + unseen_mails[i].subject + "</i>\n\n" if len(unseen_mails) > self.MAIL_LIST_LIMIT: body += "<i>" + _("(and {0} more)").format(str(len(unseen_mails) - self.MAIL_LIST_LIMIT)) + "</i>" if len(unseen_mails) > 1: # multiple new emails summary = _("You have {0} new mails.").format(str(len(unseen_mails))) else: summary = _("You have a new mail.") self.notifications['0'].update(summary, body, "mail-unread") self.notifications['0'].show() def notify_single(self, new_mails): for mail in new_mails: n = self.get_notification(mail.sender, mail.subject, "mail-unread") notification_id = str(id(n)) n.add_action("mark-as-read", _("Mark as read"), self.__notification_action_handler, (mail, notification_id), None) n.show() self.notifications[notification_id] = n def get_notification(self, summary, body, icon): n = Notify.Notification.new(summary, body, icon) n.set_category("email") n.add_action("default", "default", self.__notification_action_handler, None, None) return n def __notification_action_handler(self, n, action, user_data): with self.mailcheck_lock: if action == "default": mailclient = get_default_mail_reader() if mailclient != None: self.pid.append(subprocess.Popen(mailclient)) # clicking the notification bubble has closed all notifications # so clear the reference array as well. self.notifications = {} elif action == "mark-as-read": self.reminder.set_to_seen(user_data[0].id) self.reminder.save(self.mail_list) # clicking the action has closed the notification # so remove its reference del self.notifications[user_data[1]] def clear(self): with self.mailcheck_lock: # mark all mails to seen for mail in self.mail_list: self.reminder.set_to_seen(mail.id) self.reminder.save(self.mail_list) # close all notifications for n in self.notifications.itervalues(): n.close() self.notifications = {} self.mail_list = [] def run_user_scripts(self, event, data): if event == "on_mail_check": if self.cfg.get('script', 'script0_enabled') == '1': script_file = self.cfg.get('script', 'script0_file') if script_file != '' and os.path.exists(script_file): self.pid.append(subprocess.Popen("%s %s" % (script_file, data), shell = True)) else: print 'Warning: cannot execute script:', script_file if (data != '0') and (self.cfg.get('script', 'script1_enabled') == '1'): script_file = self.cfg.get('script', 'script1_file') if script_file != '' and os.path.exists(script_file): self.pid.append(subprocess.Popen("%s %s" % (script_file, data), shell = True)) else: print 'Warning: cannot execute script:', script_file