Files
Ant-Browser/backend/internal/launchcode/selector_match.go
T
ant-black 70132417ad publish: 1.2.0 snapshot (f3d7ec5)
channel: master

version: 1.2.0

source-ref: D:\code\open_source\ant-chrome master

source-commit: f3d7ec5

merged-public-base: 3d264eb
2026-05-05 18:08:10 +08:00

150 lines
4.0 KiB
Go

package launchcode
import (
"ant-chrome/backend/internal/browser"
"net/http"
"sort"
"strings"
)
func (s *LaunchServer) findProfilesBySelector(selector LaunchSelector) ([]browser.Profile, int, string) {
if selector.IsEmpty() {
return nil, http.StatusBadRequest, "selector is required"
}
if err := selector.Validate(); err != nil {
return nil, http.StatusBadRequest, err.Error()
}
if s.browserMgr == nil {
return nil, http.StatusInternalServerError, "advanced profile selector is not available"
}
snapshots := s.profileSnapshots()
if len(snapshots) == 0 {
return nil, http.StatusNotFound, "profile selector matched no instance"
}
if selector.Code != "" {
profileID, err := s.service.Resolve(selector.Code)
if err != nil {
return nil, http.StatusNotFound, "launch code not found"
}
filtered := make([]browser.Profile, 0, 1)
for _, item := range snapshots {
if item.ProfileId == profileID {
filtered = append(filtered, item)
break
}
}
snapshots = filtered
}
if selector.ProfileID != "" {
snapshots = filterProfiles(snapshots, func(item browser.Profile) bool {
return item.ProfileId == selector.ProfileID
})
}
if selector.ProfileName != "" {
snapshots = filterProfiles(snapshots, func(item browser.Profile) bool {
return strings.EqualFold(strings.TrimSpace(item.ProfileName), selector.ProfileName)
})
}
if selector.GroupID != "" {
snapshots = filterProfiles(snapshots, func(item browser.Profile) bool {
return strings.TrimSpace(item.GroupId) == selector.GroupID
})
}
if len(selector.Tags) > 0 {
snapshots = filterProfiles(snapshots, func(item browser.Profile) bool {
return profileHasAllTags(item, selector.Tags)
})
}
fuzzyQueries := selector.Keywords
if selector.Key != "" {
exactMatches := filterProfiles(snapshots, func(item browser.Profile) bool {
return profileHasExactKeyword(item, selector.Key)
})
if len(exactMatches) > 0 {
snapshots = exactMatches
} else {
fuzzyQueries = normalizeSelectorTerms(append([]string{selector.Key}, fuzzyQueries...))
}
}
if len(fuzzyQueries) > 0 {
snapshots = filterProfiles(snapshots, func(item browser.Profile) bool {
return profileMatchesAllKeywordQueries(item, fuzzyQueries)
})
}
if len(snapshots) == 0 {
if selector.OnlyCode() {
return nil, http.StatusNotFound, "launch code not found"
}
return nil, http.StatusNotFound, "profile selector matched no instance"
}
sortProfilesForSelector(snapshots)
return snapshots, http.StatusOK, ""
}
func (s *LaunchServer) findProfileBySelector(selector LaunchSelector) (browser.Profile, int, string) {
snapshots, status, errMsg := s.findProfilesBySelector(selector)
if errMsg != "" {
return browser.Profile{}, status, errMsg
}
if len(snapshots) > 1 && selector.MatchMode != launchMatchModeFirst {
return browser.Profile{}, http.StatusConflict, buildAmbiguousSelectorError(snapshots)
}
return snapshots[0], http.StatusOK, ""
}
func (s *LaunchServer) profileSnapshots() []browser.Profile {
if s.browserMgr == nil {
return nil
}
s.browserMgr.Mutex.Lock()
items := make([]browser.Profile, 0, len(s.browserMgr.Profiles))
for _, profile := range s.browserMgr.Profiles {
if profile == nil {
continue
}
items = append(items, *profile)
}
s.browserMgr.Mutex.Unlock()
if s.service != nil {
for i := range items {
if code, err := s.service.EnsureCode(items[i].ProfileId); err == nil {
items[i].LaunchCode = code
}
}
}
return items
}
func filterProfiles(items []browser.Profile, keep func(browser.Profile) bool) []browser.Profile {
filtered := make([]browser.Profile, 0, len(items))
for _, item := range items {
if keep(item) {
filtered = append(filtered, item)
}
}
return filtered
}
func sortProfilesForSelector(items []browser.Profile) {
sort.Slice(items, func(i, j int) bool {
leftName := strings.ToLower(strings.TrimSpace(items[i].ProfileName))
rightName := strings.ToLower(strings.TrimSpace(items[j].ProfileName))
if leftName != rightName {
return leftName < rightName
}
return items[i].ProfileId < items[j].ProfileId
})
}