diff --git a/paperless.conf.example b/paperless.conf.example index 15498a26a..dd00a7fb8 100644 --- a/paperless.conf.example +++ b/paperless.conf.example @@ -122,6 +122,14 @@ PAPERLESS_EMAIL_SECRET="" # "true", the document will instead be opened in the browser, if possible. #PAPERLESS_INLINE_DOC="false" +# By default, paperless will check the document text for document date information. +# Uncomment the line below to enable checking the document filename for date +# information. The date order can be set to any option as specified in +# https://dateparser.readthedocs.io/en/latest/#settings. The filename will be +# checked first, and if nothing is found, the document text will be checked +# as normal. +#PAPERLESS_FILENAME_DATE_ORDER="YMD" + # # The following values use sensible defaults for modern systems, but if you're # running Paperless on a low-resource device (like a Raspberry Pi), modifying diff --git a/src/paperless/settings.py b/src/paperless/settings.py index 956b90a7f..fb722bf14 100644 --- a/src/paperless/settings.py +++ b/src/paperless/settings.py @@ -292,3 +292,4 @@ FY_END = os.getenv("PAPERLESS_FINANCIAL_YEAR_END") # Specify the default date order (for autodetected dates) DATE_ORDER = os.getenv("PAPERLESS_DATE_ORDER", "DMY") +FILENAME_DATE_ORDER = os.getenv("PAPERLESS_FILENAME_DATE_ORDER") diff --git a/src/paperless_tesseract/parsers.py b/src/paperless_tesseract/parsers.py index e3c2ed361..d22f1a72b 100644 --- a/src/paperless_tesseract/parsers.py +++ b/src/paperless_tesseract/parsers.py @@ -34,6 +34,7 @@ class RasterisedDocumentParser(DocumentParser): THREADS = int(settings.OCR_THREADS) if settings.OCR_THREADS else None UNPAPER = settings.UNPAPER_BINARY DATE_ORDER = settings.DATE_ORDER + FILENAME_DATE_ORDER = settings.FILENAME_DATE_ORDER DEFAULT_OCR_LANGUAGE = settings.OCR_LANGUAGE OCR_ALWAYS = settings.OCR_ALWAYS @@ -206,7 +207,30 @@ class RasterisedDocumentParser(DocumentParser): date = None datestring = None + if self.FILENAME_DATE_ORDER: + self.log("info", "Checking document title for date") + text = os.path.basename(self.document_path) + for m in re.finditer(DATE_REGEX, text): + datestring = m.group(0) + try: + date = dateparser.parse( + datestring, + settings={'DATE_ORDER': self.FILENAME_DATE_ORDER, + 'PREFER_DAY_OF_MONTH': 'first', + 'RETURN_AS_TIMEZONE_AWARE': True}) + except TypeError: + # Skip all matches that do not parse to a proper date + continue + + if date is not None: + self.log("info", + "Detected document date {} based on string {} " + "from document title" + "".format(date.isoformat(), datestring)) + return date + try: + self.log('info', "Checking document text for date") text = self.get_text() except ParseError as e: return None diff --git a/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.pdf b/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.pdf new file mode 100644 index 000000000..629125956 Binary files /dev/null and b/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.pdf differ diff --git a/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.png b/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.png new file mode 100644 index 000000000..4a7671635 Binary files /dev/null and b/src/paperless_tesseract/tests/samples/2013-12-11_tests_date_in_filename_2.png differ diff --git a/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.pdf b/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.pdf new file mode 100644 index 000000000..629125956 Binary files /dev/null and b/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.pdf differ diff --git a/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.png b/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.png new file mode 100644 index 000000000..4a7671635 Binary files /dev/null and b/src/paperless_tesseract/tests/samples/tests_date_in_filename_2018-03-20_1.png differ diff --git a/src/paperless_tesseract/tests/test_date.py b/src/paperless_tesseract/tests/test_date.py index 096a1c147..7e6129e29 100644 --- a/src/paperless_tesseract/tests/test_date.py +++ b/src/paperless_tesseract/tests/test_date.py @@ -425,4 +425,72 @@ class TestDate(TestCase): datetime.datetime(2017, 12, 31, 0, 0, tzinfo=tz.gettz(settings.TIME_ZONE)) ) + + @mock.patch( + "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", + SCRATCH + ) + def test_filename_date_1_pdf(self): + input_file = os.path.join(self.SAMPLE_FILES, + "tests_date_in_filename_2018-03-20_1.pdf") + document = RasterisedDocumentParser(input_file) + document.FILENAME_DATE_ORDER = 'YMD' + document.get_text() + date = document.get_date() + self.assertEqual(document._is_ocred(), True) + self.assertEqual( + date, + datetime.datetime(2018, 3, 20, 0, 0, + tzinfo=tz.gettz(settings.TIME_ZONE)) + ) + + @mock.patch( + "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", + SCRATCH + ) + def test_filename_date_1_png(self): + input_file = os.path.join(self.SAMPLE_FILES, + "tests_date_in_filename_2018-03-20_1.png") + document = RasterisedDocumentParser(input_file) + document.FILENAME_DATE_ORDER = 'YMD' + date = document.get_date() + self.assertEqual(document._is_ocred(), False) + self.assertEqual( + date, + datetime.datetime(2018, 3, 20, 0, 0, + tzinfo=tz.gettz(settings.TIME_ZONE)) + ) + + @mock.patch( + "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", + SCRATCH + ) + def test_filename_date_2_pdf(self): + input_file = os.path.join(self.SAMPLE_FILES, + "2013-12-11_tests_date_in_filename_2.pdf") + document = RasterisedDocumentParser(input_file) + document.FILENAME_DATE_ORDER = 'YMD' + date = document.get_date() + self.assertEqual(document._is_ocred(), True) + self.assertEqual( + date, + datetime.datetime(2013, 12, 11, 0, 0, + tzinfo=tz.gettz(settings.TIME_ZONE)) + ) + + @mock.patch( + "paperless_tesseract.parsers.RasterisedDocumentParser.SCRATCH", + SCRATCH + ) + def test_filename_date_2_png(self): + input_file = os.path.join(self.SAMPLE_FILES, + "2013-12-11_tests_date_in_filename_2.png") + document = RasterisedDocumentParser(input_file) + document.FILENAME_DATE_ORDER = 'YMD' + date = document.get_date() + self.assertEqual(document._is_ocred(), False) + self.assertEqual( + date, + datetime.datetime(2013, 12, 11, 0, 0, + tzinfo=tz.gettz(settings.TIME_ZONE)) )