103 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			103 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			Go
		
	
	
	
|  | package search | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"mime" | ||
|  | 	"path/filepath" | ||
|  | 	"regexp" | ||
|  | 	"strings" | ||
|  | ) | ||
|  | 
 | ||
|  | var ( | ||
|  | 	typeRegexp = regexp.MustCompile(`type:(\w+)`) | ||
|  | ) | ||
|  | 
 | ||
|  | type condition func(path string) bool | ||
|  | 
 | ||
|  | func extensionCondition(extension string) condition { | ||
|  | 	return func(path string) bool { | ||
|  | 		return filepath.Ext(path) == "."+extension | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | func imageCondition(path string) bool { | ||
|  | 	extension := filepath.Ext(path) | ||
|  | 	mimetype := mime.TypeByExtension(extension) | ||
|  | 
 | ||
|  | 	return strings.HasPrefix(mimetype, "image") | ||
|  | } | ||
|  | 
 | ||
|  | func audioCondition(path string) bool { | ||
|  | 	extension := filepath.Ext(path) | ||
|  | 	mimetype := mime.TypeByExtension(extension) | ||
|  | 
 | ||
|  | 	return strings.HasPrefix(mimetype, "audio") | ||
|  | } | ||
|  | 
 | ||
|  | func videoCondition(path string) bool { | ||
|  | 	extension := filepath.Ext(path) | ||
|  | 	mimetype := mime.TypeByExtension(extension) | ||
|  | 
 | ||
|  | 	return strings.HasPrefix(mimetype, "video") | ||
|  | } | ||
|  | 
 | ||
|  | func parseSearch(value string) *searchOptions { | ||
|  | 	opts := &searchOptions{ | ||
|  | 		CaseSensitive: strings.Contains(value, "case:sensitive"), | ||
|  | 		Conditions:    []condition{}, | ||
|  | 		Terms:         []string{}, | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// removes the options from the value
 | ||
|  | 	value = strings.Replace(value, "case:insensitive", "", -1) | ||
|  | 	value = strings.Replace(value, "case:sensitive", "", -1) | ||
|  | 	value = strings.TrimSpace(value) | ||
|  | 
 | ||
|  | 	types := typeRegexp.FindAllStringSubmatch(value, -1) | ||
|  | 	for _, t := range types { | ||
|  | 		if len(t) == 1 { | ||
|  | 			continue | ||
|  | 		} | ||
|  | 
 | ||
|  | 		switch t[1] { | ||
|  | 		case "image": | ||
|  | 			opts.Conditions = append(opts.Conditions, imageCondition) | ||
|  | 		case "audio", "music": | ||
|  | 			opts.Conditions = append(opts.Conditions, audioCondition) | ||
|  | 		case "video": | ||
|  | 			opts.Conditions = append(opts.Conditions, videoCondition) | ||
|  | 		default: | ||
|  | 			opts.Conditions = append(opts.Conditions, extensionCondition(t[1])) | ||
|  | 		} | ||
|  | 	} | ||
|  | 
 | ||
|  | 	if len(types) > 0 { | ||
|  | 		// Remove the fields from the search value.
 | ||
|  | 		value = typeRegexp.ReplaceAllString(value, "") | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// If it's canse insensitive, put everything in lowercase.
 | ||
|  | 	if !opts.CaseSensitive { | ||
|  | 		value = strings.ToLower(value) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Remove the spaces from the search value.
 | ||
|  | 	value = strings.TrimSpace(value) | ||
|  | 
 | ||
|  | 	if value == "" { | ||
|  | 		return opts | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// if the value starts with " and finishes what that character, we will
 | ||
|  | 	// only search for that term
 | ||
|  | 	if value[0] == '"' && value[len(value)-1] == '"' { | ||
|  | 		unique := strings.TrimPrefix(value, "\"") | ||
|  | 		unique = strings.TrimSuffix(unique, "\"") | ||
|  | 
 | ||
|  | 		opts.Terms = []string{unique} | ||
|  | 		return opts | ||
|  | 	} | ||
|  | 
 | ||
|  | 	opts.Terms = strings.Split(value, " ") | ||
|  | 	return opts | ||
|  | } |