// 获得资源详细信息 func FindResource(id string) (resourceMap map[string]interface{}, comments []map[string]interface{}) { condition := "id=" + id resource := model.NewResource() err := resource.Where(condition).Find() if err != nil { logger.Errorln("resource service FindResource error:", err) return } resourceMap = make(map[string]interface{}) util.Struct2Map(resourceMap, resource) resourceMap["catname"] = GetCategoryName(resource.Catid) // 链接的host if resource.Form == model.LinkForm { urlObj, err := url.Parse(resource.Url) if err == nil { resourceMap["host"] = urlObj.Host } } else { resourceMap["url"] = "/resources/" + strconv.Itoa(resource.Id) } resourceEx := model.NewResourceEx() err = resourceEx.Where(condition).Find() if err != nil { logger.Errorln("resource service FindResource Error:", err) return } util.Struct2Map(resourceMap, resourceEx) // 评论信息 comments, ownerUser, _ := FindObjComments(id, strconv.Itoa(model.TYPE_RESOURCE), resource.Uid, 0) resourceMap["user"] = ownerUser return }
// 增加资源 func PublishResource(uid int, form url.Values) bool { resource := model.NewResource() err := util.ConvertAssign(resource, form) if err != nil { logger.Errorln("user ConvertAssign error", err) return false } resource.Ctime = time.Now().Format("2006-01-02 15:04:05") resource.Uid = uid id, err := resource.Insert() if err != nil { logger.Errorln("PublishResource error:", err) return false } // 发布资源,活跃度+10 go IncUserWeight("uid="+strconv.Itoa(uid), 10) // 入扩展表 resourceEx := model.NewResourceEx() resourceEx.Id = int(id) if _, err := resourceEx.Insert(); err != nil { logger.Errorln("PublishResource Ex error:", err) return false } return true }
// 更新该主题的喜欢数 // objid:被喜欢对象id;num: 喜欢数(负数表示取消喜欢) func (self ResourceLike) UpdateLike(objid, num int) { // 更新喜欢数(TODO:暂时每次都更新表) err := model.NewResourceEx().Where("id=?", objid).Increment("likenum", num) if err != nil { logger.Errorln("更新资源喜欢数失败:", err) } }
// 更新该资源的评论信息 // cid:评论id;objid:被评论对象id;uid:评论者;cmttime:评论时间 func (self ResourceComment) UpdateComment(cid, objid, uid int, cmttime string) { id := strconv.Itoa(objid) // 更新评论数(TODO:暂时每次都更新表) err := model.NewResourceEx().Where("id="+id).Increment("cmtnum", 1) if err != nil { logger.Errorln("更新资源评论数失败:", err) } }
// 索引资源 func IndexingResource(isAll bool) { solrClient := NewSolrClient() resourceObj := model.NewResource() resourceExObj := model.NewResourceEx() limit := strconv.Itoa(MaxRows) if isAll { id := 0 for { resourceList, err := resourceObj.Where("id>?", id).Limit(limit).FindAll() if err != nil { logger.Errorln("IndexingResource error:", err) break } if len(resourceList) == 0 { break } ids := util.Models2Intslice(resourceList, "Id") tmpStr := strings.Repeat("?,", len(ids)) query := "id in(" + tmpStr[:len(tmpStr)-1] + ")" args := make([]interface{}, len(ids)) for i, rid := range ids { args[i] = rid } resourceExList, err := resourceExObj.Where(query, args...).FindAll() if err != nil { logger.Errorln("IndexingResource error:", err) break } resourceExMap := make(map[int]*model.ResourceEx, len(resourceExList)) for _, resourceEx := range resourceExList { resourceExMap[resourceEx.Id] = resourceEx } for _, resource := range resourceList { if id < resource.Id { id = resource.Id } resourceEx, _ := resourceExMap[resource.Id] document := model.NewDocument(resource, resourceEx) addCommand := model.NewDefaultArgsAddCommand(document) solrClient.Push(addCommand) } solrClient.Post() } } }
// 获得某个分类的资源列表 func FindResourcesByCatid(catid string) []map[string]interface{} { resourceList, err := model.NewResource().Where("catid=" + catid).Order("mtime DESC").FindAll() if err != nil { logger.Errorln("resource service FindResourcesByCatid error:", err) return nil } count := len(resourceList) ids := make([]int, count) uids := make(map[int]int) for i, resource := range resourceList { ids[i] = resource.Id uids[resource.Uid] = resource.Uid } // 获取扩展信息(计数) resourceExList, err := model.NewResourceEx().Where("id in(" + util.Join(ids, ",") + ")").FindAll() if err != nil { logger.Errorln("resource service FindResourcesByCatid Error:", err) return nil } resourceExMap := make(map[int]*model.ResourceEx, len(resourceExList)) for _, resourceEx := range resourceExList { resourceExMap[resourceEx.Id] = resourceEx } userMap := getUserInfos(uids) resources := make([]map[string]interface{}, count) for i, resource := range resourceList { tmpMap := make(map[string]interface{}) util.Struct2Map(tmpMap, resource) util.Struct2Map(tmpMap, resourceExMap[resource.Id]) tmpMap["user"] = userMap[resource.Uid] // 链接的host if resource.Form == model.LinkForm { urlObj, err := url.Parse(resource.Url) if err == nil { tmpMap["host"] = urlObj.Host } } else { tmpMap["url"] = "/resources/" + strconv.Itoa(resource.Id) } resources[i] = tmpMap } return resources }
// flush 将浏览数刷入数据库中 func (this *view) flush() { this.locker.Lock() defer this.locker.Unlock() objid := strconv.Itoa(this.objid) switch this.objtype { case model.TYPE_TOPIC: model.NewTopicEx().Where("tid="+objid).Increment("view", this.num) case model.TYPE_ARTICLE: model.NewArticle().Where("id="+objid).Increment("viewnum", this.num) case model.TYPE_RESOURCE: model.NewResourceEx().Where("id="+objid).Increment("viewnum", this.num) case model.TYPE_PROJECT: model.NewOpenProject().Where("id="+objid).Increment("viewnum", this.num) } this.num = 0 }
// 处理 Reddit 中的一条资源 func dealRedditOneResource(contentSelection *goquery.Selection) error { aSelection := contentSelection.Find(".title a.title") title := aSelection.Text() if title == "" { return errors.New("title is empty") } resourceUrl, ok := aSelection.Attr("href") if !ok || resourceUrl == "" { return errors.New("resource url is empty") } isReddit := false resource := model.NewResource() // Reddit 自身的内容 if contentSelection.HasClass("self") { isReddit = true resourceUrl = Reddit + resourceUrl } err := resource.Where("url=?", resourceUrl).Find("id") // 已经存在 if resource.Id != 0 { // 如果是 reddit 本身的,可以更新评论信息 if !isReddit { return errors.New("url" + resourceUrl + "has exists!") } } if isReddit { resource.Form = model.ContentForm var doc *goquery.Document if doc, err = goquery.NewDocument(resourceUrl); err != nil { return errors.New("goquery reddit.com/r/golang self newdocument error:" + err.Error()) } content, err := doc.Find("#siteTable .usertext .md").Html() if err != nil { return err } doc.Find(".commentarea .comment .usertext .md").Each(func(i int, contentSel *goquery.Selection) { if i == 0 { content += `<hr/>**评论:**<br/><br/>` } comment, err := contentSel.Html() if err != nil { return } comment = strings.TrimSpace(comment) comment = resourceRe.ReplaceAllLiteralString(comment, "\n") author := contentSel.ParentsFiltered(".usertext").Prev().Find(".author").Text() content += author + ": <pre>" + comment + "</pre>" }) if strings.TrimSpace(content) == "" { return errors.New("goquery reddit.com/r/golang self newdocument(" + resourceUrl + ") error: content is empty") } resource.Content = content // reddit 本身的,当做其他资源 resource.Catid = 4 } else { resource.Form = model.LinkForm // Github,是开源项目 if contentSelection.Find(".title .domain a").Text() == "github.com" { resource.Catid = 2 } else { resource.Catid = 1 } } resource.Title = title resource.Url = resourceUrl resource.Uid = PresetUids[rand.Intn(4)] ctime := util.TimeNow() datetime, ok := contentSelection.Find(".tagline time").Attr("datetime") if ok { dtime, err := time.ParseInLocation(time.RFC3339, datetime, time.UTC) if err != nil { logger.Errorln("parse ctime error:", err) } else { ctime = dtime.Local().Format("2006-01-02 15:04:05") } } resource.Ctime = ctime if resource.Id == 0 { var id int64 id, err = resource.Insert() if err != nil { return errors.New("insert into Resource error:" + err.Error()) } // 存扩展信息 resourceEx := model.NewResourceEx() resourceEx.Id = int(id) if _, err = resourceEx.Insert(); err != nil { return errors.New("insert into ResourceEx error:" + err.Error()) } } else { if err = resource.Persist(resource); err != nil { return errors.New("persist resource:" + strconv.Itoa(resource.Id) + " error:" + err.Error()) } } return nil }
// 增加(修改)资源 func PublishResource(user map[string]interface{}, form url.Values) (err error) { uid := user["uid"].(int) resource := model.NewResource() if form.Get("id") != "" { err = resource.Where("id=?", form.Get("id")).Find() if err != nil { logger.Errorln("Publish Resource find error:", err) return } isAdmin := false if _, ok := user["isadmin"]; ok { isAdmin = user["isadmin"].(bool) } if resource.Uid != uid && !isAdmin { err = NotModifyAuthorityErr return } fields := []string{"title", "catid", "form", "url", "content"} if form.Get("form") == model.LinkForm { form.Set("content", "") } else { form.Set("url", "") } id := form.Get("id") query, args := updateSetClause(form, fields) err = resource.Set(query, args...).Where("id=?", id).Update() if err != nil { logger.Errorf("更新資源 【%s】 信息失败:%s\n", id, err) return } // 修改資源,活跃度+2 go IncUserWeight("uid="+strconv.Itoa(uid), 2) } else { util.ConvertAssign(resource, form) resource.Uid = uid resource.Ctime = util.TimeNow() var id int64 id, err = resource.Insert() if err != nil { logger.Errorln("Publish Resource error:", err) return } // 存扩展信息 resourceEx := model.NewResourceEx() resourceEx.Id = int(id) if _, err = resourceEx.Insert(); err != nil { logger.Errorln("PublishResource Ex error:", err) return } // 给 被@用户 发系统消息 /* ext := map[string]interface{}{ "objid": id, "objtype": model.TYPE_RESOURCE, "uid": user["uid"], "msgtype": model.MsgtypePublishAtMe, } go SendSysMsgAtUsernames(form.Get("usernames"), ext) */ // 发布主题,活跃度+10 go IncUserWeight("uid="+strconv.Itoa(uid), 10) } return }
// 获得某个分类的资源列表 // page 当前第几页 func FindResourcesByCatid(catid string, page int) (resources []map[string]interface{}, total int) { var offset = 0 if page > 1 { offset = (page - 1) * PAGE_NUM } resourceObj := model.NewResource() limit := strconv.Itoa(offset) + "," + strconv.Itoa(PAGE_NUM) resourceList, err := resourceObj.Where("catid=?", catid).Order("mtime DESC").Limit(limit).FindAll() if err != nil { logger.Errorln("resource service FindResourcesByCatid error:", err) return } // 获得该类别总资源数 total, err = resourceObj.Count() if err != nil { logger.Errorln("resource service resourceObj.Count Error:", err) return } count := len(resourceList) ids := make([]int, count) uids := make([]int, count) for i, resource := range resourceList { ids[i] = resource.Id uids[i] = resource.Uid } // 获取扩展信息(计数) resourceExList, err := model.NewResourceEx().Where("id in(" + util.Join(ids, ",") + ")").FindAll() if err != nil { logger.Errorln("resource service FindResourcesByCatid Error:", err) return } resourceExMap := make(map[int]*model.ResourceEx, len(resourceExList)) for _, resourceEx := range resourceExList { resourceExMap[resourceEx.Id] = resourceEx } userMap := GetUserInfos(uids) resources = make([]map[string]interface{}, count) for i, resource := range resourceList { tmpMap := make(map[string]interface{}) util.Struct2Map(tmpMap, resource) util.Struct2Map(tmpMap, resourceExMap[resource.Id]) tmpMap["user"] = userMap[resource.Uid] // 链接的host if resource.Form == model.LinkForm { urlObj, err := url.Parse(resource.Url) if err == nil { tmpMap["host"] = urlObj.Host } } else { tmpMap["url"] = "/resources/" + strconv.Itoa(resource.Id) } resources[i] = tmpMap } return }