def test_filepath_no_date(self): importer = mock.MagicMock(wraps=self.importer) importer.date.return_value = None with mock.patch('beangulp.archive.utils.getmdate', return_value=datetime.datetime.fromtimestamp( 0, datetime.timezone.utc)): filepath = archive.filepath(importer, path.abspath('test.pdf')) self.assertEqual(filepath, 'Assets/Tests/1970-01-01.test.pdf')
def test_filepath_date_in_name(self): importer = mock.MagicMock(wraps=self.importer) importer.filename.return_value = '1970-01-03.name.pdf' with self.assertRaises(exceptions.Error) as ex: filepath = archive.filepath(importer, path.abspath('test.pdf')) self.assertRegex(ex.exception.message, r'contains [\w\s]+ date')
def test_filepath_sep_in_name(self): importer = mock.MagicMock(wraps=self.importer) importer.filename.return_value = f'dir{os.sep:}name.pdf' with self.assertRaises(exceptions.Error) as ex: filepath = archive.filepath(importer, path.abspath('test.pdf')) self.assertRegex(ex.exception.message, r'contains path separator')
def test_filepath_no_filename(self): filepath = archive.filepath(self.importer, path.abspath('test.pdf')) self.assertEqual(filepath, 'Assets/Tests/1970-01-01.test.pdf')
def test_filepath(self): importer = mock.MagicMock(wraps=self.importer) importer.filename.return_value = 'foo.csv' filepath = archive.filepath(importer, path.abspath('test.pdf')) self.assertEqual(filepath, 'Assets/Tests/1970-01-01.foo.csv')
def _archive(ctx, src, destination, dry_run, overwrite, failfast): """Archive documents. Walk the SRC list of files or directories and move each file identified by one of the configured importers in a directory hierarchy mirroring the structure of the accounts associated to the documents and with a file name composed by the document date and document name returned by the importer. Documents are moved to their filing location only when no errors are encountered processing all the input files. Documents in the destination directory are not overwritten, unless the --force option is used. When the directory hierarchy root is not specified with the --destination DIR options, it is assumed to be directory in which the ingest script is located. """ # If the output directory is not specified, move the files at the # root where the import script is located. Providing this default # seems better than using a required option. if destination is None: import __main__ destination = os.path.dirname(os.path.abspath(__main__.__file__)) log = utils.logger() errors = exceptions.ExceptionsTrap(log) renames = [] for filename in _walk(src, log): with errors: importer = identify.identify(ctx.importers, filename) if not importer: log('') # Newline. continue # Signal processing of this document. log(' ...', nl=False) destpath = archive.filepath(importer, filename) # Prepend destination directory path. destpath = os.path.join(destination, destpath) # Check for destination filename collisions. collisions = [src for src, dst in renames if dst == destpath] if collisions: raise exceptions.Error('Collision in destination file path.', destpath) # Check if the destination file already exists. if not overwrite and os.path.exists(destpath): raise exceptions.Error('Destination file already exists.', destpath) renames.append((filename, destpath)) log(' OK', fg='green') log(f' {destpath:}') if failfast and errors: break # If there are any errors, stop here. if errors: log('# Errors detected: documents will not be filed.') sys.exit(1) if not dry_run: for src, dst in renames: archive.move(src, dst)
def test_filepath_no_date(self): importer = mock.MagicMock(wraps=self.importer) importer.date.return_value = None with mock.patch('os.path.getmtime', return_value=86401): filepath = archive.filepath(importer, path.abspath('test.pdf')) self.assertEqual(filepath, 'Assets/Tests/1970-01-02.test.pdf')