// sf is the recursive function used to build the structure neeeded by SelectFields func sf(in interface{}, c echo.Context) (interface{}, error) { in = reflect.Indirect(reflect.ValueOf(in)).Interface() Type := reflect.TypeOf(in) switch Type.Kind() { case reflect.Struct: ret := make(map[string]interface{}) value := reflect.ValueOf(in) if fieldString := c.QueryParam("fields"); fieldString != "" { fields := strings.Split(fieldString, ",") for _, field := range fields { fieldName := utils.UpperFirst(field) if structField, ok := Type.FieldByName(fieldName); ok { jsonTag := structField.Tag.Get("json") if jsonTag != "-" && jsonTag != "" { ret[strings.Split(jsonTag, ",")[0]] = value.FieldByName(fieldName).Interface() } } else { // Else check if json field name is different from struct field name (with first letter in uppercase) // this is the user expected behaviour, but we prefer the above approach to speed up the process var found bool for i := 0; i < Type.NumField(); i++ { jsonTag := Type.Field(i).Tag.Get("json") if strings.Split(jsonTag, ",")[0] == field { ret[field] = value.Field(i).Interface() found = true break } } if !found { return nil, fmt.Errorf("Field %s does not exists", field) } } } } else { for i := 0; i < Type.NumField(); i++ { jsonTag := Type.Field(i).Tag.Get("json") if jsonTag != "-" && jsonTag != "" { ret[strings.Split(jsonTag, ",")[0]] = value.Field(i).Interface() } } } return &ret, nil case reflect.Slice: value := reflect.ValueOf(in) ret := make([]interface{}, value.Len()) for i := 0; i < value.Len(); i++ { if m, e := sf(value.Index(i).Elem().Interface(), c); e == nil { ret[i] = m } else { return nil, fmt.Errorf(`Error "%s" on field number %d`, e.Error(), i) } } return &ret, nil } return nil, errors.New("input parameter is not a struct or a slice of struct") }
func (h *handler) handleDownloadTarFunc(c echo.Context) error { pathToSend := c.QueryParam("path") fileFilter := c.QueryParam("file-filter") if strings.TrimSpace(pathToSend) == "" { return fmt.Errorf("Request does not contain query 'path' value") } var tarProvider tar_io.TarProvider if isDir, err := path_utils.DirectoryExists(pathToSend); err != nil { return fmt.Errorf("Unable to determine if path '%s' is a directory, error: %s", pathToSend, err.Error()) } else if isDir { tarProvider = tar_io.Factories.TarProvider.Dir(pathToSend, fileFilter) h.logger.Infof("Now starting to send dir '%s'", pathToSend) } else if isFile, err := path_utils.FileExists(pathToSend); err != nil { return fmt.Errorf("Unable to determine if path '%s' is a file, error: %s", pathToSend, err.Error()) } else if isFile { tarProvider = tar_io.Factories.TarProvider.File(pathToSend) h.logger.Infof("Now starting to send file '%s'", pathToSend) } else { return fmt.Errorf("Path '%s' is not an existing file or directory", pathToSend) } handler := &sendTarHandler{writer: c.Response()} err := tar_io.UploadProvider(tarProvider, handler) if err != nil { return fmt.Errorf("Unable to send file, error: %s", err.Error()) } return nil }
func (self InstallController) SetupConfig(ctx echo.Context) error { // config/env.ini 存在 if db.MasterDB != nil { if logic.DefaultInstall.IsTableExist(ctx) { return ctx.Redirect(http.StatusSeeOther, "/") } return ctx.Redirect(http.StatusSeeOther, "/install/do") } step := goutils.MustInt(ctx.QueryParam("step")) if step == 2 { err := self.genConfig(ctx) if err != nil { data := map[string]interface{}{ "dbhost": ctx.FormValue("dbhost"), "dbport": ctx.FormValue("dbport"), "dbname": ctx.FormValue("dbname"), "uname": ctx.FormValue("uname"), "err_type": 1, } if err == db.ConnectDBErr { data["err_type"] = 1 } else if err == db.UseDBErr { data["err_type"] = 2 } return renderInstall(ctx, "install/setup-err.html", data) } } return renderInstall(ctx, "install/setup-config.html", map[string]interface{}{"step": step}) }
// 消息列表 func (MessageController) ReadList(ctx echo.Context) error { user := ctx.Get("user").(*model.Me) msgtype := ctx.Param("msgtype") if msgtype == "" { msgtype = "system" } curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) var ( messages []map[string]interface{} total int64 ) switch msgtype { case "system": messages = logic.DefaultMessage.FindSysMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.SysMsgCount(ctx, user.Uid) case "inbox": messages = logic.DefaultMessage.FindToMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.ToMsgCount(ctx, user.Uid) case "outbox": messages = logic.DefaultMessage.FindFromMsgsByUid(ctx, user.Uid, paginator) total = logic.DefaultMessage.FromMsgCount(ctx, user.Uid) default: return ctx.Redirect(http.StatusSeeOther, "/") } pageHtml := paginator.SetTotal(total).GetPageHtml(fmt.Sprintf("/message/%s", msgtype)) return render(ctx, "messages/list.html", map[string]interface{}{"messages": messages, "msgtype": msgtype, "page": template.HTML(pageHtml)}) }
func (h *handler) handleStatsFunc(c echo.Context) error { path := c.QueryParam("path") if strings.TrimSpace(path) == "" { return fmt.Errorf("Request does not contain query 'path' value") } info, err := os.Stat(path) if err != nil { if os.IsNotExist(err) { return c.JSON(200, &dtos.StatsDto{ Path: path, Exists: false, }) } return fmt.Errorf("Unable to get stats of path '%s', error: %s", path, err.Error()) } returnDto := &dtos.StatsDto{ Path: path, Exists: true, IsDir: info.IsDir(), ModTime: info.ModTime(), Mode: info.Mode(), Size: info.Size(), } return c.JSON(200, returnDto) }
// ReadList 获得wiki列表 func (WikiController) ReadList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) wikis := logic.DefaultWiki.FindBy(ctx, limit+5, lastId) if wikis == nil { logger.Errorln("wiki controller: find wikis error") return ctx.Redirect(http.StatusSeeOther, "/wiki") } num := len(wikis) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } return ctx.Redirect(http.StatusSeeOther, "/wiki") } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId != 0 { prevId = lastId // 避免因为wiki下线,导致判断错误(所以 > 5) if prevId-wikis[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true wikis = wikis[:limit] nextId = wikis[limit-1].Id } else { nextId = wikis[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } // 获取当前用户喜欢对象信息 // me, ok := ctx.Get("user").(*model.Me) // var likeFlags map[int]int // if ok { // likeFlags, _ = logic.DefaultLike.FindUserLikeObjects(ctx, me.Uid, model.TypeWiki, wikis[0].Id, nextId) // } return render(ctx, "wiki/list.html", map[string]interface{}{"wikis": wikis, "activeWiki": "active", "page": pageInfo}) }
func (h *handler) handlePathSummaryFunc(c echo.Context) error { path := c.QueryParam("path") if strings.TrimSpace(path) == "" { return fmt.Errorf("Request does not contain query 'path' value") } info, err := os.Stat(path) if err != nil { if os.IsNotExist(err) { //TODO: Return empty dir instead of NotFound so that on the other side it will result in a "out of sync" status? //return c.JSON(http.StatusNotFound, &dtos.FilesystemSummaryDto{ return c.JSON(200, &dtos.FilesystemSummaryDto{ FlattenedFiles: []*dtos.FileSummary{ &dtos.FileSummary{}, }, }) } return fmt.Errorf("Unable to get stats of path '%s', error: %s", path, err.Error()) } baseDir := "" flattenedFiles := []*dtos.FileSummary{} if info.IsDir() { dirSummary, err := h.svcs.FilePathSummaries.GetDirSummary(path) if err != nil { return fmt.Errorf("Cannot get dir '%s' summary, error: %s", path, err.Error()) } baseDir = path for _, f := range dirSummary.FlattenedFileSummaries { flattenedFiles = append(flattenedFiles, &dtos.FileSummary{ RelativePath: f.RelativePath, ModTime: f.ModTime, ChecksumHex: f.Checksum.HexString(), }) } } else { //TODO: 2016-05-09 20:57 - it is hacky to use an empty basedir and full path for single files. See other spot where we reference this timestamp in the TODO baseDir = "" fileSummary, err := h.svcs.FilePathSummaries.GetFileSummary(baseDir, path) if err != nil { return fmt.Errorf("Cannot get file '%s' summary, error: %s", path, err.Error()) } flattenedFiles = append(flattenedFiles, &dtos.FileSummary{ RelativePath: fileSummary.RelativePath, ModTime: fileSummary.ModTime, ChecksumHex: fileSummary.Checksum.HexString(), }) } returnDto := &dtos.FilesystemSummaryDto{ BaseDir: baseDir, FlattenedFiles: flattenedFiles, } return c.JSON(200, returnDto) }
// ReadCatResources 某个分类的资源列表 func (ResourceController) ReadCatResources(ctx echo.Context) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) catid := goutils.MustInt(ctx.Param("catid")) resources, total := logic.DefaultResource.FindByCatid(ctx, paginator, catid) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) return render(ctx, "resources/index.html", map[string]interface{}{"activeResources": "active", "resources": resources, "categories": logic.AllCategory, "page": template.HTML(pageHtml), "curCatid": catid}) }
// ReadList 开源项目列表页 func (ProjectController) ReadList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) projects := logic.DefaultProject.FindBy(ctx, limit+5, lastId) num := len(projects) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/projects") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-projects[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true projects = projects[:limit] nextId = projects[limit-1].Id } else { nextId = projects[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } // 获取当前用户喜欢对象信息 me, ok := ctx.Get("user").(*model.Me) var likeFlags map[int]int if ok { likeFlags, _ = logic.DefaultLike.FindUserLikeObjects(ctx, me.Uid, model.TypeProject, projects[0].Id, nextId) } return render(ctx, "projects/list.html", map[string]interface{}{"projects": projects, "activeProjects": "active", "page": pageInfo, "likeflags": likeFlags}) }
// Get all tags func (*TagsController) Get(c echo.Context) error { var model models.Tag var name = c.QueryParam("name") ret, err := model.Get(name) if err != nil { return c.JSON(400, utils.ErrMarshal(err.Error())) } return c.JSON(200, ret) }
// Get posts func (*PostsController) Get(c echo.Context) error { var model models.Post var title = c.QueryParam("title") ret, err := model.Get(title) if err != nil { return c.JSON(400, utils.ErrMarshal(err.Error())) } return c.JSON(200, ret) }
// CheckExist 检测 uri 对应的项目是否存在(验证,true表示不存在;false表示存在) func (ProjectController) CheckExist(ctx echo.Context) error { uri := ctx.QueryParam("uri") if uri == "" { return ctx.JSON(http.StatusOK, `true`) } if logic.DefaultProject.UriExists(ctx, uri) { return ctx.JSON(http.StatusOK, `false`) } return ctx.JSON(http.StatusOK, `true`) }
func (handlerGroup *HandlerGroup) CallbackHandler(context echo.Context) error { domain := "jessemillar.auth0.com" // Instantiating the OAuth2 package to exchange the Code for a Token conf := &oauth2.Config{ ClientID: os.Getenv("AUTH0_CLIENT_ID"), ClientSecret: os.Getenv("AUTH0_CLIENT_SECRET"), RedirectURL: os.Getenv("AUTH0_CALLBACK"), Scopes: []string{"openid", "name", "email", "nickname"}, Endpoint: oauth2.Endpoint{ AuthURL: "https://" + domain + "/authorize", TokenURL: "https://" + domain + "/oauth/token", }, } // Getting the Code that we got from Auth0 code := context.QueryParam("code") // Exchanging the code for a token token, err := conf.Exchange(oauth2.NoContext, code) if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Getting the user information client := conf.Client(oauth2.NoContext, token) resp, err := client.Get("https://" + domain + "/userinfo") if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Reading the body raw, err := ioutil.ReadAll(resp.Body) defer resp.Body.Close() if err != nil { return context.String(http.StatusInternalServerError, err.Error()) } // Unmarshal the JSON of the Auth0 profile var profile map[string]interface{} if err := json.Unmarshal(raw, &profile); err != nil { return context.String(http.StatusInternalServerError, err.Error()) } helpers.MakeCookie(context, "id_token", token.Extra("id_token").(string)) // Redirect to logged in page context.Redirect(http.StatusMovedPermanently, "/frontend") return context.String(http.StatusOK, "Callback finished") // We'll never actually hit this...? }
// NodeTopics 某节点下的主题列表 func (TopicController) NodeTopics(ctx echo.Context) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) querystring, nid := "nid=?", goutils.MustInt(ctx.Param("nid")) topics := logic.DefaultTopic.FindAll(ctx, paginator, "topics.mtime DESC", querystring, nid) total := logic.DefaultTopic.Count(ctx, querystring, nid) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) // 当前节点信息 node := logic.GetNode(nid) return render(ctx, "topics/node.html", map[string]interface{}{"activeTopics": "active", "topics": topics, "page": template.HTML(pageHtml), "total": total, "node": node}) }
// ReadingList 晨读列表页 func (ReadingController) ReadingList(ctx echo.Context) error { limit := 20 lastId := goutils.MustInt(ctx.QueryParam("lastid")) rtype := goutils.MustInt(ctx.QueryParam("rtype"), model.RtypeGo) readings := logic.DefaultReading.FindBy(ctx, limit+5, rtype, lastId) num := len(readings) if num == 0 { if lastId == 0 { return ctx.Redirect(http.StatusSeeOther, "/") } else { return ctx.Redirect(http.StatusSeeOther, "/readings") } } var ( hasPrev, hasNext bool prevId, nextId int ) if lastId > 0 { prevId = lastId // 避免因为项目下线,导致判断错误(所以 > 5) if prevId-readings[0].Id > 5 { hasPrev = false } else { prevId += limit hasPrev = true } } if num > limit { hasNext = true readings = readings[:limit] nextId = readings[limit-1].Id } else { nextId = readings[num-1].Id } pageInfo := map[string]interface{}{ "has_prev": hasPrev, "prev_id": prevId, "has_next": hasNext, "next_id": nextId, } return render(ctx, "readings/list.html", map[string]interface{}{"activeReadings": "active", "readings": readings, "page": pageInfo, "rtype": rtype}) }
// http localhost:5025/admin/get-users?q=<query> X-Diskette-Session-Token:<session_token> func (service *serviceImpl) GetUsers(c echo.Context) error { var query map[string]interface{} queryStr := c.QueryParam("q") if queryStr != "" { if err := json.Unmarshal([]byte(queryStr), &query); err != nil { return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err)) } } var documents []interface{} err := service.userCollection.Find(query).All(&documents) if err != nil { return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err)) } return c.JSON(http.StatusOK, util.CreateOkResponse(documents)) }
// WrapUrl 包装链接 func (IndexController) WrapUrl(ctx echo.Context) error { tUrl := ctx.QueryParam("u") if tUrl == "" { return ctx.Redirect(http.StatusSeeOther, "/") } if pUrl, err := url.Parse(tUrl); err != nil { return ctx.Redirect(http.StatusSeeOther, tUrl) } else { if !pUrl.IsAbs() { return ctx.Redirect(http.StatusSeeOther, tUrl) } // 本站 domain := config.ConfigFile.MustValue("global", "domain") if strings.Contains(pUrl.Host, domain) { return ctx.Redirect(http.StatusSeeOther, tUrl) } iframeDeny := config.ConfigFile.MustValue("crawl", "iframe_deny") // 检测是否禁止了 iframe 加载 // 看是否在黑名单中 for _, denyHost := range strings.Split(iframeDeny, ",") { if strings.Contains(pUrl.Host, denyHost) { return ctx.Redirect(http.StatusSeeOther, tUrl) } } // 检测会比较慢,进行异步检测,记录下来,以后分析再加黑名单 go func() { resp, err := http.Head(tUrl) if err != nil { logger.Errorln("[iframe] head url:", tUrl, "error:", err) return } defer resp.Body.Close() if resp.Header.Get("X-Frame-Options") != "" { logger.Errorln("[iframe] deny:", tUrl) return } }() } return render(ctx, "wr.html", map[string]interface{}{"url": tUrl}) }
// RecentComment 最新评论 func (SidebarController) RecentComment(ctx echo.Context) error { limit := goutils.MustInt(ctx.QueryParam("limit"), 10) recentComments := logic.DefaultComment.FindRecent(ctx, 0, -1, limit) uids := slices.StructsIntSlice(recentComments, "Uid") users := logic.DefaultUser.FindUserInfos(ctx, uids) result := map[string]interface{}{ "comments": recentComments, } // json encode 不支持 map[int]... for uid, user := range users { result[strconv.Itoa(uid)] = user } return success(ctx, result) }
// Update post func (*PostsController) Update(c echo.Context) error { var model models.Post var payload models.PostPayload var status = c.QueryParam("status") if err := c.Bind(&payload); err != nil { return c.JSON(400, utils.ErrMarshal(err.Error())) } iss := 1 payload.UpdatedBy = iss ret, err := model.Update(c.P(0), payload, status) if err != nil { return c.JSON(400, utils.ErrMarshal(err.Error())) } return c.JSON(200, ret) }
func (TopicController) topicList(ctx echo.Context, view, orderBy, querystring string, args ...interface{}) error { curPage := goutils.MustInt(ctx.QueryParam("p"), 1) paginator := logic.NewPaginator(curPage) topics := logic.DefaultTopic.FindAll(ctx, paginator, orderBy, querystring, args...) total := logic.DefaultTopic.Count(ctx, querystring, args...) pageHtml := paginator.SetTotal(total).GetPageHtml(ctx.Request().URL().Path()) data := map[string]interface{}{ "topics": topics, "activeTopics": "active", "nodes": logic.GenNodes(), "view": view, "page": template.HTML(pageHtml), } return render(ctx, "topics/list.html", data) }
func appTempGet(c echo.Context) error { args := new(types.GetParams) app := new(types.App) args.Region = c.QueryParam("region") if args.Region == "" { args.Region = types.DefaultRegion } args.Id = c.QueryParam("id") err := appTempHandler.Get(args, app) // 获取数据失败 if err != nil { return c.String(http.StatusNotFound, "") } return SendData(c, http.StatusOK, app) }
// Activate 用户激活 func (AccountController) Activate(ctx echo.Context) error { contentTpl := "user/activate.html" data := map[string]interface{}{} param := goutils.Base64Decode(ctx.QueryParam("param")) values, err := url.ParseQuery(param) if err != nil { data["error"] = err.Error() return render(ctx, contentTpl, data) } uuid := values.Get("uuid") timestamp := goutils.MustInt64(values.Get("timestamp")) sign := values.Get("sign") email, ok := regActivateCodeMap[uuid] if !ok { data["error"] = "非法请求!" return render(ctx, contentTpl, data) } if timestamp < time.Now().Add(-4*time.Hour).Unix() { delete(regActivateCodeMap, uuid) // TODO:可以再次发激活邮件? data["error"] = "链接已过期" return render(ctx, contentTpl, data) } user, err := logic.DefaultUser.Activate(ctx, email, uuid, timestamp, sign) if err != nil { data["error"] = err.Error() return render(ctx, contentTpl, data) } delete(regActivateCodeMap, uuid) // 自动登录 SetCookie(ctx, user.Username) return render(ctx, contentTpl, data) }
// examples: // http DELETE localhost:5025/collection/user?q='{"name":"dfreire"}' func (service *serviceImpl) Delete(c echo.Context) error { collection := c.Param("collection") queryStr := c.QueryParam("q") if queryStr == "" { return c.JSON(http.StatusForbidden, util.CreateErrResponse(errors.New("Missing parameter 'q' (for query)"))) } var query map[string]interface{} if err := json.Unmarshal([]byte(queryStr), &query); err != nil { return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err)) } _, err := service.db.C(collection).RemoveAll(query) if err != nil { return c.JSON(http.StatusInternalServerError, util.CreateErrResponse(err)) } return c.JSON(http.StatusOK, util.CreateOkResponse(nil)) }
func appGet(c echo.Context) error { ty := c.QueryParam("type") var returnValue proto.Message var err error var Region = c.QueryParam("region") if ty == "value" { // 获取单个应用信息 args := new(types.GetParams) app := new(types.App) returnValue = app args.Region = Region args.Id = c.QueryParam("id") err = appHandler.Get(args, app) } else { // 获取应用列表 args := new(types.ListParams) applist := new(types.AppList) returnValue = applist args.Region = Region args.Offset = 0 // 列表偏移量 args.Length = 10 // 列表长度 err = appHandler.List(args, applist) } // 获取数据失败 if err != nil { return SendData(c, http.StatusNotFound, returnValue) } return SendData(c, http.StatusOK, returnValue) }
// Publish func (ReadingController) Publish(ctx echo.Context) error { var data = make(map[string]interface{}) if ctx.FormValue("submit") == "1" { user := ctx.Get("user").(*model.Me) errMsg, err := logic.DefaultReading.SaveReading(ctx, ctx.FormParams(), user.Username) if err != nil { return fail(ctx, 1, errMsg) } return success(ctx, nil) } id := goutils.MustInt(ctx.QueryParam("id")) if id != 0 { reading := logic.DefaultReading.FindById(ctx, id) if reading != nil { data["reading"] = reading } } return render(ctx, "reading/modify.html", data) }
// Modify 编辑规则 func (self RuleController) Modify(ctx echo.Context) error { var data = make(map[string]interface{}) if ctx.FormValue("submit") == "1" { user := ctx.Get("user").(*model.Me) errMsg, err := logic.DefaultRule.Save(ctx, ctx.FormParams(), user.Username) if err != nil { return fail(ctx, 1, errMsg) } return success(ctx, nil) } rule := logic.DefaultRule.FindById(ctx, ctx.QueryParam("id")) if rule == nil { return ctx.Redirect(http.StatusSeeOther, ctx.Echo().URI(echo.HandlerFunc(self.RuleList))) } data["rule"] = rule return render(ctx, "rule/modify.html", data) }
// Modify func (self ArticleController) Modify(ctx echo.Context) error { var data = make(map[string]interface{}) if ctx.FormValue("submit") == "1" { user := ctx.Get("user").(*model.Me) errMsg, err := logic.DefaultArticle.Modify(ctx, user, ctx.FormParams()) if err != nil { return fail(ctx, 1, errMsg) } return success(ctx, nil) } article, err := logic.DefaultArticle.FindById(ctx, ctx.QueryParam("id")) if err != nil { return ctx.Redirect(http.StatusSeeOther, ctx.Echo().URI(echo.HandlerFunc(self.ArticleList))) } data["article"] = article data["statusSlice"] = model.ArticleStatusSlice data["langSlice"] = model.LangSlice return render(ctx, "article/modify.html", data) }
// CommentList 获取某对象的评论信息 func (CommentController) CommentList(ctx echo.Context) error { objid := goutils.MustInt(ctx.QueryParam("objid")) objtype := goutils.MustInt(ctx.QueryParam("objtype")) commentList, err := logic.DefaultComment.FindObjectComments(ctx, objid, objtype) if err != nil { return fail(ctx, 1, "服务器内部错误") } uids := slices.StructsIntSlice(commentList, "Uid") users := logic.DefaultUser.FindUserInfos(ctx, uids) result := map[string]interface{}{ "comments": commentList, } // json encode 不支持 map[int]... for uid, user := range users { result[strconv.Itoa(uid)] = user } return success(ctx, result) }
func podGet(c echo.Context) error { var arg = new(types.GetParams) arg.Region = c.QueryParam("region") arg.ParentId = c.QueryParam("appid") arg.Id = c.QueryParam("id") var pod = new(types.Pod) err := podHandler.Get(arg, pod) if err != nil { return SendData(c, http.StatusNotFound, pod) } return SendData(c, http.StatusOK, pod) }
// GetCrop - Fetch and crop an image on the fly func (handler *CropHandler) GetCrop(c echo.Context) error { // Get height and width from url parameters width, _ := strconv.Atoi(c.QueryParam("width")) height, _ := strconv.Atoi(c.QueryParam("height")) // Get file parameter filename := c.QueryParam("file") ext := GetExtension(filename) // If no file given, not much we can do if filename == "" { return c.JSON(http.StatusNotFound, &Error{ Message: "No file given", Code: http.StatusNotFound, }) } // Fetch image from S3 file, err := handler.bucket.Get("content/" + filename) // If file can't be fetched, throw a 404 if err != nil { return c.JSON(http.StatusNotFound, &Error{ Message: "File not found in bucket", Code: http.StatusNotFound, }) } // Decode image from bytes to `image.Image` img, err := handler.decoder.DecodeBytes(file) // Crop image cropped, err := handler.cropper.Crop(uint(width), uint(height), img, ext) if err != nil { return c.JSON(http.StatusInternalServerError, &Error{ Message: err, Code: http.StatusInternalServerError, }) } // Return cropped image return c.File(string(cropped)) }