コード例 #1
0
ファイル: tag.go プロジェクト: peer23peer/TMSU
func tagFrom(store *storage.Storage, tx *storage.Tx, fromPath string, paths []string, explicit, recursive, force, followSymlinks bool) (error, warnings) {
	log.Infof(2, "loading settings")

	settings, err := store.Settings(tx)
	if err != nil {
		return fmt.Errorf("could not retrieve settings: %v", err), nil
	}

	stat, err := os.Lstat(fromPath)
	if err != nil {
		return err, nil
	}
	if stat.Mode()&os.ModeSymlink != 0 && followSymlinks {
		fromPath, err = _path.Dereference(fromPath)
		if err != nil {
			return err, nil
		}
	}

	file, err := store.FileByPath(tx, fromPath)
	if err != nil {
		return fmt.Errorf("%v: could not retrieve file: %v", fromPath, err), nil
	}
	if file == nil {
		return fmt.Errorf("%v: path is not tagged", fromPath), nil
	}

	fileTags, err := store.FileTagsByFileId(tx, file.Id, true)
	if err != nil {
		return fmt.Errorf("%v: could not retrieve filetags: %v", fromPath, err), nil
	}

	pairs := make([]entities.TagIdValueIdPair, len(fileTags))
	for index, fileTag := range fileTags {
		pairs[index] = entities.TagIdValueIdPair{fileTag.TagId, fileTag.ValueId}
	}

	warnings := make(warnings, 0, 10)

	for _, path := range paths {
		if err := tagPath(store, tx, path, pairs, explicit, recursive, force, followSymlinks, settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm(), settings.ReportDuplicates()); err != nil {
			switch {
			case os.IsPermission(err):
				warnings = append(warnings, fmt.Sprintf("%v: permisison denied", path))
			case os.IsNotExist(err):
				warnings = append(warnings, fmt.Sprintf("%v: no such file", path))
			default:
				return fmt.Errorf("%v: could not stat file: %v", path, err), warnings
			}
		}
	}

	return nil, warnings
}
コード例 #2
0
ファイル: tags.go プロジェクト: logtcn/TMSU
func tagNamesForFile(store *storage.Storage, tx *storage.Tx, fileId entities.FileId, explicitOnly, colour bool) ([]string, error) {
	fileTags, err := store.FileTagsByFileId(tx, fileId, explicitOnly)
	if err != nil {
		return nil, fmt.Errorf("could not retrieve file-tags for file '%v': %v", fileId, err)
	}

	taggings := make([]string, len(fileTags))

	for index, fileTag := range fileTags {
		tag, err := store.Tag(tx, fileTag.TagId)
		if err != nil {
			return nil, fmt.Errorf("could not lookup tag: %v", err)
		}
		if tag == nil {
			return nil, fmt.Errorf("tag '%v' does not exist", fileTag.TagId)
		}

		var tagging string
		if fileTag.ValueId == 0 {
			tagging = formatTagValueName(tag.Name, "", colour, fileTag.Implicit, fileTag.Explicit)
		} else {
			value, err := store.Value(tx, fileTag.ValueId)
			if err != nil {
				return nil, fmt.Errorf("could not lookup value: %v", err)
			}
			if value == nil {
				return nil, fmt.Errorf("value '%v' does not exist", fileTag.ValueId)
			}

			tagging = formatTagValueName(tag.Name, value.Name, colour, fileTag.Implicit, fileTag.Explicit)
		}

		taggings[index] = tagging
	}

	ansi.Sort(taggings)

	return taggings, nil
}
コード例 #3
0
ファイル: repair.go プロジェクト: logtcn/TMSU
func rationalizeFileTags(store *storage.Storage, tx *storage.Tx, files entities.Files) error {
	log.Infof(2, "rationalizing file tags")

	for _, file := range files {
		fileTags, err := store.FileTagsByFileId(tx, file.Id, false)
		if err != nil {
			return fmt.Errorf("could not determine tags for file '%v': %v", file.Path(), err)
		}

		for _, fileTag := range fileTags {
			if fileTag.Implicit && fileTag.Explicit {
				log.Infof(2, "%v: removing explicit tagging %v as implicit tagging exists", file.Path(), fileTag.TagId)

				if err := store.DeleteFileTag(tx, fileTag.FileId, fileTag.TagId, fileTag.ValueId); err != nil {
					return fmt.Errorf("could not delete file tag for file %v, tag %v and value %v", fileTag.FileId, fileTag.TagId, fileTag.ValueId)
				}
			}
		}
	}

	return nil
}
コード例 #4
0
ファイル: tag.go プロジェクト: logtcn/TMSU
func removeAlreadyAppliedTagValuePairs(store *storage.Storage, tx *storage.Tx, pairs []entities.TagIdValueIdPair, file *entities.File) ([]entities.TagIdValueIdPair, error) {
	log.Infof(2, "%v: determining existing file-tags", file.Path())

	existingFileTags, err := store.FileTagsByFileId(tx, file.Id, false)
	if err != nil {
		return nil, fmt.Errorf("%v: could not determine file's tags: %v", file.Path(), err)
	}

	log.Infof(2, "%v: determining implied tags", file.Path())

	newImplications, err := store.ImplicationsFor(tx, pairs...)
	if err != nil {
		return nil, fmt.Errorf("%v: could not determine implied tags: %v", file.Path(), err)
	}

	log.Infof(2, "%v: revising set of tags to apply", file.Path())

	revisedPairs := make([]entities.TagIdValueIdPair, 0, len(pairs))
	for _, pair := range pairs {
		predicate := func(ft entities.FileTag) bool {
			return ft.TagId == pair.TagId && ft.ValueId == pair.ValueId
		}

		if existingFileTags.Any(predicate) {
			continue
		}

		if newImplications.Implies(pair) {
			continue
		}

		revisedPairs = append(revisedPairs, pair)
	}

	return revisedPairs, nil
}