示例#1
0
文件: tag.go 项目: logtcn/TMSU
func tagPath(store *storage.Storage, tx *storage.Tx, path string, pairs []entities.TagIdValueIdPair, explicit, recursive, force bool, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg string, reportDuplicates bool) error {
	absPath, err := filepath.Abs(path)
	if err != nil {
		return fmt.Errorf("%v: could not get absolute path: %v", path, err)
	}

	stat, err := os.Stat(path)
	if err != nil {
		switch {
		case os.IsNotExist(err), os.IsPermission(err):
			if !force {
				return err
			} else {
				stat = emptyStat{}
			}
		default:
			return err
		}
	}

	log.Infof(2, "%v: checking if file exists in database", path)

	file, err := store.FileByPath(tx, absPath)
	if err != nil {
		return fmt.Errorf("%v: could not retrieve file: %v", path, err)
	}
	if file == nil {
		log.Infof(2, "%v: creating fingerprint", path)

		fp, err := fingerprint.Create(path, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg)
		if err != nil {
			if !force || !(os.IsNotExist(err) || os.IsPermission(err)) {
				return fmt.Errorf("%v: could not create fingerprint: %v", path, err)
			}
		}

		if fp != fingerprint.Empty && reportDuplicates {
			log.Infof(2, "%v: checking for duplicates", path)

			count, err := store.FileCountByFingerprint(tx, fp)
			if err != nil {
				return fmt.Errorf("%v: could not identify duplicates: %v", path, err)
			}
			if count != 0 {
				log.Warnf("'%v' is a duplicate", path)
			}
		}

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

		file, err = store.AddFile(tx, path, fp, stat.ModTime(), int64(stat.Size()), stat.IsDir())
		if err != nil {
			return fmt.Errorf("%v: could not add file to database: %v", path, err)
		}
	}

	if !explicit {
		pairs, err = removeAlreadyAppliedTagValuePairs(store, tx, pairs, file)
		if err != nil {
			return fmt.Errorf("%v: could not remove applied tags: %v", path, err)
		}
	}

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

	for _, pair := range pairs {
		if _, err = store.AddFileTag(tx, file.Id, pair.TagId, pair.ValueId); err != nil {
			return fmt.Errorf("%v: could not apply tags: %v", file.Path(), err)
		}
	}

	if recursive && stat.IsDir() {
		if err = tagRecursively(store, tx, path, pairs, explicit, force, fileFingerprintAlg, dirFingerprintAlg, symlinkFingerprintAlg, reportDuplicates); err != nil {
			return err
		}
	}

	return nil
}