mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-02-03 13:00:52 +08:00
refactor: standardize constant naming and improve file-based auth handling
- Renamed constants from uppercase to CamelCase for consistency. - Replaced redundant file-based auth handling logic with the new `util.CountAuthFiles` helper. - Fixed various error-handling inconsistencies and enhanced robustness in file operations. - Streamlined auth client reload logic in server and watcher components. - Applied minor code readability improvements across multiple packages.
This commit is contained in:
@@ -96,7 +96,7 @@ func (c *GeminiClient) Init(timeoutSec float64, autoClose bool, closeDelaySec fl
|
||||
|
||||
tr := &http.Transport{}
|
||||
if c.Proxy != "" {
|
||||
if pu, err := url.Parse(c.Proxy); err == nil {
|
||||
if pu, errParse := url.Parse(c.Proxy); errParse == nil {
|
||||
tr.Proxy = http.ProxyURL(pu)
|
||||
}
|
||||
}
|
||||
@@ -348,7 +348,9 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
if err != nil {
|
||||
return empty, &TimeoutError{GeminiError{Msg: "Generate content request timed out."}}
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
defer func() {
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
|
||||
if resp.StatusCode == 429 {
|
||||
// Surface 429 as TemporarilyBlocked to match Python behavior
|
||||
@@ -368,7 +370,7 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
return empty, &APIError{Msg: "Invalid response data received."}
|
||||
}
|
||||
var responseJSON []any
|
||||
if err := json.Unmarshal([]byte(parts[2]), &responseJSON); err != nil {
|
||||
if err = json.Unmarshal([]byte(parts[2]), &responseJSON); err != nil {
|
||||
c.Close(0)
|
||||
return empty, &APIError{Msg: "Invalid response data received."}
|
||||
}
|
||||
@@ -388,7 +390,7 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
continue
|
||||
}
|
||||
var mainPart []any
|
||||
if err := json.Unmarshal([]byte(s), &mainPart); err != nil {
|
||||
if err = json.Unmarshal([]byte(s), &mainPart); err != nil {
|
||||
continue
|
||||
}
|
||||
if len(mainPart) > 4 && mainPart[4] != nil {
|
||||
@@ -406,7 +408,7 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
continue
|
||||
}
|
||||
var top []any
|
||||
if err := json.Unmarshal([]byte(line), &top); err != nil {
|
||||
if err = json.Unmarshal([]byte(line), &top); err != nil {
|
||||
continue
|
||||
}
|
||||
lastTop = top
|
||||
@@ -420,7 +422,7 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
continue
|
||||
}
|
||||
var mainPart []any
|
||||
if err := json.Unmarshal([]byte(s), &mainPart); err != nil {
|
||||
if err = json.Unmarshal([]byte(s), &mainPart); err != nil {
|
||||
continue
|
||||
}
|
||||
if len(mainPart) > 4 && mainPart[4] != nil {
|
||||
@@ -465,7 +467,7 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
if len(bodyArr) > 1 {
|
||||
if metaArr, ok := bodyArr[1].([]any); ok {
|
||||
for _, v := range metaArr {
|
||||
if s, ok := v.(string); ok {
|
||||
if s, isOk := v.(string); isOk {
|
||||
metadata = append(metadata, s)
|
||||
}
|
||||
}
|
||||
@@ -482,22 +484,22 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
reGen := regexp.MustCompile(`http://googleusercontent\.com/image_generation_content/\d+`)
|
||||
|
||||
for ci, candAny := range candContainer {
|
||||
cArr, ok := candAny.([]any)
|
||||
if !ok {
|
||||
cArr, isOk := candAny.([]any)
|
||||
if !isOk {
|
||||
continue
|
||||
}
|
||||
// text: cArr[1][0]
|
||||
var text string
|
||||
if len(cArr) > 1 {
|
||||
if sArr, ok := cArr[1].([]any); ok && len(sArr) > 0 {
|
||||
if sArr, isOk1 := cArr[1].([]any); isOk1 && len(sArr) > 0 {
|
||||
text, _ = sArr[0].(string)
|
||||
}
|
||||
}
|
||||
if reCard.MatchString(text) {
|
||||
// candidate[22] and candidate[22][0] or text
|
||||
if len(cArr) > 22 {
|
||||
if arr, ok := cArr[22].([]any); ok && len(arr) > 0 {
|
||||
if s, ok := arr[0].(string); ok {
|
||||
if arr, isOk1 := cArr[22].([]any); isOk1 && len(arr) > 0 {
|
||||
if s, isOk2 := arr[0].(string); isOk2 {
|
||||
text = s
|
||||
}
|
||||
}
|
||||
@@ -507,9 +509,9 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
// thoughts: candidate[37][0][0]
|
||||
var thoughts *string
|
||||
if len(cArr) > 37 {
|
||||
if a, ok := cArr[37].([]any); ok && len(a) > 0 {
|
||||
if b, ok := a[0].([]any); ok && len(b) > 0 {
|
||||
if s, ok := b[0].(string); ok {
|
||||
if a, ok1 := cArr[37].([]any); ok1 && len(a) > 0 {
|
||||
if b1, ok2 := a[0].([]any); ok2 && len(b1) > 0 {
|
||||
if s, ok3 := b1[0].(string); ok3 {
|
||||
ss := decodeHTML(s)
|
||||
thoughts = &ss
|
||||
}
|
||||
@@ -518,34 +520,34 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
}
|
||||
|
||||
// web images: candidate[12][1]
|
||||
webImages := []WebImage{}
|
||||
var webImages []WebImage
|
||||
var imgSection any
|
||||
if len(cArr) > 12 {
|
||||
imgSection = cArr[12]
|
||||
}
|
||||
if arr, ok := imgSection.([]any); ok && len(arr) > 1 {
|
||||
if imagesArr, ok := arr[1].([]any); ok {
|
||||
if arr, ok1 := imgSection.([]any); ok1 && len(arr) > 1 {
|
||||
if imagesArr, ok2 := arr[1].([]any); ok2 {
|
||||
for _, wiAny := range imagesArr {
|
||||
wiArr, ok := wiAny.([]any)
|
||||
if !ok {
|
||||
wiArr, ok3 := wiAny.([]any)
|
||||
if !ok3 {
|
||||
continue
|
||||
}
|
||||
// url: wiArr[0][0][0], title: wiArr[7][0], alt: wiArr[0][4]
|
||||
var urlStr, title, alt string
|
||||
if len(wiArr) > 0 {
|
||||
if a, ok := wiArr[0].([]any); ok && len(a) > 0 {
|
||||
if b, ok := a[0].([]any); ok && len(b) > 0 {
|
||||
urlStr, _ = b[0].(string)
|
||||
if a, ok5 := wiArr[0].([]any); ok5 && len(a) > 0 {
|
||||
if b1, ok6 := a[0].([]any); ok6 && len(b1) > 0 {
|
||||
urlStr, _ = b1[0].(string)
|
||||
}
|
||||
if len(a) > 4 {
|
||||
if s, ok := a[4].(string); ok {
|
||||
if s, ok6 := a[4].(string); ok6 {
|
||||
alt = s
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(wiArr) > 7 {
|
||||
if a, ok := wiArr[7].([]any); ok && len(a) > 0 {
|
||||
if a, ok4 := wiArr[7].([]any); ok4 && len(a) > 0 {
|
||||
title, _ = a[0].(string)
|
||||
}
|
||||
}
|
||||
@@ -555,10 +557,10 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
}
|
||||
|
||||
// generated images
|
||||
genImages := []GeneratedImage{}
|
||||
var genImages []GeneratedImage
|
||||
hasGen := false
|
||||
if arr, ok := imgSection.([]any); ok && len(arr) > 7 {
|
||||
if a, ok := arr[7].([]any); ok && len(a) > 0 && a[0] != nil {
|
||||
if arr, ok1 := imgSection.([]any); ok1 && len(arr) > 7 {
|
||||
if a, ok2 := arr[7].([]any); ok2 && len(a) > 0 && a[0] != nil {
|
||||
hasGen = true
|
||||
}
|
||||
}
|
||||
@@ -567,23 +569,23 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
var imgBody []any
|
||||
for pi := bodyIndex; pi < len(responseJSON); pi++ {
|
||||
part := responseJSON[pi]
|
||||
arr, ok := part.([]any)
|
||||
if !ok || len(arr) < 3 {
|
||||
arr, ok1 := part.([]any)
|
||||
if !ok1 || len(arr) < 3 {
|
||||
continue
|
||||
}
|
||||
s, ok := arr[2].(string)
|
||||
if !ok {
|
||||
s, ok1 := arr[2].(string)
|
||||
if !ok1 {
|
||||
continue
|
||||
}
|
||||
var mp []any
|
||||
if err := json.Unmarshal([]byte(s), &mp); err != nil {
|
||||
if err = json.Unmarshal([]byte(s), &mp); err != nil {
|
||||
continue
|
||||
}
|
||||
if len(mp) > 4 {
|
||||
if tt, ok := mp[4].([]any); ok && len(tt) > ci {
|
||||
if sec, ok := tt[ci].([]any); ok && len(sec) > 12 {
|
||||
if ss, ok := sec[12].([]any); ok && len(ss) > 7 {
|
||||
if first, ok := ss[7].([]any); ok && len(first) > 0 && first[0] != nil {
|
||||
if tt, ok2 := mp[4].([]any); ok2 && len(tt) > ci {
|
||||
if sec, ok3 := tt[ci].([]any); ok3 && len(sec) > 12 {
|
||||
if ss, ok4 := sec[12].([]any); ok4 && len(ss) > 7 {
|
||||
if first, ok5 := ss[7].([]any); ok5 && len(first) > 0 && first[0] != nil {
|
||||
imgBody = mp
|
||||
break
|
||||
}
|
||||
@@ -597,34 +599,34 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
}
|
||||
imgCand := imgBody[4].([]any)[ci].([]any)
|
||||
if len(imgCand) > 1 {
|
||||
if a, ok := imgCand[1].([]any); ok && len(a) > 0 {
|
||||
if s, ok := a[0].(string); ok {
|
||||
if a, ok1 := imgCand[1].([]any); ok1 && len(a) > 0 {
|
||||
if s, ok2 := a[0].(string); ok2 {
|
||||
text = strings.TrimSpace(reGen.ReplaceAllString(s, ""))
|
||||
}
|
||||
}
|
||||
}
|
||||
// images list at imgCand[12][7][0]
|
||||
if len(imgCand) > 12 {
|
||||
if s1, ok := imgCand[12].([]any); ok && len(s1) > 7 {
|
||||
if s2, ok := s1[7].([]any); ok && len(s2) > 0 {
|
||||
if s3, ok := s2[0].([]any); ok {
|
||||
if s1, ok1 := imgCand[12].([]any); ok1 && len(s1) > 7 {
|
||||
if s2, ok2 := s1[7].([]any); ok2 && len(s2) > 0 {
|
||||
if s3, ok3 := s2[0].([]any); ok3 {
|
||||
for ii, giAny := range s3 {
|
||||
ga, ok := giAny.([]any)
|
||||
if !ok || len(ga) < 4 {
|
||||
ga, ok4 := giAny.([]any)
|
||||
if !ok4 || len(ga) < 4 {
|
||||
continue
|
||||
}
|
||||
// url: ga[0][3][3]
|
||||
var urlStr, title, alt string
|
||||
if a, ok := ga[0].([]any); ok && len(a) > 3 {
|
||||
if b, ok := a[3].([]any); ok && len(b) > 3 {
|
||||
urlStr, _ = b[3].(string)
|
||||
if a, ok5 := ga[0].([]any); ok5 && len(a) > 3 {
|
||||
if b1, ok6 := a[3].([]any); ok6 && len(b1) > 3 {
|
||||
urlStr, _ = b1[3].(string)
|
||||
}
|
||||
}
|
||||
// title from ga[3][6]
|
||||
if len(ga) > 3 {
|
||||
if a, ok := ga[3].([]any); ok {
|
||||
if a, ok5 := ga[3].([]any); ok5 {
|
||||
if len(a) > 6 {
|
||||
if v, ok := a[6].(float64); ok && v != 0 {
|
||||
if v, ok6 := a[6].(float64); ok6 && v != 0 {
|
||||
title = fmt.Sprintf("[Generated Image %.0f]", v)
|
||||
} else {
|
||||
title = "[Generated Image]"
|
||||
@@ -634,13 +636,13 @@ func (c *GeminiClient) generateOnce(prompt string, files []string, model Model,
|
||||
}
|
||||
// alt from ga[3][5][ii] fallback
|
||||
if len(a) > 5 {
|
||||
if tt, ok := a[5].([]any); ok {
|
||||
if tt, ok6 := a[5].([]any); ok6 {
|
||||
if ii < len(tt) {
|
||||
if s, ok := tt[ii].(string); ok {
|
||||
if s, ok7 := tt[ii].(string); ok7 {
|
||||
alt = s
|
||||
}
|
||||
} else if len(tt) > 0 {
|
||||
if s, ok := tt[0].(string); ok {
|
||||
if s, ok7 := tt[0].(string); ok7 {
|
||||
alt = s
|
||||
}
|
||||
}
|
||||
@@ -709,14 +711,6 @@ func extractErrorCode(top []any) (int, bool) {
|
||||
return int(f), true
|
||||
}
|
||||
|
||||
// truncateForLog returns a shortened string for logging
|
||||
func truncateForLog(s string, n int) string {
|
||||
if n <= 0 || len(s) <= n {
|
||||
return s
|
||||
}
|
||||
return s[:n]
|
||||
}
|
||||
|
||||
// StartChat returns a ChatSession attached to the client
|
||||
func (c *GeminiClient) StartChat(model Model, gem *Gem, metadata []string) *ChatSession {
|
||||
return &ChatSession{client: c, metadata: normalizeMeta(metadata), model: model, gem: gem, requestedModel: strings.ToLower(model.Name)}
|
||||
|
||||
@@ -122,7 +122,7 @@ func (i Image) Save(path string, filename string, cookies map[string]string, ver
|
||||
_ = resp.Body.Close()
|
||||
}()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("Error downloading image: %d %s", resp.StatusCode, resp.Status)
|
||||
return "", fmt.Errorf("error downloading image: %d %s", resp.StatusCode, resp.Status)
|
||||
}
|
||||
if ct := resp.Header.Get("Content-Type"); ct != "" && !strings.Contains(strings.ToLower(ct), "image") {
|
||||
Warning("Content type of %s is not image, but %s.", filename, ct)
|
||||
|
||||
@@ -101,7 +101,9 @@ func LoadConvStore(path string) (map[string][]string, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
out := map[string][]string{}
|
||||
err = db.View(func(tx *bolt.Tx) error {
|
||||
b := tx.Bucket([]byte("account_meta"))
|
||||
@@ -138,24 +140,26 @@ func SaveConvStore(path string, data map[string][]string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
return db.Update(func(tx *bolt.Tx) error {
|
||||
// Recreate bucket to reflect the given snapshot exactly.
|
||||
if b := tx.Bucket([]byte("account_meta")); b != nil {
|
||||
if err := tx.DeleteBucket([]byte("account_meta")); err != nil {
|
||||
if err = tx.DeleteBucket([]byte("account_meta")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
b, err := tx.CreateBucket([]byte("account_meta"))
|
||||
if err != nil {
|
||||
return err
|
||||
b, errCreateBucket := tx.CreateBucket([]byte("account_meta"))
|
||||
if errCreateBucket != nil {
|
||||
return errCreateBucket
|
||||
}
|
||||
for k, v := range data {
|
||||
enc, e := json.Marshal(v)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
if e := b.Put([]byte(k), enc); e != nil {
|
||||
if e = b.Put([]byte(k), enc); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
@@ -177,7 +181,9 @@ func LoadConvData(path string) (map[string]ConversationRecord, map[string]string
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
items := map[string]ConversationRecord{}
|
||||
index := map[string]string{}
|
||||
err = db.View(func(tx *bolt.Tx) error {
|
||||
@@ -229,37 +235,39 @@ func SaveConvData(path string, items map[string]ConversationRecord, index map[st
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer db.Close()
|
||||
defer func() {
|
||||
_ = db.Close()
|
||||
}()
|
||||
return db.Update(func(tx *bolt.Tx) error {
|
||||
// Recreate items bucket
|
||||
if b := tx.Bucket([]byte("conv_items")); b != nil {
|
||||
if err := tx.DeleteBucket([]byte("conv_items")); err != nil {
|
||||
if err = tx.DeleteBucket([]byte("conv_items")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
bi, err := tx.CreateBucket([]byte("conv_items"))
|
||||
if err != nil {
|
||||
return err
|
||||
bi, errCreateBucket := tx.CreateBucket([]byte("conv_items"))
|
||||
if errCreateBucket != nil {
|
||||
return errCreateBucket
|
||||
}
|
||||
for k, rec := range items {
|
||||
enc, e := json.Marshal(rec)
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
if e := bi.Put([]byte(k), enc); e != nil {
|
||||
if e = bi.Put([]byte(k), enc); e != nil {
|
||||
return e
|
||||
}
|
||||
}
|
||||
|
||||
// Recreate index bucket
|
||||
if b := tx.Bucket([]byte("conv_index")); b != nil {
|
||||
if err := tx.DeleteBucket([]byte("conv_index")); err != nil {
|
||||
if err = tx.DeleteBucket([]byte("conv_index")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
bx, err := tx.CreateBucket([]byte("conv_index"))
|
||||
if err != nil {
|
||||
return err
|
||||
bx, errCreateBucket := tx.CreateBucket([]byte("conv_index"))
|
||||
if errCreateBucket != nil {
|
||||
return errCreateBucket
|
||||
}
|
||||
for k, v := range index {
|
||||
if e := bx.Put([]byte(k), []byte(v)); e != nil {
|
||||
|
||||
@@ -79,10 +79,6 @@ func SendWithSplit(chat *ChatSession, text string, files []string, cfg *config.C
|
||||
useHint = false
|
||||
chunkSize = maxChars
|
||||
}
|
||||
if chunkSize <= 0 {
|
||||
// As a last resort, split by single rune to avoid exceeding the limit
|
||||
chunkSize = 1
|
||||
}
|
||||
|
||||
// Split into rune-safe chunks
|
||||
chunks := ChunkByRunes(text, chunkSize)
|
||||
|
||||
Reference in New Issue
Block a user