def set(self, path, values): tags = self.make_tags_obj(path) log_info(u'set: values=%s', unicode(values)) self.inject(tags, values) log_info(u'set: tags=%s', unicode(dict(tags))) tags.save() return values.keys()
def get_value_from_tag(cls, field, tag): if not isinstance(tag, (list, tuple)): log_info( (u'_BaseMutagenMetaStore.get_value_from_tag: ' u'tag value is not a list, dropping: %r, %r'), field, tag, ) raise ValueError(tag) return list(tag)
def get_value_from_tag(cls, field, tag): if not isinstance(tag, (list, tuple)): log_info( ( u'_BaseMutagenMetaStore.get_value_from_tag: ' u'tag value is not a list, dropping: %r, %r' ), field, tag, ) raise ValueError(tag) return list(tag)
def add_directory(self, fake_path): self.validate_fake_path(fake_path) parts = split_path(fake_path) len_parts = len(parts) if len_parts >= len(self.substitution_patterns): log_error( 'add_directory: too many directories: %r', fake_path, ) raise InvalidArgument splitters = self._create_splitters(fake_path, {}) splitter = splitters[-1] try: splitter.split(parts[-1]) except PatternError, e: log_info(u'add_directory: %s', e) raise InvalidArgument
def disable_profiling(): log_info('disabling profiling') global _profiling_enabled _profiling_enabled = False
def enable_profiling(): log_info('enabling profiling; times are in ms') global _profiling_enabled _profiling_enabled = True
def rename_path(self, old_fake_path, new_fake_path): self.validate_fake_path(old_fake_path) self.validate_fake_path(new_fake_path) log_info( u'SourceTreeRepresentation.rename_path: renaming %s to %s', old_fake_path, new_fake_path, ) old_path_parts = split_path(old_fake_path) new_path_parts = split_path(new_fake_path) if len(old_path_parts) != len(new_path_parts): log_error( (u'rename_path: old path and new path have ' u'differing directory depths: %s, %s'), old_fake_path, new_fake_path, ) raise InvalidArgument # Find the index of the path segment that changed: for index, (old_path_part, new_path_part) in enumerate( zip(old_path_parts, new_path_parts)): if old_path_part != new_path_part: break old_node_path = join_path_abs(old_path_parts[:index + 1]) # Here's our approach: # 1. Separate the affected end points into files and directories. # 2. For each directory end point, remove the old directory and add the # new one. # 3. For each file end point: # a. We know which path segment changed, so we can use that # information to get old tag values for that segment and new tag # values for that segment. These values represent the total tag # change for that particular end point. # b. Group the values by real path and then combine each group. # c. For each affected real path, use Values.diff3 to calculate a # final values delta and apply it to the real path. end_points = self.path_store.get_end_points(old_fake_path) file_end_points = [] directory_end_points = [] for end_point in end_points: if self.is_file(end_point): file_end_points.append(end_point) else: directory_end_points.append(end_point) del end_points # Handle directory end points: for end_point in directory_end_points: self.remove_directory(end_point) end_point_parts = split_path(end_point) end_point_parts[index] = new_path_parts[index] self.add_directory_with_parents(join_path_abs(end_point_parts)) del directory_end_points # Get old values, new values for each file end point: old_values_by_end_point = {} new_values_by_end_point = {} for end_point in file_end_points: meta_data = self.path_store.get_meta_data(end_point) end_point_splitters = meta_data['splitters'] splitter = end_point_splitters[index] old_values = Values.from_flat_dict(splitter.split(old_path_part)) try: new_values = Values.from_flat_dict( splitter.split(new_path_part)) except PatternError, e: log_error(u'rename_path: %s', e) raise InvalidArgument old_values_by_end_point[end_point] = old_values new_values_by_end_point[end_point] = new_values
def add_source_file(self, real_path): ''' Add source file ``real_path`` to the source tree representation. Do nothing if: * The file does not exist. * The target file is a directory. ''' # We want to filter out unreadable files and symlinks. These checks # are racey, of course. A symlink could be removed and replaced with # a real file immediately after our check. Likewise, a file that is # unreadable because of permissions could have its mode changed. # However, in either of these cases a new source tree monitor event # will be received and another attempt to add the source file will # be made. Thus, there is no serious consequence. # Note that if all MetaStore implementations pulled metadata from file # contents, the isreadable check would be unnecessary. But some # (PathMetaStore, for instance) do not read the source file to obtain # metadata. # Also note that if we handled symlinks correctly everywhere (in # getattr, populate, and in SourceTreeMonitor implementations), the # issymlink check could be dropped. Since we don't currently handle # them correctly, though, it is best to simply ignore them. if not self.source_tree.isreadable(real_path): log_debug( u'add_source_file: not readable, not adding: %s', real_path, ) return if self.source_tree.issymlink(real_path): log_debug( u'add_source_file: not adding symlink: %s', real_path, ) return # We only remove the existing entry if it is a file. An existing entry # that is a directory likely indicates a more serious problem. That # should give us a traceback. try: self.remove_source_file(real_path) except PathNotFound: pass values = self.meta_store.get(real_path) fake_paths = [] splitter_groups = [] for substitutions in values.iter_permutations(): try: fake_path = self.fill_path(substitutions) except UnrepresentablePath, e: log_info(u'Unrepresentable file: %s', real_path) log_info(unicode(e)) return if fake_path not in fake_paths: fake_paths.append(fake_path) splitters = self._create_splitters(fake_path, substitutions) splitter_groups.append(splitters)
def populate(self): log_info('populating source tree representation...') self.add_source_dir(self.source_tree.root)