mirror of
https://github.com/chaitin/MonkeyCode.git
synced 2026-02-03 15:23:30 +08:00
Merge pull request #379 from Strke/add-zip
Add the backend of download jetbrains plugin
This commit is contained in:
3
.github/workflows/backend-ci-cd.yml
vendored
3
.github/workflows/backend-ci-cd.yml
vendored
@@ -99,6 +99,9 @@ jobs:
|
||||
VERSION_NO_V=${{ steps.get_version.outputs.VERSION }}
|
||||
VERSION_NO_V=${VERSION_NO_V#v}
|
||||
wget -O assets/vsix/monkeycode-${VERSION_NO_V}.vsix https://baizhiyun.oss-cn-hangzhou.aliyuncs.com/monkeycode/vsix/monkeycode-${VERSION_NO_V}.vsix
|
||||
|
||||
# 下载 JetBrains 插件 (架构无关), jetbrains插件的下载地址硬编码, 后续需要修改
|
||||
wget -O assets/jetbrains/monkeycode-${VERSION_NO_V}.zip https://baizhiyun.oss-cn-hangzhou.aliyuncs.com/monkeycode/jetbrains/monkeycode-jetbrains-1.22.4.zip
|
||||
|
||||
# 下载 x86_64 SGP
|
||||
wget -O tarballs/sgp.tgz https://baizhiyun.oss-cn-hangzhou.aliyuncs.com/monkeycode/sgp/x86_64/sgp.tgz
|
||||
|
||||
@@ -27,6 +27,7 @@ WORKDIR /app
|
||||
|
||||
ADD migration ./migration
|
||||
ADD assets/vsix ./assets/vsix
|
||||
ADD assets/jetbrains ./assets/jetbrains
|
||||
|
||||
COPY --from=builder /out/main /app/main
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ type UserHandler struct {
|
||||
logger *slog.Logger
|
||||
cfg *config.Config
|
||||
vsixCache map[string]*CacheEntry
|
||||
zipCache map[string]*CacheEntry
|
||||
cacheMu sync.RWMutex
|
||||
limiter *rate.Limiter
|
||||
}
|
||||
@@ -68,11 +69,14 @@ func NewUserHandler(
|
||||
logger: logger,
|
||||
cfg: cfg,
|
||||
vsixCache: make(map[string]*CacheEntry),
|
||||
zipCache: make(map[string]*CacheEntry),
|
||||
limiter: rate.NewLimiter(rate.Every(time.Duration(cfg.Extension.LimitSecond)*time.Second), cfg.Extension.Limit),
|
||||
}
|
||||
|
||||
w.GET("/api/v1/static/vsix/:version", web.BaseHandler(u.VSIXDownload))
|
||||
w.GET("/api/v1/static/vsix", web.BaseHandler(u.VSIXDownload))
|
||||
w.GET("/api/v1/static/jetbrains/:version", web.BaseHandler(u.ZipDownload))
|
||||
w.GET("/api/v1/static/jetbrains", web.BaseHandler(u.ZipDownload))
|
||||
w.POST("/api/v1/vscode/init-auth", web.BindHandler(u.VSCodeAuthInit))
|
||||
|
||||
// admin
|
||||
@@ -170,6 +174,13 @@ func (h *UserHandler) cleanExpiredCache() {
|
||||
delete(h.vsixCache, key)
|
||||
}
|
||||
}
|
||||
if h.zipCache != nil {
|
||||
for key, entry := range h.zipCache {
|
||||
if now.Sub(entry.createdAt) > time.Hour {
|
||||
delete(h.zipCache, key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VSIXDownload 下载VSCode插件
|
||||
@@ -236,6 +247,75 @@ func (h *UserHandler) VSIXDownload(c *web.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// ZipDownload 下载ZIP包(Jetbrains插件包)
|
||||
//
|
||||
// @Tags User
|
||||
// @Summary 下载ZIP包
|
||||
// @Description 下载ZIP安装包(缓存1小时)
|
||||
// @ID zip-download
|
||||
// @Accept json
|
||||
// @Produce octet-stream
|
||||
// @Router /api/v1/static/jetbrains [get]
|
||||
func (h *UserHandler) ZipDownload(c *web.Context) error {
|
||||
if !h.limiter.Allow() {
|
||||
return c.String(http.StatusTooManyRequests, "Too Many Requests")
|
||||
}
|
||||
|
||||
s, err := h.usecase.GetSetting(c.Request().Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
host := c.Request().Host
|
||||
h.logger.With("url", c.Request().URL).With("header", c.Request().Header).With("host", host).DebugContext(c.Request().Context(), "zip download")
|
||||
cacheKey := h.generateCacheKey(version.Version, h.cfg.GetBaseURL(c.Request(), s))
|
||||
ver := strings.Trim(version.Version, "v")
|
||||
|
||||
// 缓存命中
|
||||
h.cacheMu.RLock()
|
||||
if entry, exists := h.zipCache[cacheKey]; exists {
|
||||
if time.Since(entry.createdAt) < time.Hour {
|
||||
h.cacheMu.RUnlock()
|
||||
|
||||
disposition := fmt.Sprintf("attachment; filename=monkeycode-%s.zip", ver)
|
||||
c.Response().Header().Set("Content-Type", "application/octet-stream")
|
||||
c.Response().Header().Set("Content-Disposition", disposition)
|
||||
c.Response().Header().Set("Content-Length", fmt.Sprintf("%d", len(entry.data)))
|
||||
|
||||
fmt.Println(c.Response().Header())
|
||||
|
||||
_, werr := c.Response().Writer.Write(entry.data)
|
||||
return werr
|
||||
}
|
||||
}
|
||||
h.cacheMu.RUnlock()
|
||||
|
||||
var buf bytes.Buffer
|
||||
if err := vsix.ChangeVsixEndpoint(fmt.Sprintf("/app/assets/jetbrains/monkeycode-%s.zip", ver), "roo-code/package.json", h.cfg.GetBaseURL(c.Request(), s), &buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := buf.Bytes()
|
||||
h.cacheMu.Lock()
|
||||
h.zipCache[cacheKey] = &CacheEntry{
|
||||
data: data,
|
||||
createdAt: time.Now(),
|
||||
}
|
||||
h.cacheMu.Unlock()
|
||||
|
||||
// 异步清理
|
||||
go h.cleanExpiredCache()
|
||||
|
||||
// 响应输出
|
||||
disposition := fmt.Sprintf("attachment; filename=monkeycode-%s.zip", ver)
|
||||
c.Response().Header().Set("Content-Type", "application/octet-stream")
|
||||
c.Response().Header().Set("Content-Disposition", disposition)
|
||||
c.Response().Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
|
||||
|
||||
_, err = c.Response().Writer.Write(data)
|
||||
return err
|
||||
}
|
||||
|
||||
// Login 用户登录
|
||||
//
|
||||
// @Tags User
|
||||
|
||||
Reference in New Issue
Block a user