def test_clone(self): ' Test cloning of containers ' for fmt in ('epub', 'azw3'): base = os.path.join(self.tdir, fmt + '-') book = get_simple_book(fmt) tdir = base + 'first' os.mkdir(tdir) c1 = get_container(book, tdir=tdir) tdir = base + 'second' os.mkdir(tdir) c2 = clone_container(c1, tdir) for c in (c1, c2): for name, path in iteritems(c.name_path_map): self.assertEqual(2, nlinks_file(path), 'The file %s is not linked' % name) for name in c1.name_path_map: self.assertIn(name, c2.name_path_map) self.assertEqual( c1.open(name).read(), c2.open(name).read(), 'The file %s differs' % name) spine_names = tuple(x[0] for x in c1.spine_names) text = spine_names[0] root = c2.parsed(text) root.xpath('//*[local-name()="body"]')[0].set( 'id', 'changed id for test') c2.dirty(text) c2.commit_item(text) for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[text])) self.assertNotEqual(c1.open(text).read(), c2.open(text).read()) name = spine_names[1] with c1.open(name, mode='r+b') as f: f.seek(0, 2) f.write(b' ') for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[name])) self.assertNotEqual(c1.open(name).read(), c2.open(name).read()) x = base + 'out.' + fmt for c in (c1, c2): c.commit(outpath=x)
def test_clone(self): ' Test cloning of containers ' for fmt in ('epub', 'azw3'): base = os.path.join(self.tdir, fmt + '-') book = get_simple_book(fmt) tdir = base + 'first' os.mkdir(tdir) c1 = get_container(book, tdir=tdir) tdir = base + 'second' os.mkdir(tdir) c2 = clone_container(c1, tdir) for c in (c1, c2): for name, path in c.name_path_map.iteritems(): self.assertEqual(2, nlinks_file(path), 'The file %s is not linked' % name) for name in c1.name_path_map: self.assertIn(name, c2.name_path_map) self.assertEqual(c1.open(name).read(), c2.open(name).read(), 'The file %s differs' % name) spine_names = tuple(x[0] for x in c1.spine_names) text = spine_names[0] root = c2.parsed(text) root.xpath('//*[local-name()="body"]')[0].set('id', 'changed id for test') c2.dirty(text) c2.commit_item(text) for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[text])) self.assertNotEqual(c1.open(text).read(), c2.open(text).read()) name = spine_names[1] with c1.open(name, mode='r+b') as f: f.seek(0, 2) f.write(b' ') for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[name])) self.assertNotEqual(c1.open(name).read(), c2.open(name).read()) x = base + 'out.' + fmt for c in (c1, c2): c.commit(outpath=x)
def test_clone(self): " Test cloning of containers " for fmt in ("epub", "azw3"): base = os.path.join(self.tdir, fmt + "-") book = get_simple_book(fmt) tdir = base + "first" os.mkdir(tdir) c1 = get_container(book, tdir=tdir) tdir = base + "second" os.mkdir(tdir) c2 = clone_container(c1, tdir) for c in (c1, c2): for name, path in c.name_path_map.iteritems(): self.assertEqual(2, nlinks_file(path), "The file %s is not linked" % name) for name in c1.name_path_map: self.assertIn(name, c2.name_path_map) self.assertEqual(c1.open(name).read(), c2.open(name).read(), "The file %s differs" % name) spine_names = tuple(x[0] for x in c1.spine_names) text = spine_names[0] root = c2.parsed(text) root.xpath('//*[local-name()="body"]')[0].set("id", "changed id for test") c2.dirty(text) c2.commit_item(text) for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[text])) self.assertNotEqual(c1.open(text).read(), c2.open(text).read()) name = spine_names[1] with c1.open(name, mode="r+b") as f: f.seek(0, 2) f.write(b" ") for c in (c1, c2): self.assertEqual(1, nlinks_file(c.name_path_map[name])) self.assertNotEqual(c1.open(name).read(), c2.open(name).read()) x = base + "out." + fmt for c in (c1, c2): c.commit(outpath=x)
def commit_item(self, name, keep_parsed=False): if name not in self.parsed_cache: return data = self.serialize_item(name) self.dirtied.discard(name) if not keep_parsed: self.parsed_cache.pop(name) dest = self.name_path_map[name] if self.cloned and nlinks_file(dest) > 1: # Decouple this file from its links os.unlink(dest) with open(dest, 'wb') as f: f.write(data)
def open(self, name, mode='rb'): ''' Open the file pointed to by name for direct read/write. Note that this will commit the file if it is dirtied and remove it from the parse cache. You must finish with this file before accessing the parsed version of it again, or bad things will happen. ''' if name in self.dirtied: self.commit_item(name) self.parsed_cache.pop(name, False) path = self.name_to_abspath(name) base = os.path.dirname(path) if not os.path.exists(base): os.makedirs(base) else: if self.cloned and mode not in {'r', 'rb'} and os.path.exists(path) and nlinks_file(path) > 1: # Decouple this file from its links temp = path + 'xxx' shutil.copyfile(path, temp) os.unlink(path) os.rename(temp, path) return open(path, mode)