From 06b67f48c0d46bf87bab57ce7e719dd76f2faf90 Mon Sep 17 00:00:00 2001 From: David Rousselie Date: Wed, 1 Feb 2006 00:33:09 +0100 Subject: [PATCH] Live Email checking - only check for email received while connected to Jabber (not before) darcs-hash:20060131233309-86b55-56666f0af136645b96407db8e3c877b1c2432577.gz --- jabber/component.py | 52 +++++++++++++++++++++++++--- jabber/lang.py | 4 ++- jabber/mailconnection.py | 9 +++-- jabber/mailconnection_factory.py | 8 +++-- jabber/storage.py | 40 ++++++++++++++++----- run_test.py | 6 ++-- tests/jmc-test.xml | 2 +- tests/test_mailconnection_factory.py | 17 ++++++--- tests/test_storage.py | 5 +++ 9 files changed, 115 insertions(+), 28 deletions(-) diff --git a/jabber/component.py b/jabber/component.py index 3878dac..b965bee 100644 --- a/jabber/component.py +++ b/jabber/component.py @@ -214,6 +214,10 @@ class MailComponent(Component): label = lang_class.account_check_interval, \ var = "interval", \ value = unicode(self.__interval)) + + reg_form.add_field(type = "boolean", \ + label = lang_class.account_live_email_only, \ + var = "live_email_only") return reg_form @@ -349,6 +353,12 @@ class MailComponent(Component): label = lang_class.account_check_interval, \ var = "interval", \ value = str(account.interval)) + + reg_form_init.add_field(type = "boolean", \ + label = lang_class.account_live_email_only, \ + var = "live_email_only", \ + value = str(account.live_email_only).lower()) + return reg_form_init """ Looping method """ @@ -619,10 +629,13 @@ class MailComponent(Component): else: interval = None - self.__logger.debug(u"New Account: %s, %s, %s, %s, %s, %s, %s, %s %i %i %i %i %i %i %i" \ + live_email_only = x.fields.has_key("live_email_only") \ + and (x.fields["live_email_only"].value == "1") + + self.__logger.debug(u"New Account: %s, %s, %s, %s, %s, %s, %s, %s %i %i %i %i %i %i %i %s" \ % (name, login, password, str(store_password), host, str(port), \ mailbox, type, chat_action, online_action, away_action, \ - xa_action, dnd_action, offline_action, interval)) + xa_action, dnd_action, offline_action, interval, str(live_email_only))) iq = iq.make_result_response() self.stream.send(iq) @@ -667,6 +680,7 @@ class MailComponent(Component): account.dnd_action = dnd_action account.offline_action = offline_action account.interval = interval + account.live_email_only = live_email_only if port: account.port = port @@ -821,12 +835,13 @@ class MailComponent(Component): def check_mail(self, jid, name): self.__logger.debug("CHECK_MAIL " + unicode(jid) + " " + name) account = self.__storage[(jid, name)] - if account.password is None: - self.__ask_password(name, jid, account.default_lang_class, account) - return action = account.action + if action != mailconnection.DO_NOTHING: try: + if account.password is None: + self.__ask_password(name, jid, account.default_lang_class, account) + return self.__logger.debug("Checking " + name) self.__logger.debug("\t" + account.login \ + "@" + account.host) @@ -884,6 +899,33 @@ class MailComponent(Component): self.__logger.debug("CHECK_ALL_MAIL") for jid, name in self.__storage.keys(): account = self.__storage[(jid, name)] + if account.first_check and account.live_email_only: + account.first_check = False + print "HERE" + if account.password is None: + self.__ask_password(name, jid, account.default_lang_class, account) + return + try: + account.connect() + mail_list = account.get_mail_list() + if not mail_list or mail_list[0] == '': + account.lastmail = 0 + else: + account.lastmail = len(mail_list) + account.disconnect() + account.in_error = False + except Exception,e: + if account.in_error == False: + account.in_error = True + msg = Message(from_jid = name + "@" + unicode(self.jid), \ + to_jid = jid, \ + stanza_type = "error", \ + subject = account.default_lang_class.check_error_subject, \ + body = account.default_lang_class.check_error_body \ + % (e)) + self.stream.send(msg) + self.__logger.debug("Error while checking mail : %s" \ + % (e)) account.lastcheck += 1 if account.lastcheck == account.interval: account.lastcheck = 0 diff --git a/jabber/lang.py b/jabber/lang.py index bcd1113..6bb634a 100644 --- a/jabber/lang.py +++ b/jabber/lang.py @@ -41,6 +41,7 @@ class Lang: account_dnd_action = u"Action when state is 'Do not Disturb'" account_offline_action = u"Action when state is 'Offline'" account_check_interval = u"Mail check interval (in minutes)" + account_live_email_only = u"Reports only emails received while connected to Jabber" action_nothing = u"Do nothing" action_retrieve = u"Retrieve mail" action_digest = u"Send mail digest" @@ -78,6 +79,8 @@ class Lang: account_dnd_action = u"Action lorsque l'état est 'Do not Disturb'" account_offline_action = u"Action lorsque l'état est 'Offline'" account_check_interval = u"Interval de vérification de nouveaux emails (en minutes)" + account_live_email_only = u"Vérifier les nouveaux emails seulement " \ + "lorsqu'une session Jabber est ouverte" action_nothing = u"Ne rien faire" action_retrieve = u"Récupérer l'email" action_digest = u"Envoyer un résumé" @@ -98,4 +101,3 @@ class Lang: check_error_subject = u"Erreur lors de la vérification des emails." check_error_body = u"Une erreur est survenue lors de la vérification " \ "des emails :\n\t%s" - diff --git a/jabber/mailconnection.py b/jabber/mailconnection.py index 03647b5..bc71ba9 100644 --- a/jabber/mailconnection.py +++ b/jabber/mailconnection.py @@ -165,11 +165,13 @@ class MailConnection(object): self.default_lang_class = Lang.en self.waiting_password_reply = False self.in_error = False + self.live_email_only = False + self.first_check = True def __eq__(self, other): return self.get_type() == other.get_type() \ and self.login == other.login \ - and self.password == other.password \ + and (not self.store_password or self.password == other.password) \ and self.store_password == other.store_password \ and self.host == other.host \ and self.port == other.port \ @@ -180,14 +182,15 @@ class MailConnection(object): and self.xa_action == other.xa_action \ and self.dnd_action == other.dnd_action \ and self.offline_action == other.offline_action \ - and self.interval == other.interval + and self.interval == other.interval \ + and self.live_email_only == other.live_email_only def __str__(self): return self.get_type() + "#" + self.login + "#" + \ (self.store_password and self.password or "/\\") + "#" \ + self.host + "#" + str(self.port) + "#" + str(self.chat_action) + "#" \ + str(self.online_action) + "#" + str(self.away_action) + "#" + \ - str(self.xa_action) + "#" + str(self.dnd_action) + "#" + str(self.offline_action) + "#" + str(self.interval) + str(self.xa_action) + "#" + str(self.dnd_action) + "#" + str(self.offline_action) + "#" + str(self.interval) + "#" + str(self.live_email_only) def get_decoded_part(self, part): content_charset = part.get_content_charset() diff --git a/jabber/mailconnection_factory.py b/jabber/mailconnection_factory.py index 891982e..5867e86 100644 --- a/jabber/mailconnection_factory.py +++ b/jabber/mailconnection_factory.py @@ -75,8 +75,9 @@ def str_to_mail_connection(connection_string): dnd_action = None offline_action = None interval = None + live_email_only = False if type[0:4] == "imap": - if len(arg_list) == 8: + if len(arg_list) == 9: chat_action = int(arg_list.pop()) online_action = int(arg_list.pop()) away_action = int(arg_list.pop()) @@ -84,6 +85,7 @@ def str_to_mail_connection(connection_string): dnd_action = int(arg_list.pop()) offline_action = int(arg_list.pop()) interval = int(arg_list.pop()) + live_email_only = (arg_list.pop().lower() == "true") else: retrieve = bool(arg_list.pop() == "True") if retrieve: @@ -99,7 +101,7 @@ def str_to_mail_connection(connection_string): port = port, \ mailbox = mailbox) else: - if len(arg_list) == 7: + if len(arg_list) == 8: chat_action = int(arg_list.pop()) online_action = int(arg_list.pop()) away_action = int(arg_list.pop()) @@ -107,6 +109,7 @@ def str_to_mail_connection(connection_string): dnd_action = int(arg_list.pop()) offline_action = int(arg_list.pop()) interval = int(arg_list.pop()) + live_email_only = (arg_list.pop().lower() == "true") else: retrieve = bool(arg_list.pop() == "True") if retrieve: @@ -130,6 +133,7 @@ def str_to_mail_connection(connection_string): result.offline_action = offline_action if interval is not None: result.interval = interval + result.live_email_only = live_email_only return result diff --git a/jabber/storage.py b/jabber/storage.py index 56c7564..2d7e663 100644 --- a/jabber/storage.py +++ b/jabber/storage.py @@ -188,6 +188,7 @@ class SQLiteStorage(Storage): dnd_action INTEGER, offline_action INTEGER, interval INTEGER, + live_email_only BOOLEAN, mailbox STRING, PRIMARY KEY(jid, name) ) @@ -211,14 +212,33 @@ class SQLiteStorage(Storage): cursor.execute("""select * from account""") result = {} for row in cursor.fetchall(): -# print "Creating new " + row[self.nb_pk_fields] + " connection." - account = result["#".join(row[0:self.nb_pk_fields])] = mailconnection_factory.get_new_mail_connection(row[self.nb_pk_fields]) - for field_index in range(self.nb_pk_fields + 1, len(row)): + # print "Creating new " + row[self.nb_pk_fields] + " connection." + account_type = row[self.nb_pk_fields] + account = result["#".join(row[0:self.nb_pk_fields])] = mailconnection_factory.get_new_mail_connection(account_type) + account.login = row[self.nb_pk_fields + 1] + account.password = row[self.nb_pk_fields + 2] + if account.password is None: + account.store_password = False + else: + account.store_password = True + account.host = row[self.nb_pk_fields + 3] + account.port = int(row[self.nb_pk_fields + 4]) + account.chat_action = int(row[self.nb_pk_fields + 5]) + account.online_action = int(row[self.nb_pk_fields + 6]) + account.away_action = int(row[self.nb_pk_fields + 7]) + account.xa_action = int(row[self.nb_pk_fields + 8]) + account.dnd_action = int(row[self.nb_pk_fields + 9]) + account.offline_action = int(row[self.nb_pk_fields + 10]) + account.interval = int(row[self.nb_pk_fields + 11]) + account.live_email_only = (row[self.nb_pk_fields + 12] == 1) + if account_type[0:4] == "imap": + account.mailbox = row[self.nb_pk_fields + 13] +# for field_index in range(self.nb_pk_fields + 1, len(row)): # print "\tSetting " + str(cursor.description[field_index][0]) + \ # " to " + str(row[field_index]) - setattr(account, - cursor.description[field_index][0], - row[field_index]) +# setattr(account, +# cursor.description[field_index][0], +# row[field_index]) cursor.close() return result @@ -226,17 +246,20 @@ class SQLiteStorage(Storage): Storage.__setitem__(self, pk_tuple, obj) cursor = self.__connection.cursor() mailbox = None + password = None if obj.type[0:4] == "imap": mailbox = obj.mailbox + if obj.store_password == True: + password = obj.password cursor.execute(""" insert or replace into account values - (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, (pk_tuple[0], pk_tuple[1], obj.type, obj.login, - obj.password, + password, obj.host, obj.port, obj.chat_action, @@ -246,6 +269,7 @@ class SQLiteStorage(Storage): obj.dnd_action, obj.offline_action, obj.interval, + obj.live_email_only, mailbox)) self.__connection.commit() cursor.close() diff --git a/run_test.py b/run_test.py index 004781f..db69cd9 100644 --- a/run_test.py +++ b/run_test.py @@ -72,9 +72,9 @@ if __name__ == '__main__': # test_support.run_suite(mc_factory_suite) # test_support.run_suite(component_suite) # test_support.run_suite(component2_suite) - # test_support.run_suite(storage_suite) - # test_support.run_suite(sqlitestorage_suite) - # test_support.run_suite(dbmstorage_suite) + #test_support.run_suite(storage_suite) + #test_support.run_suite(sqlitestorage_suite) + #test_support.run_suite(dbmstorage_suite) test_support.run_suite(jmc_suite) # coverage.stop() diff --git a/tests/jmc-test.xml b/tests/jmc-test.xml index 8fea6a5..f09380f 100644 --- a/tests/jmc-test.xml +++ b/tests/jmc-test.xml @@ -12,7 +12,7 @@ http://people.happycoders.org/dax/jabber/jmc/ - DBM + SQLite . 5 diff --git a/tests/test_mailconnection_factory.py b/tests/test_mailconnection_factory.py index 6f139af..fab5dac 100644 --- a/tests/test_mailconnection_factory.py +++ b/tests/test_mailconnection_factory.py @@ -58,6 +58,7 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.RETRIEVE) self.assertEquals(mc.offline_action, mailconnection.DO_NOTHING) self.assertEquals(mc.interval, 5) + self.assertEquals(mc.live_email_only, False) def test_str_to_mail_connection_pop3_v01_v02(self): mc = str_to_mail_connection("pop3#login#passwd#host#110#False") @@ -74,9 +75,10 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.DO_NOTHING) self.assertEquals(mc.interval, 5) + self.assertEquals(mc.live_email_only, False) def test_str_to_mail_connection_imap(self): - mc = str_to_mail_connection("imap#login#passwd#host#193#0#0#0#1#1#2#4#INBOX") + mc = str_to_mail_connection("imap#login#passwd#host#193#0#0#0#1#1#2#4#True#INBOX") self.assertEquals(mc.get_type(), "imap") self.assertEquals(mc.login, "login") self.assertEquals(mc.password, "passwd") @@ -90,9 +92,10 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.RETRIEVE) self.assertEquals(mc.interval, 4) + self.assertEquals(mc.live_email_only, True) def test_str_to_mail_connection_no_password(self): - mc = str_to_mail_connection("imap#login#/\\#host#193#0#0#0#1#1#2#4#INBOX") + mc = str_to_mail_connection("imap#login#/\\#host#193#0#0#0#1#1#2#4#False#INBOX") self.assertEquals(mc.get_type(), "imap") self.assertEquals(mc.login, "login") self.assertEquals(mc.password, None) @@ -107,9 +110,10 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.RETRIEVE) self.assertEquals(mc.interval, 4) + self.assertEquals(mc.live_email_only, False) def test_str_to_mail_connection_imaps(self): - mc = str_to_mail_connection("imaps#login#passwd#host#993#0#0#0#1#1#2#4#INBOX.SubDir") + mc = str_to_mail_connection("imaps#login#passwd#host#993#0#0#0#1#1#2#4#True#INBOX.SubDir") self.assertEquals(mc.get_type(), "imaps") self.assertEquals(mc.login, "login") self.assertEquals(mc.password, "passwd") @@ -123,9 +127,10 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.RETRIEVE) self.assertEquals(mc.interval, 4) + self.assertEquals(mc.live_email_only, True) def test_str_to_mail_connection_pop3(self): - mc = str_to_mail_connection("pop3#login#passwd#host#110#0#0#0#1#1#2#4") + mc = str_to_mail_connection("pop3#login#passwd#host#110#0#0#0#1#1#2#4#False") self.assertEquals(mc.get_type(), "pop3") self.assertEquals(mc.login, "login") self.assertEquals(mc.password, "passwd") @@ -138,9 +143,10 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.RETRIEVE) self.assertEquals(mc.interval, 4) + self.assertEquals(mc.live_email_only, False) def test_str_to_mail_connection_pop3s(self): - mc = str_to_mail_connection("pop3s#login#passwd#host#995#0#0#0#1#1#2#4") + mc = str_to_mail_connection("pop3s#login#passwd#host#995#0#0#0#1#1#2#4#True") self.assertEquals(mc.get_type(), "pop3s") self.assertEquals(mc.login, "login") self.assertEquals(mc.password, "passwd") @@ -153,4 +159,5 @@ class MailConnectionFactory_TestCase(unittest.TestCase): self.assertEquals(mc.dnd_action, mailconnection.DIGEST) self.assertEquals(mc.offline_action, mailconnection.RETRIEVE) self.assertEquals(mc.interval, 4) + self.assertEquals(mc.live_email_only, True) diff --git a/tests/test_storage.py b/tests/test_storage.py index ff6f413..361ec91 100644 --- a/tests/test_storage.py +++ b/tests/test_storage.py @@ -72,6 +72,8 @@ class DBMStorage_TestCase(unittest.TestCase): self._account2.dnd_action = mailconnection.DO_NOTHING self._account2.offline_action = mailconnection.DO_NOTHING self._account2.interval = 4 + self._account2.store_password = False + self._account2.live_email_only = True def tearDown(self): db_file = self._storage.file @@ -190,6 +192,8 @@ class SQLiteStorage_TestCase(DBMStorage_TestCase): self._account2.dnd_action = mailconnection.DO_NOTHING self._account2.offline_action = mailconnection.DO_NOTHING self._account2.interval = 4 + self._account2.store_password = False + self._account2.live_email_only = True # def tearDown(self): # os.remove(self._storage.file) @@ -199,6 +203,7 @@ class SQLiteStorage_TestCase(DBMStorage_TestCase): def test_set_sync_get(self): self._storage[("test@localhost", "account1")] = self._account1 self._storage[("test@localhost", "account2")] = self._account2 + self._account2.password = None loaded_storage = SQLiteStorage(nb_pk_fields = 2, spool_dir = "./spool/test") self.assertEquals(loaded_storage[("test@localhost", "account1")], self._account1)