def test_read_after_write_or_tag(tempdir): '''Read after write or tag''' path = os.path.join(tempdir, 'thing1') fsfs.write(path, key='value') assert fsfs.read(path) == {'key': 'value'} path = os.path.join(tempdir, 'thing2') fsfs.tag(path, 'thingy') assert fsfs.read(path) == {}
def create(self, name=None, sequences=8, shots=20, assets=20): '''This actually uses fsfs to create a project''' name = self.project(name) path = self.project_path(name) fsfs.tag(path, 'project') seq_names = [] for seq_name in sample(self.sequences, sequences): seq_name = self.sequence(seq_name) seq_names.append(seq_name) seq_path = self.sequence_path(project=name, sequence=seq_name) fsfs.tag(seq_path, 'sequence') for i in range(shots): shot_name = self.shot(i) shot_path = self.shot_path( project=name, sequence=seq_name, shot=shot_name ) fsfs.tag(shot_path, 'shot') perms = [ zip(asset, self.variants) for asset in itertools.permutations( self.assets, len(self.variants) ) ] variants = [a + '_' + b for (a, b) in itertools.chain(*perms)] assets = max([len(assets), len(variants)]) asset_names = sample(variants, assets) for asset_name in asset_names: asset_path = self.asset_path(project=name, asset=asset_name) fsfs.tag(asset_path, 'asset')
def test_tag(tempdir): '''Tag and untag''' fake = ProjectFaker(root=tempdir) asset_path = fake.asset_path() tag_path = fsfs.make_tag_path(asset_path, 'asset') # fresh tag fsfs.tag(asset_path, 'asset') assert os.path.isfile(tag_path) # tag already exists, should do nothing fsfs.tag(asset_path, 'asset') assert os.path.isfile(tag_path) # remove tag, tag should be gone, data root should still be there fsfs.untag(asset_path, 'asset') assert not os.path.isfile(tag_path) assert os.path.isdir(os.path.join(asset_path, fsfs.get_data_root()))
def test_search_up(tempdir): '''Search up''' fake = ProjectFaker(root=tempdir) project = fake.project() project_path = fake.project_path(project=project) fsfs.tag(project_path, 'project') sequence = fake.sequence() sequence_path = fake.sequence_path(project=project, sequence=sequence) fsfs.tag(sequence_path, 'sequence') shot = fake.shot() shot_path = fake.shot_path(project=project, sequence=sequence, shot=shot) fsfs.tag(shot_path, 'shot') full_search = fsfs.search(shot_path, direction=fsfs.UP) results = list(full_search) assert len(results) == 3 assert results[0].name == shot assert results[1].name == sequence assert results[2].name == project project_result = fsfs.search(shot_path, fsfs.UP).tags('project').one() assert project_result.name == project assert samefile(project_result.path, project_path) no_result = fsfs.search(shot_path, fsfs.UP).tags('unused').one() assert no_result is None
def test_read_write(tempdir): '''Entry read and write.''' fake = ProjectFaker(root=tempdir) project_path = fake.project_path() fsfs.tag(project_path, 'project') # First read will be empty project_data = fsfs.read(project_path) assert project_data == {} # Write updates the cached data and mtime in EntryData # This should prevent subsequent reads from unnecessarily accessing disk fsfs.write(project_path, hello='world!') # ids are the same because we haven't read from disk assert fsfs.read(project_path) is project_data assert project_data == {'hello': 'world!'} # Write another key fsfs.write(project_path, integer=10) # Still receiving cached data on read assert fsfs.read(project_path) is project_data assert project_data == {'hello': 'world!', 'integer': 10} # If keys are included in read, we return a new dict with only those keys assert fsfs.read(project_path, 'integer') is not project_data # External data change causes mtime to change entry = fsfs.get_entry(project_path) time.sleep(0.1) with open(entry.data.file, 'w') as f: data = dict(hello='wurld!') f.write(json.dumps(data)) # Now ids are different, because our cached mtime is < the mtime on disk # causing read to return a new dict assert fsfs.read(project_path) is not project_data
def test_search_down(tempdir): '''Search down''' fake = ProjectFaker(root=tempdir) project = fake.project() project_path = fake.project_path(project=project) fsfs.tag(project_path, 'project') sequence1 = fake.sequence() sequence1_path = fake.sequence_path(project=project, sequence=sequence1) fsfs.tag(sequence1_path, 'sequence') sequence2 = fake.sequence() sequence2_path = fake.sequence_path(project=project, sequence=sequence2) fsfs.tag(sequence2_path, 'sequence') assets = sample(fake.assets, 10) hero = assets[0] hero_path = fake.asset_path(project=project, asset=hero) fsfs.tag(hero_path, 'asset', 'hero') for asset in assets[1:]: path = fake.asset_path(project=project, asset=asset) fsfs.tag(path, 'asset') for sequence in (sequence1, sequence2): for i in sample(range(99), 10): shot = fake.shot(i) path = fake.shot_path( project=project, sequence=sequence, shot=shot ) fsfs.tag(path, 'shot') full_search = fsfs.search(project_path) results = list(full_search) assert len(results) == 33 first_result = fsfs.search(project_path).one() assert first_result.name == project assert samefile(first_result.path, project_path) assert 'project' in first_result.tags asset_search = fsfs.search(project_path).tags('asset') assert len(list(asset_search)) == 10 hero_search = fsfs.search(project_path).tags('asset', 'hero') hero_result = list(hero_search) assert len(hero_result) == 1 assert hero_result[0].name == hero assert samefile(hero_result[0].path, hero_path) assert ['asset', 'hero'] == hero_result[0].tags
def run(self, args, *extra_args): import fsfs fsfs.tag(args.root, *args.tags)
def tag(root, tags): '''Tag a directory''' fsfs.tag(root, *tags)