def assertok(self, res, *args): """Check that the return code is OK. It also prints out what happened (which would end up /dev/null'ed in non-verbose mode) """ if 'uid FETCH' in args[0] and not self.verbose_mails: res = utils.shorten(res, 140) if 'SEARCH' in args[0]: res = utils.shorten(res, 140) self.logger.debug("{} = {}".format(args, res)) if res[0] not in ["OK", "BYE"]: self.logger.error( __("{} returned {} - aborting".format(args, res))) raise ISBGError(__exitcodes__['imap'] if self.exitcodes else -1, "\n%s returned %s - aborting\n" % (repr(args), res) )
def assertok(self, res, *args): """Check that the return code is OK. It also prints out what happened (which would end up /dev/null'ed in non-verbose mode) """ if 'uid FETCH' in args[0] and not self.verbose_mails: res = utils.shorten(res, 140) if 'SEARCH' in args[0]: res = utils.shorten(res, 140) self.logger.debug("{} = {}".format(args, res)) if res[0] not in ["OK", "BYE"]: self.logger.error(__("{} returned {} - aborting".format(args, res))) raise ISBGError( __exitcodes__['imap'] if self.exitcodes else -1, "\n%s returned %s - aborting\n" % (repr(args), res))
def learn(self, folder, learn_type, move_to, origpastuids): """Learn the spams (and if requested deleted or move them). Args: folder (str): The IMAP folder. leart_type (str): ```spam``` to learn spam, ```ham``` to learn nonspam. move_to (str): If not ```None```, the imap folder where the emails will be moved. origpastuids (list(int)): ``uids`` to not process. Returns: Sa_Learn: It contains the information about the result of the process. It will call ``spamc`` to learn the emails. Raises: isbg.ISBGError: if learn_type is unknown. TODO: Add suport to ``learn_type=forget``. """ sa_learning = Sa_Learn() # Sanity checks: if learn_type not in ['spam', 'ham']: raise isbg.ISBGError(-1, message="Unknown learn_type") if self.imap is None: raise isbg.ISBGError(-1, message="Imap is required") self.logger.debug(__( "Teach {} to SA from: {}".format(learn_type, folder))) self.imap.select(folder) if self.learnunflagged: _, uids = self.imap.uid("SEARCH", None, "UNFLAGGED") elif self.learnflagged: _, uids = self.imap.uid("SEARCH", None, "(FLAGGED)") else: _, uids = self.imap.uid("SEARCH", None, "ALL") uids, sa_learning.newpastuids = SpamAssassin.get_formated_uids( uids, origpastuids, self.partialrun) sa_learning.tolearn = len(uids) for uid in uids: mail = imaputils.get_message(self.imap, uid, logger=self.logger) # Unwrap spamassassin reports unwrapped = sa_unwrap.unwrap(mail) if unwrapped is not None: self.logger.debug(__("{} Unwrapped: {}".format( uid, utils.shorten(imaputils.mail_content( unwrapped[0]), 140)))) if unwrapped is not None and unwrapped: # len(unwrapped)>0 mail = unwrapped[0] if self.dryrun: self.logger.warning("Skipped learning due to dryrun!") continue else: code, code_orig = learn_mail(mail, learn_type) if code == -9999: # error processing email, try next. self.logger.exception(__( 'spamc error for mail {}'.format(uid))) self.logger.debug(repr(imaputils.mail_content(mail))) continue if code in [69, 74]: raise isbg.ISBGError( isbg.__exitcodes__['flags'], "spamassassin is misconfigured (use --allow-tell)") if code == 5: # learned. sa_learning.learned += 1 self.logger.debug(__( "Learned {} (spamc return code {})".format(uid, code_orig))) elif code == 6: # already learned. self.logger.debug(__( "Already learned {} (spamc return code {})".format( uid, code_orig))) elif code == 98: # too big. self.logger.warning(__( "{} is too big (spamc return code {})".format( uid, code_orig))) else: raise isbg.ISBGError(-1, ("{}: Unknown return code {} from " + "spamc").format(uid, code_orig)) sa_learning.uids.append(int(uid)) if not self.dryrun: if self.learnthendestroy: if self.gmail: self.imap.uid("COPY", uid, "[Gmail]/Trash") else: self.imap.uid("STORE", uid, self.spamflagscmd, "(\\Deleted)") elif move_to is not None: self.imap.uid("COPY", uid, move_to) elif self.learnthenflag: self.imap.uid("STORE", uid, self.spamflagscmd, "(\\Flagged)") return sa_learning
def test_shorten(): """Test the shorten function.""" # We try with dicts: dic = {1: 'Option 1', 2: u'Option 2', 3: b'Option 3'} assert dic == utils.shorten(dic, 8), "The dicts should be the same." dic2 = utils.shorten(dic, 7) assert dic != dic2, "The dicts should be diferents." # Note: py2 and py3: assert dic2[1] in ['u\'Opti…', '\'Optio…'], "Unexpected shortened string." assert dic2[2] in ['u\'Opti…', '\'Optio…'], "Unexpected shortened string." assert dic2[3] in ['\'Optio…', 'b\'Opti…'], "Unexpected shortened string." # We try with lists: ls = ['Option 1', 'Option 2', 'Option 3'] assert ls == utils.shorten(ls, 8) ls2 = utils.shorten(ls, 7) for k in ls2: assert k in ['u\'Opti…', '\'Optio…'], "Unexpected shortened string." # We try with strings: assert "Option 1" == utils.shorten("Option 1", 8), \ "Strings should be the same." assert utils.shorten("Option 1", 7) in ['u\'Opti…', "\'Optio…"], \ "Strings should be diferents." # Others: with pytest.raises(TypeError, message="None should raise a TypeError."): utils.shorten(None, 8) with pytest.raises(TypeError, message="None should raise a TypeError."): utils.shorten(None, 7) with pytest.raises(TypeError, message="None should raise a TypeError."): utils.shorten(False, 8) with pytest.raises(TypeError, message="None should raise a TypeError."): utils.shorten(True, 7) with pytest.raises(TypeError, message="int should raise a TypeError."): utils.shorten(1, 7) with pytest.raises(TypeError, message="float should raise a TypeError."): utils.shorten(1.0, 7) with pytest.raises(ValueError, message="length should be at least 1."): utils.shorten("123", 0) with pytest.raises(TypeError, message="int should be not supported."): assert utils.shorten([1, 2, 3], 2) assert utils.shorten(["111", "2", "3"], 3) == ["111", "2", "3"] assert utils.shorten(("111", "2", "3"), 3) == ("111", "2", "3")
def learn(self, folder, learn_type, move_to, origpastuids): """Learn the spams (and if requested deleted or move them). Args: folder (str): The IMAP folder. leart_type (str): ```spam``` to learn spam, ```ham``` to learn nonspam. move_to (str): If not ```None```, the imap folder where the emails will be moved. origpastuids (list(int)): ``uids`` to not process. Returns: Sa_Learn: It contains the information about the result of the process. It will call ``spamc`` to learn the emails. Raises: isbg.ISBGError: if learn_type is unknown. TODO: Add suport to ``learn_type=forget``. """ sa_learning = Sa_Learn() # Sanity checks: if learn_type not in ['spam', 'ham']: raise isbg.ISBGError(-1, message="Unknown learn_type") if self.imap is None: raise isbg.ISBGError(-1, message="Imap is required") self.logger.debug( __("Teach {} to SA from: {}".format(learn_type, folder))) self.imap.select(folder) if self.learnunflagged: _, uids = self.imap.uid("SEARCH", None, "UNFLAGGED") elif self.learnflagged: _, uids = self.imap.uid("SEARCH", None, "(FLAGGED)") else: _, uids = self.imap.uid("SEARCH", None, "ALL") uids, sa_learning.newpastuids = SpamAssassin.get_formated_uids( uids, origpastuids, self.partialrun) sa_learning.tolearn = len(uids) for uid in uids: mail = imaputils.get_message(self.imap, uid, logger=self.logger) # Unwrap spamassassin reports unwrapped = sa_unwrap.unwrap(mail) if unwrapped is not None: self.logger.debug( __("{} Unwrapped: {}".format( uid, utils.shorten(imaputils.mail_content(unwrapped[0]), 140)))) if unwrapped is not None and unwrapped: # len(unwrapped)>0 mail = unwrapped[0] if self.dryrun: self.logger.warning("Skipped learning due to dryrun!") continue else: code, code_orig = learn_mail(mail, learn_type) if code == -9999: # error processing email, try next. self.logger.exception(__( 'spamc error for mail {}'.format(uid))) self.logger.debug(repr(imaputils.mail_content(mail))) continue if code in [69, 74]: raise isbg.ISBGError( isbg.__exitcodes__['flags'], "spamassassin is misconfigured (use --allow-tell)") if code == 5: # learned. sa_learning.learned += 1 self.logger.debug( __("Learned {} (spamc return code {})".format( uid, code_orig))) elif code == 6: # already learned. self.logger.debug( __("Already learned {} (spamc return code {})".format( uid, code_orig))) elif code == 98: # too big. self.logger.warning( __("{} is too big (spamc return code {})".format( uid, code_orig))) else: raise isbg.ISBGError(-1, ("{}: Unknown return code {} from " + "spamc").format(uid, code_orig)) sa_learning.uids.append(int(uid)) if not self.dryrun: if self.learnthendestroy: if self.gmail: self.imap.uid("COPY", uid, "[Gmail]/Trash") else: self.imap.uid("STORE", uid, self.spamflagscmd, "(\\Deleted)") elif move_to is not None: self.imap.uid("COPY", uid, move_to) elif self.learnthenflag: self.imap.uid("STORE", uid, self.spamflagscmd, "(\\Flagged)") return sa_learning