Пример #1
0
// 某个wiki页面详细信息
func FindWiki(uri string) map[string]interface{} {
	wiki := model.NewWiki()
	if err := wiki.Where("uri=" + uri).Find(); err != nil {
		logger.Errorln("wiki service FindWiki error:", err)
		return nil
	}
	uids := make(map[int]int)
	uids[wiki.Uid] = wiki.Uid
	if wiki.Cuid != "" {
		cuids := strings.Split(wiki.Cuid, ",")
		for _, cuid := range cuids {
			tmpUid := util.MustInt(cuid)
			uids[tmpUid] = tmpUid
		}
	}
	userMap := getUserInfos(uids)
	result := make(map[string]interface{})
	util.Struct2Map(result, wiki)
	result["user"] = userMap[wiki.Uid]
	if wiki.Cuid != "" {
		cuids := strings.Split(wiki.Cuid, ",")
		cusers := make([]*model.User, len(cuids))
		for i, cuid := range cuids {
			cusers[i] = userMap[util.MustInt(cuid)]
		}
		result["cuser"] = cusers
	}
	return result
}
Пример #2
0
// 收藏(取消收藏)
// uri: /favorite/{objid:[0-9]+}.json
func FavoriteHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	user, _ := filter.CurrentUser(req)

	if !util.CheckInt(req.PostForm, "objtype") {
		fmt.Fprint(rw, `{"ok": 0, "error":"参数错误"}`)
		return
	}

	var err error

	objtype := util.MustInt(req.PostFormValue("objtype"))
	collect := util.MustInt(req.PostFormValue("collect"))
	if collect == 1 {
		err = service.SaveFavorite(user["uid"].(int), util.MustInt(vars["objid"]), objtype)
	} else {
		err = service.CancelFavorite(user["uid"].(int), util.MustInt(vars["objid"]), objtype)
	}

	if err != nil {
		fmt.Fprint(rw, `{"ok": 0, "error":"`+err.Error()+`""}`)
		return
	}

	fmt.Fprint(rw, `{"ok": 1, "message":"success"}`)
}
Пример #3
0
// checkRange 检查范围值是否合法。
// src为要检查的值;destRange为目标范围;msg出错时信息参数
func checkRange(src int, destRange string, msg string) (errMsg string) {
	parts := strings.SplitN(destRange, ",", 2)
	parts[0] = strings.TrimSpace(parts[0])
	parts[1] = strings.TrimSpace(parts[1])
	min, max := 0, 0
	if parts[0] == "" {
		max = util.MustInt(parts[1])
		if src > max {
			errMsg = fmt.Sprintf(msg, max)
		}
		return
	}
	if parts[1] == "" {
		min = util.MustInt(parts[0])
		if src < min {
			errMsg = fmt.Sprintf(msg, min)
		}
		return
	}
	if min == 0 {
		min = util.MustInt(parts[0])
	}
	if max == 0 {
		max = util.MustInt(parts[1])
	}
	if src < min || src > max {
		errMsg = fmt.Sprintf(msg, min, max)
		return
	}
	return
}
Пример #4
0
// 喜欢(或取消喜欢)
// uri: /like/{objid:[0-9]+}.json
func LikeHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	user, _ := filter.CurrentUser(req)
	// 入库
	err := service.PostComment(util.MustInt(vars["objid"]), util.MustInt(req.FormValue("objtype")), user["uid"].(int), req.FormValue("content"), req.FormValue("objname"))
	if err != nil {
		fmt.Fprint(rw, `{"errno": 1, "error":"服务器内部错误"}`)
		return
	}
	fmt.Fprint(rw, `{"errno": 0, "error":""}`)
}
Пример #5
0
// 获得发给某人的短消息(收件箱)
func FindToMsgsByUid(uid string) []map[string]interface{} {
	messages, err := model.NewMessage().Where("to=" + uid + " AND tdel=" + model.TdelNotDel).Order("ctime DESC").FindAll()
	if err != nil {
		logger.Errorln("message service FindToMsgsByUid Error:", err)
		return nil
	}
	uids := make(map[int]int)
	ids := make([]int, 0, len(messages))
	for _, message := range messages {
		uids[message.From] = message.From
		if message.Hasread == model.NotRead {
			ids = append(ids, message.Id)
		}
	}
	// 标记已读
	go MarkHasRead(ids, false, util.MustInt(uid))
	userMap := getUserInfos(uids)
	result := make([]map[string]interface{}, len(messages))
	for i, message := range messages {
		tmpMap := make(map[string]interface{})
		util.Struct2Map(tmpMap, message)
		tmpMap["user"] = userMap[message.From]
		// 为了跟系统消息一致
		tmpMap["title"] = "发来了一条消息:"
		result[i] = tmpMap
	}
	return result
}
Пример #6
0
// 评论(或回复)
// uri: /comment/{objid:[0-9]+}.json
func CommentHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	user, _ := filter.CurrentUser(req)

	if !util.CheckInt(req.PostForm, "objtype") {
		fmt.Fprint(rw, `{"errno": 1, "error":"参数错误"}`)
		return
	}

	// 入库
	comment, err := service.PostComment(user["uid"].(int), util.MustInt(vars["objid"]), req.PostForm)
	if err != nil {
		fmt.Fprint(rw, `{"errno": 1, "error":"服务器内部错误"}`)
		return
	}

	buf, err := json.Marshal(comment)
	if err != nil {
		logger.Errorln("[RecentCommentHandler] json.marshal error:", err)
		fmt.Fprint(rw, `{"errno": 1, "error":"解析json出错"}`)
		return
	}

	fmt.Fprint(rw, `{"errno": 0, "error":"", "data":`+string(buf)+`}`)
}
Пример #7
0
// 社区帖子详细页
// uri: /topics/{tid:[0-9]+}
func TopicDetailHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)

	topic, replies, err := service.FindTopicByTid(vars["tid"])
	if err != nil {
		util.Redirect(rw, req, "/topics")
		return
	}

	likeFlag := 0
	hadCollect := 0
	user, ok := filter.CurrentUser(req)
	if ok {
		uid := user["uid"].(int)
		tid := topic["tid"].(int)
		likeFlag = service.HadLike(uid, tid, model.TYPE_TOPIC)
		hadCollect = service.HadFavorite(uid, tid, model.TYPE_TOPIC)
	}

	service.Views.Incr(req, model.TYPE_TOPIC, util.MustInt(vars["tid"]))

	// 设置内容模板
	req.Form.Set(filter.CONTENT_TPL_KEY, "/template/topics/detail.html,/template/common/comment.html")
	// 设置模板数据
	filter.SetData(req, map[string]interface{}{"activeTopics": "active", "topic": topic, "replies": replies, "likeflag": likeFlag, "hadcollect": hadCollect})
}
Пример #8
0
// 新建帖子
// uri: /topics/new{json:(|.json)}
func NewTopicHandler(rw http.ResponseWriter, req *http.Request) {
	nodes := genNodes()
	vars := mux.Vars(req)
	title := req.FormValue("title")
	// 请求新建帖子页面
	if title == "" || req.Method != "POST" || vars["json"] == "" {
		req.Form.Set(filter.CONTENT_TPL_KEY, "/template/topics/new.html")
		filter.SetData(req, map[string]interface{}{"nodes": nodes})
		return
	}

	user, _ := filter.CurrentUser(req)
	// 入库
	topic := model.NewTopic()
	topic.Uid = user["uid"].(int)
	topic.Nid = util.MustInt(req.FormValue("nid"))
	topic.Title = req.FormValue("title")
	topic.Content = req.FormValue("content")
	errMsg, err := service.PublishTopic(topic)
	if err != nil {
		fmt.Fprint(rw, `{"errno": 1, "error":"`, errMsg, `"}`)
		return
	}
	fmt.Fprint(rw, `{"errno": 0, "error":""}`)
}
Пример #9
0
// 发表评论(或回复)。
// objid 注册的评论对象
// uid 评论人
func PostComment(uid, objid int, form url.Values) (*model.Comment, error) {
	comment := model.NewComment()
	comment.Objid = objid
	objtype := util.MustInt(form.Get("objtype"))
	comment.Objtype = objtype
	comment.Uid = uid
	comment.Content = form.Get("content")

	// TODO:评论楼层怎么处理,避免冲突?最后的楼层信息保存在内存中?

	// 暂时只是从数据库中取出最后的评论楼层
	stringBuilder := util.NewBuffer()
	stringBuilder.Append("objid=").AppendInt(objid).Append(" AND objtype=").AppendInt(objtype)
	tmpCmt, err := model.NewComment().Where(stringBuilder.String()).Order("ctime DESC").Find()
	if err != nil {
		logger.Errorln("post comment service error:", err)
		return nil, err
	} else {
		comment.Floor = tmpCmt.Floor + 1
	}
	// 入评论库
	cid, err := comment.Insert()
	if err != nil {
		logger.Errorln("post comment service error:", err)
		return nil, err
	}
	comment.Cid = cid
	comment.Ctime = util.TimeNow()
	decodeCmtContent(comment)

	// 回调,不关心处理结果(有些对象可能不需要回调)
	if commenter, ok := commenters[objtype]; ok {
		logger.Debugf("评论[objid:%d] [objtype:%d] [uid:%d] 成功,通知被评论者更新", objid, objtype, uid)
		go commenter.UpdateComment(cid, objid, uid, time.Now().Format("2006-01-02 15:04:05"))
	}

	// 发评论,活跃度+5
	go IncUserWeight("uid="+strconv.Itoa(uid), 5)

	// 给被评论对象所有者发系统消息
	ext := map[string]interface{}{
		"objid":   objid,
		"objtype": objtype,
		"cid":     cid,
		"uid":     uid,
	}
	go SendSystemMsgTo(0, objtype, ext)

	// @某人 发系统消息
	go SendSysMsgAtUids(form.Get("uid"), ext)
	go SendSysMsgAtUsernames(form.Get("usernames"), ext)

	return comment, nil
}
Пример #10
0
func initMaxOnlineNum() {
	maxRwMu.Lock()
	defer maxRwMu.Unlock()
	if maxOnlineNum == 0 {
		data, err := ioutil.ReadFile(getDataFile())
		if err != nil {
			logger.Errorln("read data file error:", err)
			return
		}
		maxOnlineNum = util.MustInt(strings.TrimSpace(string(data)))
	}
}
Пример #11
0
// 喜欢(或取消喜欢)
// uri: /like/{objid:[0-9]+}.json
func LikeHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	user, _ := filter.CurrentUser(req)

	if !util.CheckInt(req.PostForm, "objtype") || !util.CheckInt(req.PostForm, "flag") {
		fmt.Fprint(rw, `{"ok": 0, "error":"参数错误"}`)
		return
	}

	uid := user["uid"].(int)
	objid := util.MustInt(vars["objid"])
	objtype := util.MustInt(req.PostFormValue("objtype"))
	likeFlag := util.MustInt(req.PostFormValue("flag"))

	err := service.LikeObject(uid, objid, objtype, likeFlag)
	if err != nil {
		fmt.Fprint(rw, `{"ok": 0, "error":"服务器内部错误"}`)
		return
	}

	fmt.Fprint(rw, `{"ok": 1, "msg":"success", "data":""}`)
}
Пример #12
0
// 某节点下的帖子列表
// uri: /topics/node{nid:[0-9]+}
func NodesHandler(rw http.ResponseWriter, req *http.Request) {
	page, _ := strconv.Atoi(req.FormValue("p"))
	if page == 0 {
		page = 1
	}
	vars := mux.Vars(req)
	topics, total := service.FindTopics(page, 0, "nid="+vars["nid"])
	pageHtml := service.GetPageHtml(page, total)
	// 当前节点信息
	node := model.GetNode(util.MustInt(vars["nid"]))
	req.Form.Set(filter.CONTENT_TPL_KEY, "/template/topics/node.html")
	// 设置模板数据
	filter.SetData(req, map[string]interface{}{"activeTopics": "active", "topics": topics, "page": template.HTML(pageHtml), "total": total, "node": node})
}
Пример #13
0
func doCrawl(wbconf map[string]string, isAll bool) {
	crawlUrl := wbconf["incr_url"]
	if isAll {
		crawlUrl = wbconf["all_url"]
	}

	listselector := wbconf["listselector"]
	resultselector := wbconf["resultselector"]
	pageField := wbconf["page_field"]

	maxPage := 1
	if isAll {
		maxPage = util.MustInt(wbconf["max_page"])
	}

	// 个人博客,一般通过 tag 方式获取,这种处理方式和搜索不一样
	if wbconf["keywords"] == "" {
		for p := maxPage; p >= 1; p-- {
			if pageField == "" {

				// 标题不包含 go 等关键词的,也入库
				if err := parseArticleList(crawlUrl+strconv.Itoa(p), listselector, resultselector, false); err != nil {
					break
				}
			}
		}

		return
	}

	keywords := strings.Split(wbconf["keywords"], ",")

	for _, keyword := range keywords {
		for p := 1; p <= maxPage; p++ {

			page := fmt.Sprintf("&%s=%d", pageField, p)
			if err := parseArticleList(crawlUrl+keyword+page, listselector, resultselector, true); err != nil {
				logger.Errorln("parse article url error:", err)
				break
			}
		}
	}
}
Пример #14
0
// 发短消息
// uri: /message/send{json:(|.json)}
func SendMessageHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	content := req.FormValue("content")
	// 请求新建帖子页面
	if content == "" || req.Method != "POST" || vars["json"] == "" {
		user := service.FindUserByUsername(req.FormValue("username"))
		filter.SetData(req, map[string]interface{}{"user": user})
		req.Form.Set(filter.CONTENT_TPL_KEY, "/template/messages/send.html")
		return
	}

	user, _ := filter.CurrentUser(req)
	to := util.MustInt(req.FormValue("to"))
	success := service.SendMessageTo(user["uid"].(int), to, content)
	if !success {
		fmt.Fprint(rw, `{"errno": 1, "error":"对不起,发送失败,请稍候再试!"}`)
		return
	}
	fmt.Fprint(rw, `{"errno": 0, "error":""}`)
}
Пример #15
0
// 新建帖子
// uri: /topics/new{json:(|.json)}
func NewTopicHandler(rw http.ResponseWriter, req *http.Request) {
	nodes := genNodes()
	vars := mux.Vars(req)
	content := req.FormValue("content")
	// 请求新建帖子页面
	if content == "" || req.Method != "POST" || vars["json"] == "" {
		req.Form.Set(filter.CONTENT_TPL_KEY, "/template/topics/new.html")
		filter.SetData(req, map[string]interface{}{"nodes": nodes})
		return
	}

	// 入库
	topic := model.NewTopic()
	logger.Traceln("anonymous")
	logger.Traceln(req.FormValue("anonymous"))
	if req.FormValue("anonymous") == "1" {
		topic.Uid, _ = strconv.Atoi(Config["auid"])
	} else {
		user, _ := filter.CurrentUser(req)
		if user != nil {
			topic.Uid = user["uid"].(int)
		} else {
			topic.Uid, _ = strconv.Atoi(Config["auid"])
		}
	}

	logger.Traceln(topic)
	topic.Nid = util.MustInt(req.FormValue("nid"))
	topic.Title = req.FormValue("title")
	topic.Content = req.FormValue("content")
	logger.Traceln(topic)
	errMsg, err := service.PublishTopic(topic)
	logger.Traceln("PublishTopic end")
	logger.Traceln(errMsg)
	if err != nil {
		fmt.Fprint(rw, `{"errno": 1, "error":"`, errMsg, `"}`)
		return
	}
	fmt.Fprint(rw, `{"errno": 0, "error":""}`)
}
Пример #16
0
// 获取当前(id)博文以及前后博文
func FindArticlesById(idstr string) (curArticle *model.Article, prevNext []*model.Article, err error) {

	id := util.MustInt(idstr)
	cond := "id BETWEEN ? AND ? AND status!=2"

	articles, err := model.NewArticle().Where(cond, id-5, id+5).FindAll()
	if err != nil {
		logger.Errorln("article service FindArticlesById Error:", err)
		return
	}

	if len(articles) == 0 {
		return
	}

	prevNext = make([]*model.Article, 2)
	prevId, nextId := articles[0].Id, articles[len(articles)-1].Id
	for _, article := range articles {
		if article.Id < id && article.Id > prevId {
			prevId = article.Id
			prevNext[0] = article
		} else if article.Id > id && article.Id < nextId {
			nextId = article.Id
			prevNext[1] = article
		} else if article.Id == id {
			curArticle = article
		}
	}

	if prevId == id {
		prevNext[0] = nil
	}

	if nextId == id {
		prevNext[1] = nil
	}

	return
}
Пример #17
0
// 某个资源详细页
// uri: /resources/{id:[0-9]+}
func ResourceDetailHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	resource, comments := service.FindResource(vars["id"])

	if len(resource) == 0 {
		util.Redirect(rw, req, "/resources")
		return
	}

	likeFlag := 0
	hadCollect := 0
	user, ok := filter.CurrentUser(req)
	if ok {
		uid := user["uid"].(int)
		id := resource["id"].(int)
		likeFlag = service.HadLike(uid, id, model.TYPE_RESOURCE)
		hadCollect = service.HadFavorite(uid, id, model.TYPE_RESOURCE)
	}

	service.Views.Incr(req, model.TYPE_RESOURCE, util.MustInt(vars["id"]))

	req.Form.Set(filter.CONTENT_TPL_KEY, "/template/resources/detail.html,/template/common/comment.html")
	filter.SetData(req, map[string]interface{}{"activeResources": "active", "resource": resource, "comments": comments, "likeflag": likeFlag, "hadcollect": hadCollect})
}
Пример #18
0
// 获得某人的系统消息
// 系统消息类型不同,在ext中存放的字段也不一样,如下:
//   model.MsgtypeTopicReply/MsgtypeResourceComment/MsgtypeWikiComment存放都为:
//		{"uid":xxx,"objid":xxx}
//   model.MsgtypeAtMe为:{"uid":xxx,"cid":xxx,"objid":xxx,"objtype":xxx}
func FindSysMsgsByUid(uid string) []map[string]interface{} {
	messages, err := model.NewSystemMessage().Where("to=" + uid).Order("ctime DESC").FindAll()
	if err != nil {
		logger.Errorln("message service FindSysMsgsByUid Error:", err)
		return nil
	}
	uids := make(map[int]int)
	tids := make(map[int]int)
	resIds := make(map[int]int)
	wikiIds := make(map[int]int)
	// 评论ID
	cids := make(map[int]int)

	ids := make([]int, 0, len(messages))
	for _, message := range messages {
		ext := message.Ext()
		if val, ok := ext["uid"]; ok {
			uid := int(val.(float64))
			uids[uid] = uid
		}
		var objid int
		if val, ok := ext["objid"]; ok {
			objid = int(val.(float64))
		}
		switch message.Msgtype {
		case model.MsgtypeTopicReply:
			tids[objid] = objid
		case model.MsgtypeWikiComment:
			wikiIds[objid] = objid
		case model.MsgtypeAtMe:
			objTypeFloat := ext["objtype"].(float64)
			switch int(objTypeFloat) {
			case model.TYPE_TOPIC:
				tids[objid] = objid
			case model.TYPE_BLOG:
				//tids[objid] = objid
			case model.TYPE_RESOURCE:
				resIds[objid] = objid
			case model.TYPE_WIKI:
				wikiIds[objid] = objid
			}
		}
		if val, ok := ext["cid"]; ok {
			cid := int(val.(float64))
			cids[cid] = cid
		}
		if message.Hasread == "未读" {
			ids = append(ids, message.Id)
		}
	}
	// 标记已读
	go MarkHasRead(ids, true, util.MustInt(uid))

	userMap := getUserInfos(uids)
	commentMap := getComments(cids)
	topicMap := getTopics(tids)

	result := make([]map[string]interface{}, len(messages))
	for i, message := range messages {
		tmpMap := make(map[string]interface{})
		// 某条信息的提示(标题)
		title := ""
		ext := message.Ext()
		if val, ok := ext["objid"]; ok {
			objTitle := ""
			objUrl := ""
			objid := int(val.(float64))
			switch message.Msgtype {
			case model.MsgtypeTopicReply:
				objTitle = topicMap[objid].Title
				objUrl = "/topics/" + strconv.Itoa(topicMap[objid].Tid)
				title = "回复了你的主题:"
			case model.MsgtypeAtMe:
				title = "评论时提到了你,在"
				switch int(ext["objtype"].(float64)) {
				case model.TYPE_TOPIC:
					objTitle = topicMap[objid].Title
					objUrl = "/topics/" + strconv.Itoa(topicMap[objid].Tid)
					title += "主题:"
				}
			}
			tmpMap["objtitle"] = objTitle
			tmpMap["objurl"] = objUrl
		}
		tmpMap["ctime"] = message.Ctime
		tmpMap["id"] = message.Id
		tmpMap["hasread"] = message.Hasread
		if val, ok := ext["uid"]; ok {
			tmpMap["user"] = userMap[int(val.(float64))]
		}
		// content 和 cid不会同时存在
		if val, ok := ext["content"]; ok {
			tmpMap["content"] = val.(string)
		} else if val, ok := ext["cid"]; ok {
			tmpMap["content"] = decodeCmtContent(commentMap[int(val.(float64))])
		}
		tmpMap["title"] = title
		result[i] = tmpMap
	}
	return result
}
Пример #19
0
// 某个分类的资源列表
// uri: /resources/cat/{catid:[0-9]+}
func CatResourcesHandler(rw http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	catid := vars["catid"]

	page, _ := strconv.Atoi(req.FormValue("p"))
	if page == 0 {
		page = 1
	}

	resources, total := service.FindResourcesByCatid(catid, page)
	pageHtml := service.GetPageHtml(page, total, req.URL.Path)

	req.Form.Set(filter.CONTENT_TPL_KEY, "/template/resources/index.html")
	filter.SetData(req, map[string]interface{}{"activeResources": "active", "resources": resources, "categories": service.AllCategory, "page": template.HTML(pageHtml), "curCatid": util.MustInt(catid)})
}