SauceNao

package module
v0.0.0-...-9d06c70 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 23, 2026 License: MIT Imports: 15 Imported by: 0

README

SauceNAO-go

要求

  • Go 1.25+
  • 运行中的 FlareSolverr 服务端

安装

go get github.com/Miuzarte/SauceNAO-go

示例

package main

import (
    "context"
    "fmt"
    "reflect"
    "strconv"
    fs "github.com/Miuzarte/FlareSolverr-go"
    sn "github.com/Miuzarte/SauceNAO-go"
)

const (
    // https://saucenao.com/user.php
    API_KEY = "abc123"
    // using `https://saucenao.com` when empty
    OVERRIDE_HOST = ""
    // number of results
    NUM_RESULT = 2
    // 0=show all
    // 1=hide expected explicit
    // 2=hide expected and suspected explicit
    // 3=hide all but expected safe
    HIDE = 0
)

func main() {
    fsClient := fs.NewClient("http://127.0.0.1:8191/v1")
    client := sn.NewClient(
        API_KEY,
        OVERRIDE_HOST,
        NUM_RESULT,
        HIDE,
        fsClient,
    )

    // can be:
    // url.(string): using .Get()
    // filepath.(string), data.([]byte), r.(io.Reader): using .Post()
    var img any
    resp, err := client.Search(context.Background(), img)
    if err != nil {
        panic(err)
    }

    for _, result := range resp.Results {
        similarity, _ := strconv.ParseFloat(header.Similarity, 64)

        hideThumbnail := similarity < 60.0 && result.Header.Hidden > 0
        if !hideThumbnail {
            fmt.Printf("thumbnail: %s", result.Header.Thumbnail)
        }

        var data interface{String() string} = result.DecodeData()
        v := reflect.ValueOf(data)
        if v.Kind() == reflect.Pointer && v.IsNil() {
            // the corresponding struct is not completed
            fmt.Printf("%s: %s\n", header.IndexName, resp.RawBody)
            continue
        }

        fmt.Printf(
            "SauceNAO (%s%%)\n%s\n%s\n",
            result.Header.Similarity,
            result.Header.IndexName,
            data,
        )
    }
}

Documentation

Index

Constants

View Source
const (
	API_HOST  = `https://saucenao.com`
	API_PATH  = `/search.php`
	USER_PATH = `/user.php` // 必定触发 cf
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

type Client struct {
	ApiKey             string
	Host               string
	NumRes             int
	Hide               int
	FlareSolverrClient *fs.Client
	// contains filtered or unexported fields
}

func NewClient

func NewClient(apiKey, overrideHost string, numRes, hide int, fsClient *fs.Client) *Client

func (*Client) Get

func (c *Client) Get(ctx context.Context, imgUrl string) (*Response, error)

func (*Client) Post

func (c *Client) Post(ctx context.Context, imgData []byte) (*Response, error)

func (*Client) Search

func (c *Client) Search(ctx context.Context, image any) (resp *Response, err error)

type HttpError

type HttpError struct {
	StatusCode int
	Url        string
	Body       string
}

func (*HttpError) Error

func (e *HttpError) Error() string

type IndexEntry

type IndexEntry struct {
	Status   int `json:"status"`
	ParentID int `json:"parent_id"`
	ID       int `json:"id"`
	Results  int `json:"results"`
}

type Response

type Response struct {
	Header  ResponseHeader `json:"header"`
	Results []Result       `json:"results"`
	RawBody string         `json:"-"` // for debug
}

type ResponseHeader

type ResponseHeader struct {
	UserId            string  `json:"user_id"`             // api key 所属
	AccountType       string  `json:"account_type"`        // "1"
	ShortLimit        string  `json:"short_limit"`         // "4"   // 30s
	LongLimit         string  `json:"long_limit"`          // "100" // 24h
	LongRemaining     int     `json:"long_remaining"`      // 85
	ShortRemaining    int     `json:"short_remaining"`     // 3
	Status            int     `json:"status"`              // 0
	ResultsRequested  int     `json:"results_requested"`   // 对应 numres 参数
	SearchDepth       string  `json:"search_depth"`        // "128"
	MinimumSimilarity float64 `json:"minimum_similarity"`  // 41.49
	QueryImageDisplay string  `json:"query_image_display"` // 提交的图片 url
	QueryImage        string  `json:"query_image"`         // 提交的图片文件名
	ResultsReturned   int     `json:"results_returned"`    // 最终返回的结果数量

	Index map[string]IndexEntry `json:"index"` // "0","2","44" ...
}

type Result

type Result struct {
	Header ResultHeader   `json:"header"`
	Data   map[string]any `json:"data"` // delay decode using [mapstructure.Decode]
}

func (Result) DecodeData

func (r Result) DecodeData() (ret interface{ String() string })

type ResultHeader

type ResultHeader struct {
	Similarity string     `json:"similarity"` // .2f
	Thumbnail  string     `json:"thumbnail"`
	IndexId    db.IndexId `json:"index_id"`
	IndexName  string     `json:"index_name"`
	Dupes      int        `json:"dupes"`
	Hidden     int        `json:"hidden"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL