コード例 #1
0
ファイル: rename.go プロジェクト: peer23peer/TMSU
func renameTag(store *storage.Storage, tx *storage.Tx, currentName, newName string) error {
	sourceTag, err := store.TagByName(tx, currentName)
	if err != nil {
		return fmt.Errorf("could not retrieve tag '%v': %v", currentName, err)
	}
	if sourceTag == nil {
		return fmt.Errorf("no such tag '%v'", currentName)
	}

	destTag, err := store.TagByName(tx, newName)
	if err != nil {
		return fmt.Errorf("could not retrieve tag '%v': %v", newName, err)
	}
	if destTag != nil {
		return fmt.Errorf("tag '%v' already exists", newName)
	}

	log.Infof(2, "renaming tag '%v' to '%v'.", currentName, newName)

	_, err = store.RenameTag(tx, sourceTag.Id, newName)
	if err != nil {
		return fmt.Errorf("could not rename tag '%v' to '%v': %v", currentName, newName, err)
	}

	return nil
}
コード例 #2
0
ファイル: values.go プロジェクト: peer23peer/TMSU
func listValuesForTag(store *storage.Storage, tx *storage.Tx, tagName string, showCount, onePerLine bool) error {
	tag, err := store.TagByName(tx, tagName)
	if err != nil {
		return fmt.Errorf("could not retrieve tag '%v': %v", tagName, err)
	}
	if tag == nil {
		return fmt.Errorf("no such tag, '%v'", tagName)
	}

	log.Infof(2, "retrieving values for tag '%v'.", tagName)

	values, err := store.ValuesByTag(tx, tag.Id)
	if err != nil {
		return fmt.Errorf("could not retrieve values for tag '%v': %v", tagName, err)
	}

	if showCount {
		fmt.Println(len(values))
	} else {
		if onePerLine {
			for _, value := range values {
				fmt.Println(escape(value.Name, '=', ' '))
			}
		} else {
			valueNames := make([]string, len(values))
			for index, value := range values {
				valueNames[index] = escape(value.Name, '=', ' ')
			}

			terminal.PrintColumns(valueNames)
		}
	}

	return nil
}
コード例 #3
0
ファイル: imply.go プロジェクト: logtcn/TMSU
func deleteImplications(store *storage.Storage, tx *storage.Tx, tagArgs []string) (error, warnings) {
	log.Infof(2, "loading settings")

	implyingTagArg := tagArgs[0]
	impliedTagArgs := tagArgs[1:]

	implyingTagName, implyingValueName := parseTagEqValueName(implyingTagArg)

	implyingTag, err := store.TagByName(tx, implyingTagName)
	if err != nil {
		return err, nil
	}
	if implyingTag == nil {
		return NoSuchTagError{implyingTagName}, nil
	}

	implyingValue, err := store.ValueByName(tx, implyingValueName)
	if err != nil {
		return err, nil
	}
	if implyingValue == nil {
		return NoSuchValueError{implyingValueName}, nil
	}

	warnings := make(warnings, 0, 10)
	for _, impliedTagArg := range impliedTagArgs {
		log.Infof(2, "removing tag implication %v -> %v.", implyingTagArg, impliedTagArg)

		impliedTagName, impliedValueName := parseTagEqValueName(impliedTagArg)

		impliedTag, err := store.TagByName(tx, impliedTagName)
		if err != nil {
			return err, warnings
		}
		if impliedTag == nil {
			warnings = append(warnings, fmt.Sprintf("no such tag '%v'", impliedTagName))
		}

		impliedValue, err := store.ValueByName(tx, impliedValueName)
		if err != nil {
			return err, warnings
		}
		if impliedValue == nil {
			warnings = append(warnings, fmt.Sprintf("no such value '%v'", impliedValueName))
		}

		if err := store.DeleteImplication(tx, entities.TagIdValueIdPair{implyingTag.Id, implyingValue.Id}, entities.TagIdValueIdPair{impliedTag.Id, impliedValue.Id}); err != nil {
			return fmt.Errorf("could not delete tag implication of %v to %v: %v", implyingTagArg, impliedTagArg, err), warnings
		}
	}

	return nil, warnings
}
コード例 #4
0
ファイル: merge.go プロジェクト: logtcn/TMSU
func mergeTags(store *storage.Storage, tx *storage.Tx, sourceTagNames []string, destTagName string) (error, warnings) {
	destTag, err := store.TagByName(tx, destTagName)
	if err != nil {
		return fmt.Errorf("could not retrieve tag '%v': %v", destTagName, err), nil
	}
	if destTag == nil {
		return fmt.Errorf("no such tag '%v'", destTagName), nil
	}

	warnings := make(warnings, 0, 10)
	for _, sourceTagName := range sourceTagNames {
		if sourceTagName == destTagName {
			warnings = append(warnings, fmt.Sprintf("cannot merge tag '%v' into itself", sourceTagName))
			continue
		}

		sourceTag, err := store.TagByName(tx, sourceTagName)
		if err != nil {
			return fmt.Errorf("could not retrieve tag '%v': %v", sourceTagName, err), warnings
		}
		if sourceTag == nil {
			warnings = append(warnings, fmt.Sprintf("no such tag '%v'", sourceTagName))
			continue
		}

		log.Infof(2, "finding files tagged '%v'.", sourceTagName)

		fileTags, err := store.FileTagsByTagId(tx, sourceTag.Id, true)
		if err != nil {
			return fmt.Errorf("could not retrieve files for tag '%v': %v", sourceTagName, err), warnings
		}

		log.Infof(2, "applying tag '%v' to these files.", destTagName)

		for _, fileTag := range fileTags {
			if _, err = store.AddFileTag(tx, fileTag.FileId, destTag.Id, fileTag.ValueId); err != nil {
				return fmt.Errorf("could not apply tag '%v' to file #%v: %v", destTagName, fileTag.FileId, err), warnings
			}
		}

		log.Infof(2, "deleting tag '%v'.", sourceTagName)

		if err = store.DeleteTag(tx, sourceTag.Id); err != nil {
			return fmt.Errorf("could not delete tag '%v': %v", sourceTagName, err), warnings
		}
	}

	return nil, warnings
}
コード例 #5
0
ファイル: values.go プロジェクト: peer23peer/TMSU
func listValuesForTags(store *storage.Storage, tx *storage.Tx, tagNames []string, showCount, onePerLine bool) (error, warnings) {
	warnings := make(warnings, 0, 10)

	for _, tagName := range tagNames {
		tag, err := store.TagByName(tx, tagName)
		if err != nil {
			return fmt.Errorf("could not retrieve tag '%v': %v", tagName, err), warnings
		}
		if tag == nil {
			warnings = append(warnings, fmt.Sprintf("no such tag, '%v'.", tagName))
			continue
		}

		log.Infof(2, "retrieving values for tag '%v'.", tagName)

		values, err := store.ValuesByTag(tx, tag.Id)
		if err != nil {
			return fmt.Errorf("could not retrieve values for tag '%v': %v", tagName, err), warnings
		}

		if showCount {
			fmt.Printf("%v: %v\n", tagName, len(values))
		} else {
			if onePerLine {
				fmt.Println(tagName)
				for _, value := range values {
					fmt.Println(escape(value.Name, '=', ' '))
				}
				fmt.Println()
			} else {
				valueNames := make([]string, len(values))
				for index, value := range values {
					valueNames[index] = escape(value.Name, '=', ' ')
				}

				fmt.Printf("%v: %v\n", tagName, strings.Join(valueNames, " "))
			}
		}
	}

	return nil, warnings
}
コード例 #6
0
ファイル: tag.go プロジェクト: logtcn/TMSU
func createTagsValues(store *storage.Storage, tx *storage.Tx, tagArgs []string) (error, warnings) {
	warnings := make(warnings, 0, 10)

	for _, tagArg := range tagArgs {
		name := parseTagOrValueName(tagArg)

		if name[0] == '=' {
			name = name[1:]

			value, err := store.ValueByName(tx, name)
			if err != nil {
				return fmt.Errorf("could not check if value '%v' exists: %v", name, err), warnings
			}

			if value == nil {
				if _, err := store.AddValue(tx, name); err != nil {
					return fmt.Errorf("could not create value '%v': %v", name, err), warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("value '%v' already exists", name))
			}
		} else {
			tag, err := store.TagByName(tx, name)
			if err != nil {
				return fmt.Errorf("could not check if tag '%v' exists: %v", name, err), warnings
			}

			if tag == nil {
				if _, err := store.AddTag(tx, name); err != nil {
					return fmt.Errorf("could not create tag '%v': %v", name, err), warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("tag '%v' already exists", name))
			}
		}
	}

	return nil, warnings
}
コード例 #7
0
ファイル: delete.go プロジェクト: logtcn/TMSU
func deleteTag(store *storage.Storage, tx *storage.Tx, tagArgs []string) (error, warnings) {
	warnings := make(warnings, 0, 10)

	for _, tagArg := range tagArgs {
		tagName := parseTagOrValueName(tagArg)

		tag, err := store.TagByName(tx, tagName)
		if err != nil {
			return fmt.Errorf("could not retrieve tag '%v': %v", tagName, err), warnings
		}
		if tag == nil {
			warnings = append(warnings, fmt.Sprintf("no such tag '%v'", tagName))
			continue
		}

		err = store.DeleteTag(tx, tag.Id)
		if err != nil {
			return fmt.Errorf("could not delete tag '%v': %v", tagName, err), warnings
		}
	}

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

	settings, err := store.Settings(tx)
	if err != nil {
		return err, nil
	}

	pairs := make(entities.TagIdValueIdPairs, 0, len(tagArgs))
	warnings := make(warnings, 0, 10)

	for _, tagArg := range tagArgs {
		tagName, valueName := parseTagEqValueName(tagArg)

		tag, err := store.TagByName(tx, tagName)
		if err != nil {
			return err, warnings
		}
		if tag == nil {
			if settings.AutoCreateTags() {
				tag, err = createTag(store, tx, tagName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such tag '%v'", tagName))
				continue
			}
		}

		value, err := store.ValueByName(tx, valueName)
		if err != nil {
			return err, warnings
		}
		if value == nil {
			if settings.AutoCreateValues() {
				value, err = createValue(store, tx, valueName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such value '%v'", valueName))
				continue
			}
		}

		pairs = append(pairs, entities.TagIdValueIdPair{tag.Id, value.Id})
	}

	for _, path := range paths {
		if err := tagPath(store, tx, path, pairs, explicit, recursive, force, 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
}
コード例 #9
0
ファイル: untag.go プロジェクト: peer23peer/TMSU
func untagPaths(store *storage.Storage, tx *storage.Tx, paths, tagArgs []string, recursive, followSymlinks bool) (error, warnings) {
	warnings := make(warnings, 0, 10)

	files := make(entities.Files, 0, len(paths))
	for _, path := range paths {
		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("%v: could not get absolute path: %v", path, err), warnings
		}

		log.Infof(2, "%v: resolving path", path)

		stat, err := os.Lstat(absPath)
		if err != nil {
			switch {
			case os.IsNotExist(err), os.IsPermission(err):
				// ignore
			default:
				return err, nil
			}
		} else if stat.Mode()&os.ModeSymlink != 0 && followSymlinks {
			absPath, err = _path.Dereference(absPath)
			if err != nil {
				return err, nil
			}
		}

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

		files = append(files, file)

		if recursive {
			childFiles, err := store.FilesByDirectory(tx, file.Path())
			if err != nil {
				return fmt.Errorf("%v: could not retrieve files for directory: %v", file.Path()), warnings
			}

			files = append(files, childFiles...)
		}
	}

	for _, tagArg := range tagArgs {
		tagName, valueName := parseTagEqValueName(tagArg)

		tag, err := store.TagByName(tx, tagName)
		if err != nil {
			return fmt.Errorf("could not retrieve tag '%v': %v", tagName, err), warnings
		}
		if tag == nil {
			warnings = append(warnings, fmt.Sprintf("no such tag '%v'", tagName))
			continue
		}

		value, err := store.ValueByName(tx, valueName)
		if err != nil {
			return fmt.Errorf("could not retrieve value '%v': %v", valueName, err), warnings
		}
		if value == nil {
			warnings = append(warnings, fmt.Sprintf("no such value '%v'", valueName))
			continue
		}

		for _, file := range files {
			if err := store.DeleteFileTag(tx, file.Id, tag.Id, value.Id); err != nil {
				switch err.(type) {
				case storage.FileTagDoesNotExist:
					exists, err := store.FileTagExists(tx, file.Id, tag.Id, value.Id, false)
					if err != nil {
						return fmt.Errorf("could not check if tag exists: %v", err), warnings
					}

					if exists {
						if value.Id != 0 {
							warnings = append(warnings, fmt.Sprintf("%v: cannot remove '%v=%v': delete implication  to remove this tag.", file.Path(), tag.Name, value.Name))
						} else {
							warnings = append(warnings, fmt.Sprintf("%v: cannot remove '%v': delete implication to remove this tag.", file.Path(), tag.Name))
						}
					} else {
						if value.Id != 0 {
							warnings = append(warnings, fmt.Sprintf("%v: file is not tagged '%v=%v'.", file.Path(), tag.Name, value.Name))
						} else {
							warnings = append(warnings, fmt.Sprintf("%v: file is not tagged '%v'.", file.Path(), tag.Name))
						}
					}
				default:
					return fmt.Errorf("%v: could not remove tag '%v', value '%v': %v", file.Path(), tag.Name, value.Name, err), warnings
				}
			}
		}
	}

	return nil, warnings
}
コード例 #10
0
ファイル: imply.go プロジェクト: logtcn/TMSU
func addImplications(store *storage.Storage, tx *storage.Tx, tagArgs []string) (error, warnings) {
	log.Infof(2, "loading settings")

	settings, err := store.Settings(tx)
	if err != nil {
		return err, nil
	}

	implyingTagArg := tagArgs[0]
	impliedTagArgs := tagArgs[1:]

	implyingTagName, implyingValueName := parseTagEqValueName(implyingTagArg)

	implyingTag, err := store.TagByName(tx, implyingTagName)
	if err != nil {
		return err, nil
	}
	if implyingTag == nil {
		if settings.AutoCreateTags() {
			implyingTag, err = createTag(store, tx, implyingTagName)
			if err != nil {
				return err, nil
			}
		} else {
			return NoSuchTagError{implyingTagName}, nil
		}
	}

	implyingValue, err := store.ValueByName(tx, implyingValueName)
	if err != nil {
		return err, nil
	}
	if implyingValue == nil {
		if settings.AutoCreateValues() {
			implyingValue, err = createValue(store, tx, implyingValueName)
			if err != nil {
				return err, nil
			}
		} else {
			return NoSuchValueError{implyingValueName}, nil
		}
	}

	warnings := make(warnings, 0, 10)
	for _, impliedTagArg := range impliedTagArgs {
		impliedTagName, impliedValueName := parseTagEqValueName(impliedTagArg)

		impliedTag, err := store.TagByName(tx, impliedTagName)
		if err != nil {
			return err, warnings
		}
		if impliedTag == nil {
			if settings.AutoCreateTags() {
				impliedTag, err = createTag(store, tx, impliedTagName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such tag '%v'", impliedTagName))
				continue
			}
		}

		impliedValue, err := store.ValueByName(tx, impliedValueName)
		if err != nil {
			return err, warnings
		}
		if impliedValue == nil {
			if settings.AutoCreateValues() {
				impliedValue, err = createValue(store, tx, impliedValueName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such value '%v'", impliedValueName))
				continue
			}
		}

		log.Infof(2, "adding tag implication of '%v' to '%v'", implyingTagArg, impliedTagArg)

		if err = store.AddImplication(tx, entities.TagIdValueIdPair{implyingTag.Id, implyingValue.Id}, entities.TagIdValueIdPair{impliedTag.Id, impliedValue.Id}); err != nil {
			return fmt.Errorf("cannot add implication of '%v' to '%v': %v", implyingTagArg, impliedTagArg, err), warnings
		}
	}

	return nil, warnings
}