diff --git a/api/anonymous.go b/api/anonymous.go index 38662ad..cb0b63f 100644 --- a/api/anonymous.go +++ b/api/anonymous.go @@ -78,7 +78,7 @@ func GetAnonymousResponseWithCache(c *gin.Context, message string, web bool) (st return "", "There was something wrong...", err } - cache.Set(c, fmt.Sprintf(":chatgpt:%s", message), utils.ToJson(AnonymousResponseCache{ + cache.Set(c, fmt.Sprintf(":chatgpt-%v:%s", web, message), utils.ToJson(AnonymousResponseCache{ Keyword: key, Message: res, }), time.Hour*48) diff --git a/api/card.go b/api/card.go new file mode 100644 index 0000000..f1560d8 --- /dev/null +++ b/api/card.go @@ -0,0 +1,69 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "github.com/russross/blackfriday/v2" + "net/http" + "strings" +) + +const maxColumnPerLine = 50 + +func ProcessMarkdownLine(source []byte) string { + segment := strings.Split(string(source), "\n") + var result []rune + for _, line := range segment { + data := []rune(line) + length := len([]rune(line)) + if length < maxColumnPerLine { + result = append(result, data...) + result = append(result, '\n') + } else { + for i := 0; i < length; i += maxColumnPerLine { + if i+maxColumnPerLine < length { + result = append(result, data[i:i+maxColumnPerLine]...) + result = append(result, '\n') + } else { + result = append(result, data[i:]...) + result = append(result, '\n') + } + } + } + } + return string(result) +} + +func MarkdownConvert(text string) string { + if text == "" { + return "" + } + + result := blackfriday.Run([]byte(text)) + return string(result) +} + +func CardAPI(c *gin.Context) { + var body AnonymousRequestBody + if err := c.ShouldBindJSON(&body); err != nil { + c.JSON(http.StatusBadRequest, gin.H{ + "error": "invalid request body", + }) + } + message := strings.TrimSpace(body.Message) + if len(message) == 0 { + c.JSON(http.StatusBadRequest, gin.H{ + "error": "message is empty", + }) + return + } + + key, res, err := GetAnonymousResponseWithCache(c, message, body.Web) + if err != nil { + res = "There was something wrong..." + } + + c.JSON(http.StatusOK, gin.H{ + "message": MarkdownConvert(res), + "keyword": key, + }) +} diff --git a/go.mod b/go.mod index ba6cf29..6f42afd 100644 --- a/go.mod +++ b/go.mod @@ -36,6 +36,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkoukk/tiktoken-go v0.1.5 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect diff --git a/go.sum b/go.sum index 65db482..0ad7135 100644 --- a/go.sum +++ b/go.sum @@ -203,6 +203,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= diff --git a/main.go b/main.go index 30b3105..4d388a1 100644 --- a/main.go +++ b/main.go @@ -24,6 +24,7 @@ func main() { app.Use(auth.Middleware()) app.POST("/anonymous", api.AnonymousAPI) + app.POST("/card", api.CardAPI) app.GET("/chat", api.ChatAPI) app.POST("/login", auth.LoginAPI) app.POST("/state", auth.StateAPI) diff --git a/middleware/throttle.go b/middleware/throttle.go index e0bf987..753739e 100644 --- a/middleware/throttle.go +++ b/middleware/throttle.go @@ -28,6 +28,7 @@ func (l *Limiter) RateLimit(ctx *gin.Context, rds *redis.Client, ip string, path var limits = map[string]Limiter{ "/login": {Duration: 10, Count: 5}, "/anonymous": {Duration: 60, Count: 15}, + "/card": {Duration: 1, Count: 5}, "/user": {Duration: 1, Count: 1}, "/package": {Duration: 1, Count: 2}, "/quota": {Duration: 1, Count: 2}, diff --git a/plugin/.gitignore b/plugin/.gitignore new file mode 100644 index 0000000..706fd07 --- /dev/null +++ b/plugin/.gitignore @@ -0,0 +1,2 @@ +.idea +.vscode diff --git a/plugin/card.php b/plugin/card.php new file mode 100644 index 0000000..f494e6c --- /dev/null +++ b/plugin/card.php @@ -0,0 +1,109 @@ +", "

", $resp['message'])); +$msgHeight = substr_count($resp['message'], "\n") * 20 + strlen($msg) * 0.15 + substr_count($resp['message'], " + + ChatGPT + ChatGPT Card + + + + + + chatnio + + + + OpenAI + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugin/error.php b/plugin/error.php new file mode 100644 index 0000000..4283d76 --- /dev/null +++ b/plugin/error.php @@ -0,0 +1,47 @@ + + + + Error + Error Card + + + + + Sorry, there is something wrong... + + + + + \ No newline at end of file diff --git a/plugin/favicon.ico b/plugin/favicon.ico new file mode 100644 index 0000000..688435b Binary files /dev/null and b/plugin/favicon.ico differ diff --git a/plugin/utils.php b/plugin/utils.php new file mode 100644 index 0000000..1c2f6f6 --- /dev/null +++ b/plugin/utils.php @@ -0,0 +1,31 @@ +[^\S ]+/', '/[^\S ]+ ', '<', '\\1', '><', ':', '{', '}'); + return preg_replace($search, $replace, $buffer); +} + +function fetch($message, $web): array|string|null +{ + $opts = array('http' => + array( + 'method' => 'POST', + 'header' => 'Content-type: application/json', + 'content' => json_encode(array('message' => $message, 'web' => $web)) + ) + ); + + $context = stream_context_create($opts); + $response = @file_get_contents("http://localhost:8094/card", false, $context); + $ok = $response !== false; + return $ok ? json_decode($response, true) : null; +} + +function get($param, $default = null) +{ + return $_GET[$param] ?? $default; +}