mirror of
https://github.com/black-ant/Ant-Browser.git
synced 2026-07-14 18:48:55 +08:00
207 lines
6.1 KiB
Go
207 lines
6.1 KiB
Go
package launchcode
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"ant-chrome/backend/internal/browser"
|
|
"ant-chrome/backend/internal/logger"
|
|
)
|
|
|
|
func (s *LaunchServer) createProfile(input browser.ProfileInput, requestedCode string) (*browser.Profile, string, int, string) {
|
|
profile, err := s.createProfileInternal(input)
|
|
if err != nil {
|
|
return nil, "", mapProfileWriteErrorStatus(err), err.Error()
|
|
}
|
|
if profile == nil {
|
|
return nil, "", http.StatusInternalServerError, "profile creation returned nil profile"
|
|
}
|
|
|
|
launchCode, status, errMsg := s.applyRequestedLaunchCode(profile.ProfileId, strings.TrimSpace(profile.LaunchCode), requestedCode)
|
|
if errMsg != "" {
|
|
_ = s.deleteCreatedProfile(profile.ProfileId)
|
|
return nil, "", status, errMsg
|
|
}
|
|
profile.LaunchCode = launchCode
|
|
return profile, launchCode, http.StatusCreated, ""
|
|
}
|
|
|
|
func (s *LaunchServer) updateProfile(profileID string, input browser.ProfileInput, requestedCode string, previous *browser.Profile) (*browser.Profile, string, int, string) {
|
|
profile, err := s.updateProfileInternal(profileID, input)
|
|
if err != nil {
|
|
return nil, "", mapProfileWriteErrorStatus(err), err.Error()
|
|
}
|
|
if profile == nil {
|
|
return nil, "", http.StatusInternalServerError, "profile update returned nil profile"
|
|
}
|
|
|
|
currentCode := ""
|
|
if previous != nil {
|
|
currentCode = strings.TrimSpace(previous.LaunchCode)
|
|
}
|
|
launchCode, status, errMsg := s.applyRequestedLaunchCode(profile.ProfileId, currentCode, requestedCode)
|
|
if errMsg != "" {
|
|
if rollbackErr := s.rollbackProfileUpdate(profileID, previous); rollbackErr != nil {
|
|
logger.New("LaunchServer").Warn("Profile API 更新回滚失败",
|
|
logger.F("profile_id", profileID),
|
|
logger.F("error", rollbackErr.Error()),
|
|
)
|
|
}
|
|
return nil, "", status, errMsg
|
|
}
|
|
profile.LaunchCode = launchCode
|
|
return profile, launchCode, http.StatusOK, ""
|
|
}
|
|
|
|
func (s *LaunchServer) maybeAutoLaunchProfile(profile *browser.Profile, req ProfileWriteRequest) (*browser.Profile, bool, error) {
|
|
if profile == nil || !req.AutoLaunch {
|
|
return nil, false, nil
|
|
}
|
|
|
|
params := LaunchRequestParams{}
|
|
if req.Start != nil {
|
|
params = normalizeLaunchRequestParams(*req.Start)
|
|
}
|
|
|
|
launchedProfile, err := s.launchProfile(profile.ProfileId, params)
|
|
if err != nil {
|
|
return nil, false, err
|
|
}
|
|
return launchedProfile, true, nil
|
|
}
|
|
|
|
func (s *LaunchServer) createProfileInternal(input browser.ProfileInput) (*browser.Profile, error) {
|
|
if creator, ok := s.starter.(profileCreator); ok {
|
|
return creator.CreateProfile(input)
|
|
}
|
|
if s.browserMgr != nil {
|
|
return s.browserMgr.Create(input)
|
|
}
|
|
return nil, http.ErrNotSupported
|
|
}
|
|
|
|
func (s *LaunchServer) updateProfileInternal(profileID string, input browser.ProfileInput) (*browser.Profile, error) {
|
|
if updater, ok := s.starter.(profileUpdater); ok {
|
|
return updater.UpdateProfile(profileID, input)
|
|
}
|
|
if s.browserMgr != nil {
|
|
return s.browserMgr.Update(profileID, input)
|
|
}
|
|
return nil, http.ErrNotSupported
|
|
}
|
|
|
|
func (s *LaunchServer) deleteCreatedProfile(profileID string) error {
|
|
if deleter, ok := s.starter.(profileDeleter); ok {
|
|
return deleter.DeleteProfile(profileID)
|
|
}
|
|
if s.browserMgr != nil {
|
|
return s.browserMgr.Delete(profileID)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (s *LaunchServer) deleteProfileInternal(profileID string) error {
|
|
return s.deleteCreatedProfile(profileID)
|
|
}
|
|
|
|
func (s *LaunchServer) rollbackProfileUpdate(profileID string, previous *browser.Profile) error {
|
|
if previous == nil {
|
|
return nil
|
|
}
|
|
_, err := s.updateProfileInternal(profileID, profileToInput(previous))
|
|
return err
|
|
}
|
|
|
|
func (s *LaunchServer) listProfiles() ([]browser.Profile, int, string) {
|
|
if s.browserMgr == nil {
|
|
return nil, http.StatusServiceUnavailable, "profile catalog is not available"
|
|
}
|
|
|
|
items := s.browserMgr.List()
|
|
for i := range items {
|
|
items[i].LaunchCode = s.resolveProfileLaunchCode(items[i].ProfileId, items[i].LaunchCode)
|
|
}
|
|
return items, http.StatusOK, ""
|
|
}
|
|
|
|
func (s *LaunchServer) profileSnapshotByID(profileID string) (*browser.Profile, int, string) {
|
|
profileID = strings.TrimSpace(profileID)
|
|
if profileID == "" {
|
|
return nil, http.StatusNotFound, "profile not found"
|
|
}
|
|
if s.browserMgr == nil {
|
|
return nil, http.StatusServiceUnavailable, "profile catalog is not available"
|
|
}
|
|
|
|
s.browserMgr.Mutex.Lock()
|
|
profile, ok := s.browserMgr.Profiles[profileID]
|
|
var snapshot browser.Profile
|
|
if ok && profile != nil {
|
|
snapshot = *profile
|
|
}
|
|
s.browserMgr.Mutex.Unlock()
|
|
if !ok {
|
|
return nil, http.StatusNotFound, "profile not found"
|
|
}
|
|
|
|
snapshot.LaunchCode = s.resolveProfileLaunchCode(snapshot.ProfileId, snapshot.LaunchCode)
|
|
return &snapshot, http.StatusOK, ""
|
|
}
|
|
|
|
func (s *LaunchServer) applyRequestedLaunchCode(profileID, currentCode, requestedCode string) (string, int, string) {
|
|
currentCode = strings.TrimSpace(currentCode)
|
|
requestedCode = strings.TrimSpace(requestedCode)
|
|
if requestedCode == "" {
|
|
return s.resolveProfileLaunchCode(profileID, currentCode), http.StatusOK, ""
|
|
}
|
|
if s.service == nil {
|
|
return "", http.StatusServiceUnavailable, "launch code service is unavailable"
|
|
}
|
|
|
|
code, err := s.service.SetCode(profileID, requestedCode)
|
|
if err != nil {
|
|
return "", mapProfileWriteErrorStatus(err), err.Error()
|
|
}
|
|
return code, http.StatusOK, ""
|
|
}
|
|
|
|
func (s *LaunchServer) resolveProfileLaunchCode(profileID, currentCode string) string {
|
|
if trimmed := strings.TrimSpace(currentCode); trimmed != "" {
|
|
return trimmed
|
|
}
|
|
if s.service == nil || strings.TrimSpace(profileID) == "" {
|
|
return ""
|
|
}
|
|
code, err := s.service.EnsureCode(profileID)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return code
|
|
}
|
|
|
|
func (s *LaunchServer) profileWriteSuccessPayload(profile *browser.Profile, launchCode string, created bool, updated bool, launched bool) map[string]interface{} {
|
|
payload := map[string]interface{}{
|
|
"ok": true,
|
|
"created": created,
|
|
"updated": updated,
|
|
"launched": launched,
|
|
"profileId": profile.ProfileId,
|
|
"profileName": profile.ProfileName,
|
|
"launchCode": launchCode,
|
|
"profile": profile,
|
|
}
|
|
|
|
if !launched {
|
|
return payload
|
|
}
|
|
|
|
for key, value := range s.launchSuccessPayload(profile, launchCode) {
|
|
payload[key] = value
|
|
}
|
|
payload["created"] = created
|
|
payload["updated"] = updated
|
|
payload["launched"] = true
|
|
payload["profile"] = profile
|
|
return payload
|
|
}
|