Compare commits
6 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8b3bb961a9 | ||
|
|
c08860d7fd | ||
|
|
69840e05db | ||
|
|
26a167c4d7 | ||
|
|
2c6f7ecb50 | ||
|
|
9b9f772944 |
6 changed files with 78 additions and 14 deletions
10
CHANGES.rst
10
CHANGES.rst
|
|
@ -2,11 +2,17 @@ ChangeLog
|
|||
=========
|
||||
|
||||
|
||||
`2.1.0 (2017-01-13) <https://github.com/kdeldycke/maildir-deduplicate/compare/v2.0.1...v2.1.0>`_
|
||||
------------------------------------------------------------------------------------------------
|
||||
`2.1.1 (unreleased) <https://github.com/kdeldycke/maildir-deduplicate/compare/v2.1.0...develop>`_
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
.. note:: This version is not yet released and is under active development.
|
||||
|
||||
* No changes yet.
|
||||
|
||||
|
||||
`2.1.0 (2017-01-13) <https://github.com/kdeldycke/maildir-deduplicate/compare/v2.0.1...v2.1.0>`_
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
* Fix rendering of changelog link in RST.
|
||||
* Show selected log level in debug mode.
|
||||
* Test builds against Python 3.6 and 3.7-dev, and most recent PyPy targetting
|
||||
|
|
|
|||
19
README.rst
19
README.rst
|
|
@ -42,3 +42,22 @@ Features
|
|||
* Dry-run mode.
|
||||
* Protection against false-positives by checking for size and content
|
||||
differences.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
This package is `available on PyPi
|
||||
<https://pypi.python.org/pypi/maildir-deduplicate>`_, so you can install the
|
||||
latest stable release and its dependencies with a simple ``pip`` call:
|
||||
|
||||
.. code-block:: shell-session
|
||||
|
||||
$ pip install maildir-deduplicate
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
Docs are `hosted on Read the Docs
|
||||
<https://maildir-deduplicate.readthedocs.io>`_.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import logging
|
|||
import sys
|
||||
|
||||
|
||||
__version__ = '2.1.0'
|
||||
__version__ = '2.1.1'
|
||||
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
|
|
|
|||
|
|
@ -78,8 +78,12 @@ class Mail(object):
|
|||
return os.path.getctime(self.path)
|
||||
|
||||
# Fetch from the date header.
|
||||
return email.utils.mktime_tz(email.utils.parsedate_tz(
|
||||
self.message.get('Date')))
|
||||
value = self.message.get('Date')
|
||||
try:
|
||||
value = email.utils.mktime_tz(email.utils.parsedate_tz(value))
|
||||
except ValueError:
|
||||
pass
|
||||
return value
|
||||
|
||||
@cachedproperty
|
||||
def size(self):
|
||||
|
|
@ -221,14 +225,10 @@ class Mail(object):
|
|||
parsed = email.utils.parsedate_tz(value)
|
||||
if not parsed:
|
||||
raise TypeError
|
||||
# If parsedate_tz cannot parse the date.
|
||||
except (TypeError, ValueError):
|
||||
return value
|
||||
utc_timestamp = email.utils.mktime_tz(parsed)
|
||||
try:
|
||||
utc_timestamp = email.utils.mktime_tz(parsed)
|
||||
return time.strftime(
|
||||
'%Y/%m/%d UTC', time.gmtime(utc_timestamp))
|
||||
except ValueError:
|
||||
except (TypeError, ValueError):
|
||||
return value
|
||||
elif header == 'to':
|
||||
# Sometimes email.parser strips the <> brackets from a To:
|
||||
|
|
|
|||
|
|
@ -51,7 +51,8 @@ class MailFactory(object):
|
|||
# Defaults fields values.
|
||||
self.fields = {
|
||||
'body': "Да, они летят.",
|
||||
'date': arrow.utcnow()}
|
||||
'date': arrow.utcnow(),
|
||||
'raw_date': None}
|
||||
|
||||
# Check all custom fields are recognized and supported.
|
||||
assert set(custom_fields).issubset(self.fields)
|
||||
|
|
@ -64,7 +65,7 @@ class MailFactory(object):
|
|||
self.fields.update(custom_fields)
|
||||
|
||||
# Add an extra rendered string in RFC2882 format.
|
||||
self.fields['date_rfc2822'] = maildate(
|
||||
self.fields['date_rfc2822'] = self.fields['raw_date'] or maildate(
|
||||
self.fields['date'].float_timestamp)
|
||||
|
||||
def render(self):
|
||||
|
|
@ -297,6 +298,8 @@ class TestDateStrategy(TestDeduplicate):
|
|||
newer_mail = MailFactory(date=newer_date)
|
||||
older_mail = MailFactory(date=older_date)
|
||||
oldest_mail = MailFactory(date=oldest_date)
|
||||
baddate_mail = MailFactory(raw_date="Thu, 13 Dec 101 15:30 WET")
|
||||
baddate2_mail = MailFactory(raw_date="Thu, 13 Dec 102 15:30 WET")
|
||||
|
||||
mails = {
|
||||
'mail0:1,S': oldest_mail,
|
||||
|
|
@ -411,3 +414,39 @@ class TestDateStrategy(TestDeduplicate):
|
|||
for mail_id in deleted:
|
||||
self.assertFalse(path.isfile(path.join(
|
||||
self.maildir_path, 'cur', mail_id)))
|
||||
|
||||
def test_noncompliant_dates(self):
|
||||
""" Test that noncompliant date headers (e.g., in year 101) don't fail """
|
||||
with self.runner.isolated_filesystem():
|
||||
mails = {
|
||||
'mail0:1,S': self.baddate_mail,
|
||||
'mail1:2,S': self.baddate2_mail,
|
||||
}
|
||||
self.fake_maildir(
|
||||
mails=mails,
|
||||
md_path=self.maildir_path)
|
||||
|
||||
# Older mails are kept but not the newest ones.
|
||||
kept = [ 'mail0:1,S' ]
|
||||
deleted = [ 'mail1:2,S' ]
|
||||
|
||||
assert(set(kept + deleted) == set(mails))
|
||||
|
||||
for mail_id in mails.keys():
|
||||
self.assertTrue(path.isfile(path.join(
|
||||
self.maildir_path, 'cur', mail_id)), "exists %s" % mail_id)
|
||||
|
||||
result = self.invoke(
|
||||
'deduplicate', '--time-source=date-header',
|
||||
'--strategy=delete-newest', self.maildir_path)
|
||||
|
||||
# there is presently an assertion failure in 'report' that prevents exiting with success
|
||||
#self.assertEqual(result.exit_code, 0)
|
||||
|
||||
for mail_id in kept:
|
||||
fn = path.join(self.maildir_path, 'cur', mail_id)
|
||||
print(locals())
|
||||
self.assertTrue(path.isfile(fn), "{} exists".format(fn))
|
||||
for mail_id in deleted:
|
||||
fn = path.join(self.maildir_path, 'cur', mail_id)
|
||||
self.assertFalse(path.isfile(fn), "{} deleted".format(fn))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ universal = 1
|
|||
|
||||
# https://github.com/peritus/bumpversion#configuration
|
||||
[bumpversion]
|
||||
current_version = 2.1.0
|
||||
current_version = 2.1.1
|
||||
files = ./maildir_deduplicate/__init__.py ./CHANGES.rst
|
||||
allow_dirty = True
|
||||
commit = False
|
||||
|
|
|
|||
Loading…
Reference in a new issue