// 将所有 角色 加载到内存中;后台修改角色时,重新加载一次 func LoadRoles() error { roles := make([]*model.Role, 0) err := MasterDB.Find(&roles) if err != nil { logger.Errorln("LoadRoles role read fail:", err) return err } if len(roles) == 0 { logger.Errorln("LoadRoles role read fail: num is 0") return errors.New("no role") } roleLocker.Lock() defer roleLocker.Unlock() maxRoleid := roles[len(roles)-1].Roleid Roles = make([]*model.Role, maxRoleid) // 由于角色不多,而且一般角色id是连续自增的,因此这里以角色id当slice的index for _, role := range roles { Roles[role.Roleid-1] = role } logger.Infoln("LoadRoles successfully!") return nil }
// SaveReading 保存晨读 func (ReadingLogic) SaveReading(ctx context.Context, form url.Values, username string) (errMsg string, err error) { reading := &model.MorningReading{} err = schemaDecoder.Decode(reading, form) if err != nil { logger.Errorln("reading SaveReading error", err) errMsg = err.Error() return } reading.Moreurls = strings.TrimSpace(reading.Moreurls) if strings.Contains(reading.Moreurls, "\n") { reading.Moreurls = strings.Join(strings.Split(reading.Moreurls, "\n"), ",") } reading.Username = username logger.Debugln(reading.Rtype, "id=", reading.Id) if reading.Id != 0 { _, err = MasterDB.Update(reading) } else { _, err = MasterDB.Insert(reading) } if err != nil { errMsg = "内部服务器错误" logger.Errorln("reading save:", errMsg, ":", err) return } return }
// Parse 获取url对应的资源并根据规则进行解析 func (this *RedditLogic) Parse(redditUrl string) error { redditUrl = strings.TrimSpace(redditUrl) if redditUrl == "" { redditUrl = this.domain + this.golang } else if !strings.HasPrefix(redditUrl, "https") { redditUrl = "https://" + redditUrl } var ( doc *goquery.Document err error ) // if doc, err = goquery.NewDocument(redditUrl); err != nil { if doc, err = this.newDocumentFromResp(redditUrl); err != nil { logger.Errorln("goquery reddit newdocument error:", err) return err } // 最后面的先入库处理 resourcesSelection := doc.Find("#siteTable .link") for i := resourcesSelection.Length() - 1; i >= 0; i-- { err = this.dealRedditOneResource(goquery.NewDocumentFromNode(resourcesSelection.Get(i)).Selection) if err != nil { logger.Errorln(err) } } return err }
// 索引主题 func (self SearcherLogic) IndexingTopic(isAll bool) { solrClient := NewSolrClient() var ( topicList []*model.Topic topicExList map[int]*model.TopicEx err error ) if isAll { id := 0 for { topicList = make([]*model.Topic, 0) topicExList = make(map[int]*model.TopicEx) err = MasterDB.Where("tid>?", id).OrderBy("tid ASC").Limit(self.maxRows).Find(&topicList) if err != nil { logger.Errorln("IndexingTopic error:", err) break } if len(topicList) == 0 { break } tids := util.Models2Intslice(topicList, "Tid") err = MasterDB.In("tid", tids).Find(&topicExList) if err != nil { logger.Errorln("IndexingTopic error:", err) break } for _, topic := range topicList { if id < topic.Tid { id = topic.Tid } topicEx := topicExList[topic.Tid] document := model.NewDocument(topic, topicEx) addCommand := model.NewDefaultArgsAddCommand(document) solrClient.PushAdd(addCommand) } solrClient.Post() } } }
func output(filename string, data map[string]interface{}) (err error) { var file *os.File file, err = os.Create(sitemapPath + filename) if err != nil { logger.Errorln("open file error:", err) return } defer file.Close() if err = sitemapTpl.Execute(file, data); err != nil { logger.Errorln("execute template error:", err) } return }
// 索引资源 func (self SearcherLogic) IndexingResource(isAll bool) { solrClient := NewSolrClient() var ( resourceList []*model.Resource resourceExList map[int]*model.ResourceEx err error ) if isAll { id := 0 for { resourceList = make([]*model.Resource, 0) resourceExList = make(map[int]*model.ResourceEx) err = MasterDB.Where("id>?", id).OrderBy("id ASC").Limit(self.maxRows).Find(&resourceList) if err != nil { logger.Errorln("IndexingResource error:", err) break } if len(resourceList) == 0 { break } ids := util.Models2Intslice(resourceList, "Id") err = MasterDB.In("id", ids).Find(&resourceExList) if err != nil { logger.Errorln("IndexingResource error:", err) break } for _, resource := range resourceList { if id < resource.Id { id = resource.Id } resourceEx := resourceExList[resource.Id] document := model.NewDocument(resource, resourceEx) addCommand := model.NewDefaultArgsAddCommand(document) solrClient.PushAdd(addCommand) } solrClient.Post() } } }
// 会员总数 func (UserLogic) Total() int64 { total, err := MasterDB.Count(new(model.User)) if err != nil { logger.Errorln("UserLogic Total error:", err) } return total }
// 更新该主题的喜欢数 // objid:被喜欢对象id;num: 喜欢数(负数表示取消喜欢) func (self TopicLike) UpdateLike(objid, num int) { // 更新喜欢数(TODO:暂时每次都更新表) _, err := MasterDB.Where("tid=?", objid).Incr("like", num).Update(new(model.TopicEx)) if err != nil { logger.Errorln("更新主题喜欢数失败:", err) } }
// UpdateComment 更新该主题的回复信息 // cid:评论id;objid:被评论对象id;uid:评论者;cmttime:评论时间 func (self TopicComment) UpdateComment(cid, objid, uid int, cmttime time.Time) { // 更新最后回复信息 _, err := MasterDB.Table(new(model.Topic)).Id(objid).Update(map[string]interface{}{ "lastreplyuid": uid, "lastreplytime": cmttime, }) if err != nil { logger.Errorln("更新主题最后回复人信息失败:", err) } // 更新回复数(TODO:暂时每次都更新表) _, err = MasterDB.Id(objid).Incr("reply", 1).Update(new(model.TopicEx)) if err != nil { logger.Errorln("更新主题回复数失败:", err) } }
// Total 博文总数 func (ArticleLogic) Total() int64 { total, err := MasterDB.Count(new(model.Article)) if err != nil { logger.Errorln("ArticleLogic Total error:", err) } return total }
// 更新该项目的喜欢数 // objid:被喜欢对象id;num: 喜欢数(负数表示取消喜欢) func (self ProjectLike) UpdateLike(objid, num int) { // 更新喜欢数(TODO:暂时每次都更新表) _, err := MasterDB.Id(objid).Incr("likenum", num).Update(new(model.OpenProject)) if err != nil { logger.Errorln("更新项目喜欢数失败:", err) } }
func (this *SystemMessage) SetExt(ext map[string]interface{}) { if extBytes, err := json.Marshal(ext); err != nil { logger.Errorln("SystemMessage SetExt JsonMarshal Error:", err) } else { this.Ext = string(extBytes) } }
// Total 开源项目总数 func (ProjectLogic) Total() int64 { total, err := MasterDB.Count(new(model.OpenProject)) if err != nil { logger.Errorln("ProjectLogic Total error:", err) } return total }
func (this *UploaderLogic) uploadLocalFile(localFile, key string) (err error) { this.genUpToken() var ret io.PutRet var extra = &io.PutExtra{ // Params: params, // MimeType: mieType, // Crc32: crc32, // CheckCrc: CheckCrc, } // ret 变量用于存取返回的信息,详情见 io.PutRet // uptoken 为业务服务器生成的上传口令 // key 为文件存储的标识(文件名) // localFile 为本地文件名 // extra 为上传文件的额外信息,详情见 io.PutExtra,可选 err = io.PutFile(nil, &ret, this.uptoken, key, localFile, extra) if err != nil { //上传产生错误 logger.Errorln("io.PutFile failed:", err) return } //上传成功,处理返回值 logger.Debugln(ret.Hash, ret.Key) return }
// 更新该文章的喜欢数 // objid:被喜欢对象id;num: 喜欢数(负数表示取消喜欢) func (self ArticleLike) UpdateLike(objid, num int) { // 更新喜欢数(TODO:暂时每次都更新表) _, err := MasterDB.Where("id=?", objid).Incr("likenum", num).Update(new(model.Article)) if err != nil { logger.Errorln("更新文章喜欢数失败:", err) } }
// Total 资源总数 func (ResourceLogic) Total() int64 { total, err := MasterDB.Count(new(model.Resource)) if err != nil { logger.Errorln("CommentLogic Total error:", err) } return total }
// UpdateComment 更新该文章的评论信息 // cid:评论id;objid:被评论对象id;uid:评论者;cmttime:评论时间 func (self ArticleComment) UpdateComment(cid, objid, uid int, cmttime time.Time) { // 更新评论数(TODO:暂时每次都更新表) _, err := MasterDB.Id(objid).Incr("cmtnum", 1).Update(new(model.Article)) if err != nil { logger.Errorln("更新文章评论数失败:", err) } }
func decrUserActiveWeight() { logger.Debugln("start decr user active weight...") loginTime := time.Now().Add(-72 * time.Hour) userList, err := logic.DefaultUser.FindNotLoginUsers(loginTime) if err != nil { logger.Errorln("获取最近未登录用户失败:", err) return } logger.Debugln("need dealing users:", len(userList)) for _, user := range userList { divide := 5 if err == nil { hours := (loginTime.Sub(user.LoginTime) / 24).Hours() if hours < 24 { divide = 2 } else if hours < 48 { divide = 3 } else if hours < 72 { divide = 4 } } logger.Debugln("decr user weight, username:"******"divide:", divide) logic.DefaultUser.DecrUserWeight("username", user.Username, divide) } logger.Debugln("end decr user active weight...") }
// 将所有 角色拥有的权限 加载到内存中;后台修改时,重新加载一次 func LoadRoleAuthorities() error { roleAuthorities := make([]*model.RoleAuthority, 0) err := MasterDB.Find(&roleAuthorities) if err != nil { logger.Errorln("LoadRoleAuthorities role_authority read fail:", err) return err } roleAuthLocker.Lock() defer roleAuthLocker.Unlock() RoleAuthorities = make(map[int][]int) for _, roleAuth := range roleAuthorities { roleId := roleAuth.Roleid if authorities, ok := RoleAuthorities[roleId]; ok { RoleAuthorities[roleId] = append(authorities, roleAuth.Aid) } else { RoleAuthorities[roleId] = []int{roleAuth.Aid} } } logger.Infoln("LoadRoleAuthorities successfully!") return nil }
// 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 saveMaxOnlineNum() { data := []byte(strconv.Itoa(MaxOnlineNum())) err := ioutil.WriteFile(getDataFile(), data, 0777) if err != nil { logger.Errorln("write data file error:", err) return } }
func (this *SystemMessage) GetExt() map[string]interface{} { result := make(map[string]interface{}) if err := json.Unmarshal([]byte(this.Ext), &result); err != nil { logger.Errorln("SystemMessage Ext JsonUnmarshal Error:", err) return nil } return result }
// 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}) }
// FindRecent 获得某个用户最近发布的开源项目 func (ProjectLogic) FindRecent(ctx context.Context, username string) []*model.OpenProject { projectList := make([]*model.OpenProject, 0) err := MasterDB.Where("username=?", username).Limit(5).OrderBy("id DESC").Find(&projectList) if err != nil { logger.Errorln("project logic FindRecent error:", err) return nil } return projectList }
func (EmailLogic) genEmailContent(data map[string]interface{}) (string, error) { buffer := &bytes.Buffer{} if err := emailTpl.Execute(buffer, data); err != nil { logger.Errorln("email logic execute template error:", err) return "", err } return buffer.String(), nil }
// FindById 获取单条博文 func (ArticleLogic) FindById(ctx context.Context, id string) (*model.Article, error) { article := &model.Article{} _, err := MasterDB.Id(id).Get(article) if err != nil { logger.Errorln("article logic FindById Error:", err) } return article, err }
// getOwner 通过tid获得话题的所有者 func (TopicLogic) getOwner(tid int) int { topic := &model.Topic{} _, err := MasterDB.Id(tid).Get(topic) if err != nil { logger.Errorln("topic logic getOwner Error:", err) return 0 } return topic.Uid }
// getOwner 通过id获得wiki的所有者 func (WikiLogic) getOwner(id int) int { wiki := &model.Wiki{} _, err := MasterDB.Id(id).Get(wiki) if err != nil { logger.Errorln("wiki logic getOwner Error:", err) return 0 } return wiki.Uid }
// FindBy 获取动态列表(分页) func (DynamicLogic) FindBy(ctx context.Context, lastId int, limit int) []*model.Dynamic { dynamicList := make([]*model.Dynamic, 0) err := MasterDB.Where("id>?", lastId).OrderBy("seq DESC").Limit(limit).Find(&dynamicList) if err != nil { logger.Errorln("DynamicLogic FindBy Error:", err) } return dynamicList }
// getOwner 通过id获得资源的所有者 func (ResourceLogic) getOwner(id int) int { resource := &model.Resource{} _, err := MasterDB.Id(id).Get(resource) if err != nil { logger.Errorln("resource logic getOwner Error:", err) return 0 } return resource.Uid }