Skip to content

Commit

Permalink
独立功能服务
Browse files Browse the repository at this point in the history
  • Loading branch information
movsb committed Jun 18, 2024
1 parent 95e425c commit 8c38925
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 34 deletions.
File renamed without changes.
66 changes: 66 additions & 0 deletions gateway/handlers/features/features.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package features

import (
"bytes"
"context"
_ "embed"
"errors"
"net/http"
"regexp"
"sync"
"time"

"github.com/movsb/taoblog/modules/utils"
"github.com/movsb/taoblog/service/modules/renderers/plantuml"
)

//go:embed FEATURES.md
var featuresMd []byte
var featuresTime = time.Now()

var (
light []byte
dark []byte
lock sync.RWMutex
)

func New() http.Handler {
return http.HandlerFunc(features)
}

func features(w http.ResponseWriter, r *http.Request) {
lock.Lock()
if len(light) == 0 || len(dark) == 0 {
if err := prepare(); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
lock.Unlock()
return
}
}
lock.Unlock()

content := utils.IIF(r.PathValue(`theme`) == `light`, light, dark)
w.Header().Add(`Content-Type`, `image/svg+xml`)
http.ServeContent(w, r, `features.svg`, featuresTime, bytes.NewReader(content))
}

func prepare() error {
reFeaturesPlantUML := regexp.MustCompile("```plantuml((?sU).+)```")
matches := reFeaturesPlantUML.FindSubmatch(featuresMd)
if len(matches) != 2 {
return errors.New(`no features found`)
}
compressed, err := plantuml.Compress(matches[1])
if err != nil {
return err
}
light, err = plantuml.Fetch(context.Background(), `https://www.plantuml.com/plantuml`, `svg`, compressed, false)
if err != nil {
return err
}
dark, err = plantuml.Fetch(context.Background(), `https://www.plantuml.com/plantuml`, `svg`, compressed, true)
if err != nil {
return err
}
return nil
}
38 changes: 4 additions & 34 deletions gateway/main.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package gateway

import (
"bytes"
"context"
_ "embed"
"encoding/json"
"io"
"net/http"
"net/url"
"regexp"
"strconv"
"time"

"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/movsb/taoblog/gateway/handlers/apidoc"
"github.com/movsb/taoblog/gateway/handlers/assets"
"github.com/movsb/taoblog/gateway/handlers/features"
"github.com/movsb/taoblog/gateway/handlers/robots"
"github.com/movsb/taoblog/gateway/handlers/rss"
"github.com/movsb/taoblog/gateway/handlers/sitemap"
Expand All @@ -26,18 +25,13 @@ import (
"github.com/movsb/taoblog/protocols/go/proto"
"github.com/movsb/taoblog/service"
dynamic "github.com/movsb/taoblog/service/modules/renderers/_dynamic"
"github.com/movsb/taoblog/service/modules/renderers/plantuml"
"github.com/movsb/taoblog/service/modules/webhooks"
"github.com/movsb/taoblog/theme/modules/handle304"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/encoding/protojson"
)

//go:embed FEATURES.md
var featuresMd []byte
var featuresTime = time.Now()

type Gateway struct {
mux *http.ServeMux
service *service.Service
Expand Down Expand Up @@ -91,8 +85,6 @@ func (g *Gateway) register(ctx context.Context, mux *http.ServeMux, mux2 *runtim
proto.RegisterTaoBlogHandlerFromEndpoint(ctx, mux2, g.service.GrpcAddress(), dialOptions)
proto.RegisterSearchHandlerFromEndpoint(ctx, mux2, g.service.GrpcAddress(), dialOptions)

mux2.HandlePath(`GET`, `/v3/features/{theme}`, features)

mux2.HandlePath(`GET`, `/v3/avatar/{id}`, g.getAvatar)

mux2.HandlePath(`POST`, `/v3/webhooks/github`, g.githubWebhook())
Expand All @@ -102,6 +94,9 @@ func (g *Gateway) register(ctx context.Context, mux *http.ServeMux, mux2 *runtim

info := utils.Must1(g.service.GetInfo(ctx, &proto.GetInfoRequest{}))

// 博客功能集
mc.Handle(`GET /v3/features/{theme}`, features.New())

// API 文档
mc.Handle(`GET /v3/api/`, http.StripPrefix(`/v3/api`, apidoc.New()))

Expand Down Expand Up @@ -192,28 +187,3 @@ func (g *Gateway) getAvatar(w http.ResponseWriter, req *http.Request, params map
}
g.service.GetAvatar(in)
}

var reFeaturesPlantUML = regexp.MustCompile("```plantuml((?sU).+)```")

func features(w http.ResponseWriter, r *http.Request, params map[string]string) {
matches := reFeaturesPlantUML.FindSubmatch(featuresMd)
if len(matches) == 2 {
compressed, err := plantuml.Compress(matches[1])
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
darkMode := false
if params[`theme`] == `dark` {
darkMode = true
}
content, err := plantuml.Fetch(r.Context(), `https://www.plantuml.com/plantuml`, `svg`, compressed, darkMode)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.Header().Add(`Content-Type`, `image/svg+xml`)
http.ServeContent(w, r, `features.svg`, featuresTime, bytes.NewReader(content))
return
}
}

0 comments on commit 8c38925

Please sign in to comment.