def test_safe_path_long_file_name_invalid(tmp_path): """Test that SafePath raises ValueError if path is too long but cannot be trimmed""" test_dir = tmp_path / "test" bad_file_name = "X" + "." + "x" * MAX_FILE_NAME_LEN safe_path = SafePath(test_dir) with pytest.raises(ValueError): safe_path.get_file("test1", bad_file_name)
def test_safe_path_dir(tmp_path): test_dir = tmp_path / "test" expected_dir = tmp_path / "test" / "test1" / "test2" safe_path = SafePath(str(test_dir)) result_dir = safe_path.get("test1", "test2") assert expected_dir.is_dir() assert result_dir == str(expected_dir)
def test_safe_path_dir_existing_overwrite(tmp_path): test_dir = tmp_path / "test" existing_dir = tmp_path / "test" / "test1" / "test2" existing_dir.mkdir(parents=True) safe_path = SafePath(test_dir, overwrite=True) result_dir = safe_path.get("test1", "test2") assert result_dir == existing_dir
def test_safe_path_file(tmp_path): test_dir = tmp_path / "test" expected_file = tmp_path / "test" / "test1" / "test2" / "test3.txt" safe_path = SafePath(test_dir) result_file_path = safe_path.get_file("test1", "test2", "test3.txt") assert expected_file.parent.is_dir() assert not expected_file.exists() assert result_file_path == expected_file
def test_safe_path_file(tmp_path): test_dir = tmp_path / "test" expected_file = tmp_path / "test" / "test1" / "test2" / "test3.txt" safe_path = SafePath(str(test_dir)) result_file_path = safe_path.get_file("test1", "test2", "test3.txt") expected_file.touch() assert expected_file.is_file() assert result_file_path == str(expected_file)
def test_safe_path_file_existing_overwrite(tmp_path): test_dir = tmp_path / "test" existing_file = tmp_path / "test" / "test1" / "test2" / "test3.txt" existing_file.parent.mkdir(parents=True) existing_file.touch() safe_path = SafePath(test_dir, overwrite=True) result_file_path = safe_path.get_file("test1", "test2", "test3.txt") assert result_file_path == existing_file
def test_safe_path_dir_existing(tmp_path): test_dir = tmp_path / "test" existing_dir = tmp_path / "test" / "test1" / "test2" existing_dir.mkdir(parents=True) expected_dir = tmp_path / "test" / "test1" / "test2 (1)" safe_path = SafePath(test_dir) result_dir = safe_path.get("test1", "test2") assert expected_dir.is_dir() assert result_dir == expected_dir
def test_safe_path_no_trim(tmp_path): """Test that the SafePath does not trim the path if the path is not too long""" test_dir = tmp_path / "test" max_file_name = "X" * 251 + ".ext" expected_file_name = max_file_name expected_file = tmp_path / "test" / "test1" / expected_file_name safe_path = SafePath(test_dir) result_file_path = safe_path.get_file("test1", max_file_name) expected_file.touch() assert expected_file.is_file() assert result_file_path == expected_file
def test_safe_path_bad_names(tmp_path): test_dir = tmp_path / "test" expected_dir1 = tmp_path / "test" / "test1" / "test2_" expected_dir2 = tmp_path / "test" / "test1" / "test2_ (1)" safe_path = SafePath(str(test_dir)) result_path1 = safe_path.get("test1", "test2|") result_path2 = safe_path.get("test1", "test2?") assert expected_dir1.is_dir() assert result_path1 == str(expected_dir1) assert expected_dir2.is_dir() assert result_path2 == str(expected_dir2)
def test_safe_path_bad_names(tmp_path): test_dir = tmp_path / "test" expected_dir1 = tmp_path / "test" / "test1" / "test2_________" expected_dir2 = tmp_path / "test" / "test1" / "test2_________ (1)" safe_path = SafePath(test_dir) result_path1 = safe_path.get("test1", r'test2<>:"/\|?*') result_path2 = safe_path.get("test1", r'test2/\|?*<>:"') assert expected_dir1.is_dir() assert result_path1 == expected_dir1 assert expected_dir2.is_dir() assert result_path2 == expected_dir2
def __init__( self, storage: SqliteStorage, target_dir: Path, single_notes: bool, export_trash: bool, no_export_date: bool, overwrite: bool, ) -> None: self.storage = storage self.safe_paths = SafePath(target_dir, overwrite) self.single_notes = single_notes self.export_trash = export_trash self.no_export_date = no_export_date
def test_safe_path_file_existing(tmp_path): test_dir = tmp_path / "test" existing_file = tmp_path / "test" / "test1" / "test2" / "test3.txt" existing_file.parent.mkdir(parents=True) existing_file.touch() expected_file = tmp_path / "test" / "test1" / "test2" / "test3 (1).txt" safe_path = SafePath(test_dir) result_file_path = safe_path.get_file("test1", "test2", "test3.txt") assert expected_file.parent.is_dir() assert not expected_file.exists() assert result_file_path == expected_file
def test_safe_path_long_file_name(tmp_path): """Test that SafePath trims a long file name with extension""" test_dir = tmp_path / "test" test_ext = ".ext" long_file_name = "X" * MAX_FILE_NAME_LEN + test_ext expected_file_name = "X" * (MAX_FILE_NAME_LEN - len(test_ext)) + test_ext expected_file = tmp_path / "test" / "test1" / expected_file_name safe_path = SafePath(test_dir) result_file_path = safe_path.get_file("test1", long_file_name) expected_file.touch() assert expected_file.is_file() assert result_file_path == expected_file
def test_safe_path_long_file_name_no_ext(tmp_path): """Test that SafePath trims a long file name with no extension""" test_dir = tmp_path / "test" slightly_longer_than_supported = MAX_FILE_NAME_LEN + 10 long_file_name = "X" * slightly_longer_than_supported expected_file_name = "X" * MAX_FILE_NAME_LEN expected_file = tmp_path / "test" / "test1" / expected_file_name safe_path = SafePath(test_dir) result_file_path = safe_path.get_file("test1", long_file_name) expected_file.touch() assert expected_file.is_file() assert result_file_path == expected_file
def test_safe_path_long_file_name_existing(tmp_path): """Test that SafePath trims an existing long file name with extension""" test_dir = tmp_path / "test" test_ext = ".ext" long_file_name = "X" * (MAX_FILE_NAME_LEN - len(test_ext)) + test_ext long_file = tmp_path / "test" / long_file_name expected_file_name = ( "X" * (MAX_FILE_NAME_LEN - len(test_ext) - 4) + " (1)" + test_ext ) expected_file = tmp_path / "test" / expected_file_name long_file.parent.mkdir(parents=True) long_file.touch() safe_path = SafePath(test_dir) result_file_path = safe_path.get_file(long_file_name) expected_file.touch() assert expected_file.is_file() assert result_file_path == expected_file
def __init__(self, storage: SqliteStorage, target_dir: str) -> None: self.storage = storage self.safe_paths = SafePath(target_dir)
class NoteExporter(object): def __init__(self, storage: SqliteStorage, target_dir: str) -> None: self.storage = storage self.safe_paths = SafePath(target_dir) def export_notebooks(self, single_notes: bool, export_trash: bool) -> None: count_notes = self.storage.notes.get_notes_count() count_trash = self.storage.notes.get_notes_count(is_active=False) if logger.getEffectiveLevel() == logging.DEBUG: # pragma: no cover logger.debug(f"Notes to export: {count_notes}") logger.debug(f"Trashed notes: {count_trash}") if single_notes: logger.debug("Export mode: single notes") else: logger.debug("Export mode: notebooks") if count_notes == 0 and count_trash == 0: raise NothingToExportError if count_notes > 0: logger.info("Exporting notes...") self._export_active(single_notes) if count_trash > 0 and export_trash: logger.info("Exporting trash...") self._export_trash(single_notes) def _export_active(self, single_notes: bool) -> None: notebooks = tuple(self.storage.notebooks.iter_notebooks()) with progressbar( notebooks, item_show_func=lambda x: str(x.name) if x else "", show_pos=True, file=get_progress_output(), ) as notebooks_bar: for nb in notebooks_bar: if logger.getEffectiveLevel( ) == logging.DEBUG: # pragma: no cover nb_info = log_format_notebook(nb) logger.debug(f"Exporting notebook {nb_info}") if self.storage.notebooks.get_notebook_notes_count( nb.guid) == 0: logger.debug("Notebook is empty, skip") continue self._export_notes(nb, single_notes) def _export_notes(self, notebook: Notebook, single_notes: bool) -> None: parent_dir = [notebook.stack] if notebook.stack else [] notes_source = self.storage.notes.iter_notes(notebook.guid) if single_notes: parent_dir.append(notebook.name) self._output_single_notes(parent_dir, notes_source) else: self._output_notebook(parent_dir, notebook.name, notes_source) def _export_trash(self, single_notes: bool) -> None: notes_source = self.storage.notes.iter_notes_trash() if single_notes: self._output_single_notes(["Trash"], notes_source) else: self._output_notebook([], "Trash", notes_source) def _output_single_notes( self, parent_dir: List[str], notes_source: Iterable[Note], ) -> None: for note in notes_source: note_path = self.safe_paths.get_file(*parent_dir, f"{note.title}.enex") _write_export_file(note_path, note) def _output_notebook( self, parent_dir: List[str], notebook_name: str, notes_source: Iterable[Note], ) -> None: notebook_path = self.safe_paths.get_file(*parent_dir, f"{notebook_name}.enex") _write_export_file(notebook_path, notes_source)