def test_auto_remove_empty_tag_dir(self): empty_tag_dir = os.path.join(TEST_INDEX_LOCATION, "tags", "removed tag") cli.run_cmd(["mkdir", "-p", empty_tag_dir]) self.index.update("../res/read_md.jpg") self.assertFalse(os.path.isdir(empty_tag_dir), "empty tag dir was not removed!")
def test_untag(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) self.tie_core.untag(WRITE_FILE_MD, [TEST_READ_TAG_1]) self.assertEqual([TEST_READ_TAG_2.lower()], self.tie_core.list([WRITE_FILE_MD]), "Tags after removing did not match") os.remove(WRITE_FILE_MD)
def test_tag_empty(self): cli.run_cmd(["cp", READ_FILE_NO_EXIF, WRITE_FILE_NO_EXIF]) tag = "foo bar" self.tie_core.tag(WRITE_FILE_NO_EXIF, [tag]) self.assertEqual([tag], self.tie_core.list([WRITE_FILE_NO_EXIF]), "File without exif data not tagged") os.remove(WRITE_FILE_NO_EXIF)
def test_clear_invalid(self): cli.run_cmd(["cp", READ_FILE, WRITE_FILE]) self.tie_core.clear(WRITE_FILE) tags_after_clear = self.tie_core.list([WRITE_FILE]) self.assertEqual([], tags_after_clear, "Tag list was not empty after clearing corrupt file") os.remove(WRITE_FILE)
def test_clear(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) self.tie_core.clear(WRITE_FILE_MD) tags_after_clear = self.tie_core.list([WRITE_FILE_MD]) self.assertEqual([], tags_after_clear, "Tag list was not empty after clear") os.remove(WRITE_FILE_MD)
def _setup_tag_invalid_meta_data_file(confirm_nuke): exif = ExifEditor(Configuration()) index = Index(TEST_INDEX_LOCATION, exif) core = TieCoreImpl(exif, index) cli.run_cmd(["cp", READ_FILE, WRITE_FILE]) frontend = FrontendTest(confirm_nuke, []) tie_main.run(core, RunOptions(["tag", "foo", WRITE_FILE]), frontend)
def test_list_all_tags(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) self.tie_core.update_index(WRITE_FILE_MD) tags = self.tie_core.list_all_tags() self.assertEqual( sorted([TEST_READ_TAG_1.lower(), TEST_READ_TAG_2.lower()]), sorted(tags)) os.remove(WRITE_FILE_MD)
def _prepare_vanished_file(self, path: str, tag_name: str) -> str: img = os.path.abspath(path) linkname = _path_to_linkname(img) tag_dir = os.path.join(TEST_INDEX_LOCATION, "tags", tag_name) link_path = os.path.join(tag_dir, linkname) cli.run_cmd(["mkdir", "-p", tag_dir]) cli.run_cmd(["ln", "-sf", img, link_path]) return link_path
def test_list_tags(self): cli.run_cmd( ["mkdir", "-p", os.path.join(TEST_INDEX_LOCATION, "tags", "foo")]) cli.run_cmd( ["mkdir", "-p", os.path.join(TEST_INDEX_LOCATION, "tags", "bar")]) tags = self.index.list_tags() self.assertEqual(["bar", "foo"], tags, "tags list incorrect")
def test_update_file_invalid_md(self): img = os.path.abspath("../res/read.jpg") linkname = _path_to_linkname(img) removed_tag_dir = os.path.join(TEST_INDEX_LOCATION, "tags", "removed tag") link_path = os.path.join(removed_tag_dir, linkname) cli.run_cmd(["mkdir", "-p", removed_tag_dir]) cli.run_cmd(["ln", "-sf", img, link_path]) self.index.update("../res/read.jpg") self.assertFalse(os.path.islink(link_path), "tag was not removed!")
def test_read_long_meta_data(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) long_data = '{"tags": ["whatever", "words", "something", "this-is-long", "we-need-more-tags", "foobar", "lets", "see", "if", "this", "works"], "ver": 1}' with open(WRITE_FILE_MD, 'rb') as f: self.ee._write_exif_field("Exif.Photo.UserComment", long_data, WRITE_FILE_MD) written_md = self.ee.get_meta_data(WRITE_FILE_MD) self.assertEqual([ "whatever", "words", "something", "this-is-long", "we-need-more-tags", "foobar", "lets", "see", "if", "this", "works" ], written_md.tags) os.remove(WRITE_FILE_MD)
def test_write_raw(self): cli.run_cmd(["cp", READ_FILE, WRITE_FILE]) with open(WRITE_FILE, 'rb') as f: md5_pre = hashlib.md5(f.read()).hexdigest() self.assertEqual("c14f5570050e188e897c4f1d030edff5", md5_pre) self.ee._write_exif_field("Exif.Photo.UserComment", "My Dummy Value öä ' \" ", WRITE_FILE) with open(WRITE_FILE, 'rb') as f: md5_post = hashlib.md5(f.read()).hexdigest() self.assertEqual("828d89558f1053c20daef859ce5f4634", md5_post) os.remove(WRITE_FILE)
def test_removed_tag(self): img = os.path.abspath("../res/read_md.jpg") linkname = _path_to_linkname(img) removed_tag_dir = os.path.join(TEST_INDEX_LOCATION, "tags", "removed tag") link_path = os.path.join(removed_tag_dir, linkname) cli.run_cmd(["mkdir", "-p", removed_tag_dir]) cli.run_cmd(["ln", "-sf", img, link_path]) self.index.update("../res/read_md.jpg") self.assertFalse(os.path.islink(link_path), "tag was not removed!") # Execute again to test if this (incorrectly) raises a FileNotFoundError self.index.update("../res/read_md.jpg")
def test_tag_duplicate(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) added_tag1 = "New tag Ä" self.tie_core.tag(WRITE_FILE_MD, [added_tag1, added_tag1, TEST_READ_TAG_1]) self.assertEqual( sorted([ TEST_READ_TAG_1.lower(), TEST_READ_TAG_2.lower(), added_tag1.lower() ]), self.tie_core.list([WRITE_FILE_MD]), "Tags after duplicate adding did not match") os.remove(WRITE_FILE_MD)
def test_write_md(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) with open(WRITE_FILE_MD, 'rb') as f: md5_pre = hashlib.md5(f.read()).hexdigest() self.assertEqual("1daf4da69916978e5799fb446694549f", md5_pre) self.ee.set_meta_data( WRITE_FILE_MD, md.MetaData([TEST_WRITE_TAG_1, TEST_WRITE_TAG_2], "42")) with open(WRITE_FILE_MD, 'rb') as f: md5_post = hashlib.md5(f.read()).hexdigest() self.assertEqual("b2867d616bea116475c251d8be728825", md5_post) os.remove(WRITE_FILE_MD)
def _prepare_query_test(self): cli.run_cmd(["cp", READ_FILE_MD, QUERY_FILE_1]) cli.run_cmd(["cp", READ_FILE_MD, QUERY_FILE_2]) cli.run_cmd(["cp", READ_FILE_MD, QUERY_FILE_3]) cli.run_cmd(["cp", READ_FILE_MD, QUERY_FILE_4]) self.exif.set_meta_data(QUERY_FILE_1, md.MetaData([QUERY_TAG_1, QUERY_TAG_2])) self.exif.set_meta_data(QUERY_FILE_2, md.MetaData([QUERY_TAG_2, QUERY_TAG_3])) self.exif.set_meta_data(QUERY_FILE_3, md.MetaData([QUERY_TAG_3, QUERY_TAG_4])) self.exif.set_meta_data(QUERY_FILE_4, md.MetaData([QUERY_TAG_4])) self.index.update(QUERY_FILE_1) self.index.update(QUERY_FILE_2) self.index.update(QUERY_FILE_3) self.index.update(QUERY_FILE_4)
def test_unfollowed_symlinks_corrected(self): link_name_right = self.files_base_path + ":recursive.d:level1:read_md.jpg" link_name_wrong = self.files_base_path + ":recursive.d:level1_symlinked:read_md.jpg" cli.run_cmd([ "mkdir", "-p", os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_1.lower()) ]) cli.run_cmd([ "mkdir", "-p", os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_2.lower()) ]) cli.run_cmd([ "ln", "-sf", "../res/recursive.d/level1_symlinked/read_md.jpg", os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_1.lower(), link_name_wrong) ]) cli.run_cmd([ "ln", "-sf", "../res/recursive.d/level1_symlinked/read_md.jpg", os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_2.lower(), link_name_wrong) ]) self.index.update("../res/recursive.d/level1_symlinked/read_md.jpg") self.assertTrue( os.path.islink( os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_1.lower(), link_name_right)), "no link in tagdir 1") self.assertTrue( os.path.islink( os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_2.lower(), link_name_right)), "no link in tagdir 2") self.assertFalse( os.path.islink( os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_1.lower(), link_name_wrong)), "wrong link in tagdir 1") self.assertFalse( os.path.islink( os.path.join(TEST_INDEX_LOCATION, "tags", TEST_READ_TAG_2.lower(), link_name_wrong)), "wrong link in tagdir 2")
def _remove_index(): cli.run_cmd(["rm", "-rf", TEST_INDEX_LOCATION])
def _read_exif_field(self, field_name: str, path: str) -> str: base = self._build_exiv_base_command() command = self._build_exiv_read_command(base, field_name, path) std_out_lines = cli.run_cmd(command, EXIV2_WARN_ERROR_CODE) return " ".join(std_out_lines[0].split()[3:])
def _write_exif_field(self, field_name: str, value: str, path: str): base = self._build_exiv_base_command() command = self._build_exiv_write_command(base, field_name, value, path) cli.run_cmd(command)
def test_err(self): self.assertRaises(CalledProcessError, lambda: cli.run_cmd(["cat", "../res/fooba.txt"]))
def test_cat(self): lines = cli.run_cmd(["cat", "../res/foobar.txt"]) self.assertEqual(lines[0], "foo") self.assertEqual(lines[1], "bar")
def test_list_empty_md(self): cli.run_cmd(["cp", READ_FILE_MD, WRITE_FILE_MD]) self.tie_core.clear(WRITE_FILE_MD) tags = self.tie_core.list([WRITE_FILE_MD]) self.assertEqual([], tags, "listed tags do not match empty list") os.remove(WRITE_FILE_MD)
def _create_test_link(): cli.run_cmd(["ln", "-sf", FOOBAR_TXT, LINK_FOOBAR])
def _create_broken_test_link(): cli.run_cmd(["ln", "-sf", "/non/existant/file", LINK_FOOBAR])
def _remove_test_link(): cli.run_cmd(["rm", "-f", LINK_FOOBAR])
def _create_test_link_to_dir(): cli.run_cmd(["mkdir", "-p", FOOBAR_DIR]) cli.run_cmd(["ln", "-sf", FOOBAR_DIR, LINK_FOOBAR_DIR])
def test_list_empty_raw(self): cli.run_cmd(["cp", READ_FILE, WRITE_FILE]) self.exif._write_exif_field("Exif.Photo.UserComment", "", WRITE_FILE) tags = self.tie_core.list([WRITE_FILE]) self.assertEqual([], tags, "listed tags do not match empty list") os.remove(WRITE_FILE)
def ln(destination: str, link_name: str): # "os.symlink(source, destination)" does not provide a race-free way to force the symlink creation cli.run_cmd(["ln", "-sf", destination, link_name])