Example #1
0
func recvHeartHandler(r *http.Request, w http.ResponseWriter,
	redis *models.RedisLogger, user *models.Account, p Parameter) {

	form := p.(recvHeartForm)

	// ws push
	event := &models.Event{
		Type: models.EventSystem,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Type: models.EventRecvHeart,
			Id:   user.Id,
			From: user.Id,
			To:   form.Sender,
			Body: []models.MsgBody{
				{Type: "userid", Content: user.Id},
			},
		},
	}

	awards := Awards{}
	if form.Accept {
		redis.SetRelationship(user.Id, []string{form.Sender}, models.RelFriend, true)
		event.Save()
		redis.PubMsg(models.EventSystem, form.Sender, event.Bytes())
		awards.Wealth = 1 * models.Satoshi
		GiveAwards(user, awards, redis)
	}
	redis.SetHeartRecv(user.Id, false)
	writeResponse(r.RequestURI, w, map[string]interface{}{"ExpEffect": awards}, nil)
}
Example #2
0
func followHandler(request *http.Request, resp http.ResponseWriter,
	client *ApnClient, redis *models.RedisLogger, user *models.Account, p Parameter) {

	form := p.(relationshipForm)

	for _, peer := range form.Userids {
		if redis.Relationship(peer, user.Id) == models.RelBlacklist {
			writeResponse(request.RequestURI, resp, nil, errors.NewError(errors.DbError, "对方已屏蔽了你!"))
			return
		}
	}

	redis.SetRelationship(user.Id, form.Userids, models.RelFollowing, form.Follow)
	writeResponse(request.RequestURI, resp, map[string]interface{}{"ExpEffect": Awards{}}, nil)

	for _, userid := range form.Userids {
		u := &models.Account{}
		u.FindByUserid(userid)

		event := &models.Event{
			Type: models.EventMsg,
			Time: time.Now().Unix(),
			Data: models.EventData{
				Type: models.EventSub,
				Id:   user.Id + "-" + u.Id,
				From: user.Id,
				To:   u.Id,
				Body: []models.MsgBody{
					{Type: "nikename", Content: user.Nickname},
					{Type: "image", Content: user.Profile},
				},
			},
		}

		if form.Follow {
			/*
				if err := event.Save(); err == nil {
					redis.IncrEventCount(u.Id, event.Data.Type, 1)
				}
			*/
			event.Upsert()

			event.Data.Body = append(event.Data.Body,
				models.MsgBody{Type: "new_count", Content: "1"})
			redis.PubMsg(models.EventMsg, u.Id, event.Bytes())

			// apple push
			if u.Push {
				go sendApn(client, user.Nickname+"关注了你!", u.EventCount("", ""), u.Devs...)
			}
		} else {
			//count := u.DelEvent(models.EventSub, user.Id, user.Id, u.Id)
			//redis.IncrEventCount(u.Id, models.EventSub, -count)
			event.Delete()
		}
	}
}
Example #3
0
func sendHeartHandler(r *http.Request, w http.ResponseWriter,
	redis *models.RedisLogger, user *models.Account, p Parameter) {

	form := p.(sendHeartForm)

	receivers := redis.HeartReceivers(user.Id)

	if len(receivers) == 0 {
		writeResponse(r.RequestURI, w, nil, nil)
	}

	var target string
	for _, recv := range receivers {
		if recv != user.Id {
			target = recv
			break
		}
	}
	// ws push
	event := &models.Event{
		Type: models.EventSystem,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Type: models.EventSendHeart,
			Id:   user.Id,
			From: user.Id,
			To:   target,
			Body: []models.MsgBody{
				{Type: "record_id", Content: form.Record},
				{Type: "userid", Content: user.Id},
			},
		},
	}
	if len(target) > 0 {
		event.Save()
		redis.PubMsg(models.EventSystem, target, event.Bytes())
		redis.LogHeartSend(user.Id)
		redis.SetHeartRecv(target, true)
	}

	writeResponse(r.RequestURI, w, nil, nil)
}
Example #4
0
func joinGroupHandler(request *http.Request, resp http.ResponseWriter,
	redis *models.RedisLogger, user *models.Account, p Parameter) {

	form := p.(joinGroupForm)

	redis.JoinGroup(user.Id, form.Gid, !form.Leave)
	writeResponse(request.RequestURI, resp, nil, nil)

	event := &models.Event{
		Type: "message",
		Data: models.EventData{
			From: user.Id,
			To:   form.Gid,
		},
	}
	if !form.Leave {
		event.Data.Type = "subscribe"
	} else {
		event.Data.Type = "unsubscribe"
	}

	redis.PubMsg(event.Data.Type, user.Id, event.Bytes())
}
Example #5
0
func GiveAwards(user *models.Account, awards Awards, redis *models.RedisLogger) error {
	if awards.Level < 0 || awards.Score < 0 {
		panic("invalid level or score")
	}
	if _, err := sendCoin(user.Wallet.Addr, awards.Wealth); err != nil {
		return err
	}
	redis.SendCoins(user.Id, awards.Wealth)

	err := user.UpdateProps(models.Props{
		Physical: awards.Physical,
		Literal:  awards.Literal,
		Mental:   awards.Mental,
		//Wealth:   awards.Wealth,
		Score: awards.Score,
		//Level: awards.Level,
	})
	if err != nil {
		return err
	}

	if lvl := models.Score2Level(user.Props.Score + awards.Score); lvl > user.Level() {
		// ws push
		event := &models.Event{
			Type: models.EventNotice,
			Time: time.Now().Unix(),
			Data: models.EventData{
				Type: models.EventLevelUP,
				To:   user.Id,
			},
		}
		event.Save()
		redis.PubMsg(event.Type, event.Data.To, event.Bytes())
	}

	return nil
}
Example #6
0
func taskSharedHandler(r *http.Request, w http.ResponseWriter,
	redis *models.RedisLogger, user *models.Account, p Parameter) {
	form := p.(taskSharedForm)

	u := &models.Account{}
	u.FindByUserid(form.Sender)

	// ws push
	event := &models.Event{
		Type: models.EventSystem,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Id:   user.Id,
			From: user.Id,
			To:   form.Sender,
		},
	}

	var article *models.Article

	switch form.Type {
	case models.TaskRunning:
		event.Data.Type = models.EventRunShared
		article = &models.Article{
			Author:  user.Id,
			PubTime: time.Now(),
			Contents: []models.Segment{
				{ContentType: "TEXT", ContentText: "我和" + u.Nickname + "约好一起跑步,有想一起参加的吗?" +
					"\n跑步地点: " + form.Addr +
					"\n跑步时间: " + time.Unix(form.Time, 0).Format("2006-01-02 3:04 PM")},
				{ContentType: "IMAGE", ContentText: form.Image},
			},
		}
	case models.TaskPost:
		article := &models.Article{}
		if find, _ := article.FindById(form.ArticleId); find {
			article.SetThumb(user.Id, true)
		}
		event.Data.Type = models.EventPostShared
	case models.TaskGame:
		event.Data.Type = models.EventPKShared
		result := u.Nickname + " 主动PK " + user.Nickname + "大获全胜。"
		if u.Props.Score < user.Props.Score {
			result = u.Nickname + " 主动PK " + user.Nickname + "大败亏输。"
		}
		article = &models.Article{
			Author:  user.Id,
			Type:    "pk",
			PubTime: time.Now(),
			Contents: []models.Segment{
				{ContentType: "TEXT", ContentText: result},
				{ContentType: "IMAGE", ContentText: form.Image},
			},
		}
	default:
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.AccessError))
		return
	}

	awards := Awards{}
	if form.Accept {
		redis.SetRelationship(user.Id, []string{form.Sender}, models.RelFriend, true)
		event.Save()
		redis.PubMsg(models.EventSystem, form.Sender, event.Bytes())
		user.UpdateRatio(form.Type, true)
		if article != nil {
			article.Save()
		}
		awards.Wealth = 1 * models.Satoshi
		GiveAwards(user, awards, redis)
	}

	redis.SetTaskShare(user.Id, false)

	writeResponse(r.RequestURI, w, map[string]interface{}{"ExpEffect": awards}, nil)
}
Example #7
0
func taskShareHandler(r *http.Request, w http.ResponseWriter,
	redis *models.RedisLogger, user *models.Account, p Parameter) {
	form := p.(taskShareForm)

	if form.TaskId > len(models.NewTasks) {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.AccessError))
		return
	}

	//task := models.NewTasks[form.TaskId]
	// ws push
	event := &models.Event{
		Type: models.EventSystem,
		Time: time.Now().Unix(),
		Data: models.EventData{
			//Type: models.EventRunShare,
			Id:   user.Id,
			From: user.Id,
			To:   form.Userid,
		},
	}

	switch form.Type {
	case models.TaskRunning:
		record, _ := user.LastRecord("run")
		latlng := strconv.FormatFloat(form.Lat, 'f', 7, 64) + "," +
			strconv.FormatFloat(form.Lng, 'f', 7, 64)
		event.Data.Type = models.EventRunShare
		event.Data.Body = []models.MsgBody{
			{Type: "record_id", Content: record.Id.Hex()},
			{Type: "latlng", Content: latlng},
			{Type: "locaddr", Content: form.Addr},
			{Type: "time", Content: strconv.FormatInt(form.Time, 10)},
			{Type: "addr_image", Content: form.Image},
		}
	case models.TaskPost:
		event.Data.Type = models.EventPostShare
		article := user.LatestArticle()
		event.Data.Body = []models.MsgBody{
			{Type: "article_id", Content: article.Id.Hex()},
		}
	case models.TaskGame:
		record, _ := user.LastRecord("run")
		event.Data.Type = models.EventPKShare
		event.Data.Body = []models.MsgBody{
			{Type: "record_id", Content: record.Id.Hex()},
		}
	default:
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.AccessError))
		return
	}

	event.Save()
	redis.PubMsg(event.Type, event.Data.To, event.Bytes())

	u := &models.Account{Id: form.Userid}
	u.UpdateRatio(form.Type, false)
	redis.SetTaskShare(form.Userid, true)

	if _, err := consumeCoin(user.Wallet.Addr, form.Coin); err == nil {
		redis.ConsumeCoins(user.Id, form.Coin)
	}

	writeResponse(r.RequestURI, w, nil, nil)
}
Example #8
0
func articleThumbHandler(request *http.Request, resp http.ResponseWriter,
	client *ApnClient, redis *models.RedisLogger, user *models.Account, p Parameter) {

	form := p.(articleThumbForm)
	article := &models.Article{}
	if find, err := article.FindById(form.Id); !find {
		e := errors.NewError(errors.NotExistsError, "文章不存在!")
		if err != nil {
			e = errors.NewError(errors.DbError)
		}
		writeResponse(request.RequestURI, resp, nil, e)
		return
	}

	if redis.Relationship(article.Author, user.Id) == models.RelBlacklist {
		writeResponse(request.RequestURI, resp, nil,
			errors.NewError(errors.AccessError, "对方屏蔽了你!"))
		return
	}

	if err := article.SetThumb(user.Id, form.Status); err != nil {
		writeResponse(request.RequestURI, resp, nil, err)
		return
	}

	awards := Awards{}
	if form.Status {
		awards = Awards{Score: 1, Wealth: 1 * models.Satoshi}
		GiveAwards(user, awards, redis)
	}
	writeResponse(request.RequestURI, resp, map[string]interface{}{"ExpEffect": awards}, nil)

	author := &models.Account{Id: article.Author}

	// ws push
	event := &models.Event{
		Type: models.EventArticle,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Type: models.EventThumb,
			Id:   article.Id.Hex(),
			From: user.Id,
			To:   author.Id,
			Body: []models.MsgBody{
				{Type: "total_count", Content: strconv.Itoa(article.ThumbCount + 1)},
				{Type: "image", Content: article.Image},
			},
		},
	}

	if form.Status {
		author.FindByUserid(article.Author)
		/*
			if err := event.Save(); err == nil {
				redis.IncrEventCount(article.Author, event.Data.Type, 1)
			}
		*/
		event.Upsert()

		event.Data.Body = append(event.Data.Body,
			models.MsgBody{Type: "new_count",
				Content: strconv.Itoa(models.EventCount(event.Data.Type, event.Data.Id, event.Data.To))})
		redis.PubMsg(models.EventArticle, article.Author, event.Bytes())

		// apple push
		if author.Push {
			go sendApn(client, user.Nickname+"赞了你的主题!", author.EventCount("", ""), author.Devs...)
		}
	} else {
		//count := author.DelEvent(models.EventThumb, article.Id.Hex(), user.Id, author.Id)
		//redis.IncrEventCount(author.Id, models.EventThumb, -count)
		event.Delete()
	}
	//user.UpdateAction(ActThumb, nowDate())
}
Example #9
0
func newArticleHandler(request *http.Request, resp http.ResponseWriter,
	client *ApnClient, redis *models.RedisLogger, user *models.Account, p Parameter) {
	form := p.(newArticleForm)

	article := &models.Article{
		Author:   user.Id,
		Contents: form.Contents,
		PubTime:  time.Now(),
		Parent:   form.Parent,
		//Tags:     form.Tags,
		Loc:  form.Location,
		Type: form.Type,
	}
	article.Title, article.Images = articleCover(form.Contents)
	if len(article.Images) > 0 {
		article.Image = article.Images[0]
	}
	/*
		if len(article.Tags) == 0 {
			article.Tags = []string{"SPORT_LOG"}
		}
	*/

	awards := Awards{}
	parent := &models.Article{}
	if len(form.Parent) > 0 {
		if find, err := parent.FindById(form.Parent); !find {
			e := errors.NewError(errors.NotExistsError, "文章不存在!")
			if err != nil {
				e = errors.NewError(errors.DbError)
			}
			writeResponse(request.RequestURI, resp, nil, e)
			return
		}

		if redis.Relationship(parent.Author, user.Id) == models.RelBlacklist {
			writeResponse(request.RequestURI, resp, nil,
				errors.NewError(errors.AccessError, "对方屏蔽了你!"))
			return
		}

		awards = Awards{Literal: 1 + user.Level(), Score: 1 + user.Level()}
	} else {
		if user.Stat != nil && user.Stat.LastArticleTime < nowDate().Unix() {
			awards = Awards{Literal: 2 + user.Level(), Wealth: 2 * models.Satoshi, Score: 2 + user.Level()}
		}
		user.UpdateStat(models.StatLastArticleTime, time.Now().Unix())
	}

	if article.Type == models.ArticleRecord {
		article.Coaches = []string{user.Id}
	}

	if article.Type == models.ArticleCoach {
		if parent.Author != user.Id &&
			user.Actor != models.ActorCoach && user.Actor != models.ActorAdmin {
			writeResponse(request.RequestURI, resp, nil,
				errors.NewError(errors.AccessError))
			return
		}

		if err := article.Save(); err != nil {
			log.Println(err)
			writeResponse(request.RequestURI, resp, nil, err)
			return
		}

		// ws push
		event := &models.Event{
			Type: models.EventArticle,
			Time: time.Now().Unix(),
			Data: models.EventData{
				Type: models.EventCoach,
				Id:   parent.Id.Hex(),
				From: user.Id,
				//To:   parent.Author,
				Body: []models.MsgBody{
					{Type: "total_count", Content: strconv.Itoa(parent.CoachReviewCount + 1)},
					{Type: "image", Content: user.Profile},
				},
			},
		}

		for _, coach := range parent.Coaches {
			if coach == user.Id {
				continue
			}
			event.Data.To = coach
			event.Save()
			redis.PubMsg(models.EventArticle, coach, event.Bytes())
		}

		respData := map[string]interface{}{
			"ExpEffect": Awards{},
		}
		writeResponse(request.RequestURI, resp, respData, nil)
		return
	}

	if err := article.Save(); err != nil {
		log.Println(err)
		writeResponse(request.RequestURI, resp, nil, err)
		return
	}
	t := ""
	stat := models.StatArticles
	if len(form.Parent) > 0 {
		t = models.ArticleComment
		stat = models.StatComments
	}
	redis.AddPost(user.Id, t, 1)
	user.UpdateStat(stat, 1)

	if err := GiveAwards(user, awards, redis); err != nil {
		log.Println(err)
		writeResponse(request.RequestURI, resp, nil, errors.NewError(errors.DbError))
		return
	}

	// comment
	if len(form.Parent) > 0 && parent.Author != user.Id {
		//u := &models.User{Id: parent.Author}
		author := &models.Account{}
		author.FindByUserid(parent.Author)

		// ws push
		event := &models.Event{
			Type: models.EventArticle,
			Time: time.Now().Unix(),
			Data: models.EventData{
				Type: models.EventComment,
				Id:   parent.Id.Hex(),
				From: user.Id,
				To:   parent.Author,
				Body: []models.MsgBody{
					{Type: "total_count", Content: strconv.Itoa(parent.ReviewCount + 1)},
					{Type: "image", Content: parent.Image},
				},
			},
		}
		/*
			if err := event.Save(); err == nil {
				redis.IncrEventCount(parent.Author, event.Data.Type, 1)
			}
		*/
		event.Save()

		event.Data.Body = append(event.Data.Body,
			models.MsgBody{Type: "new_count",
				Content: strconv.Itoa(models.EventCount(event.Data.Type, event.Data.Id, event.Data.To))})
		redis.PubMsg(models.EventArticle, parent.Author, event.Bytes())
		// apple push
		if author.Push {
			go sendApn(client, user.Nickname+"评论了你的主题!", author.EventCount("", ""), author.Devs...)
		}
	}

	respData := map[string]interface{}{
		//"articles_without_content": convertArticle(article),
		"ExpEffect": awards,
	}
	writeResponse(request.RequestURI, resp, respData, nil)
}
Example #10
0
func txHandler(r *http.Request, w http.ResponseWriter,
	client *ApnClient, redis *models.RedisLogger, user *models.Account, p Parameter) {
	form := p.(txForm)

	if form.FromAddr == form.ToAddr {
		writeResponse(r.RequestURI, w, map[string]string{"txid": ""}, nil)
		return
	}

	if form.Value <= 0 {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.AccessError, "无效的金额"))
		return
	}

	receiver := &models.Account{}
	if find, err := receiver.FindByWalletAddr(form.ToAddr); !find {
		e := errors.NewError(errors.NotFoundError, "无效的收款地址")
		if err != nil {
			e = errors.NewError(errors.DbError, "无效的钱包地址")
		}
		writeResponse(r.RequestURI, w, nil, e)
		return
	}

	if redis.Relationship(receiver.Id, user.Id) == models.RelBlacklist {
		writeResponse(r.RequestURI, w, nil,
			errors.NewError(errors.AccessError, "对方屏蔽了你!"))
		return
	}

	wal, err := getWallet(user.Wallet.Id, user.Wallet.Key)
	if err != nil {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.DbError, "获取钱包失败"))
		return
	}

	outputs, amount, err := getUnspent(form.FromAddr, wal.Keys, form.Value)
	if err != nil {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.DbError, "获取账户信息失败"))
		return
	}
	//log.Println("amount:", amount, "value:", form.Value)

	if form.Value > amount {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.AccessError, "余额不足"))
		return
	}

	article := &models.Article{}
	if strings.ToLower(form.Type) == "reward" && len(form.Id) > 0 {
		if b, e := article.FindById(form.Id); !b {
			err := errors.NewError(errors.NotExistsError, "文章不存在!")
			if e != nil {
				err = errors.NewError(errors.DbError)
			}
			writeResponse(r.RequestURI, w, nil, err)
			return
		}
	}

	changeAddr := form.FromAddr
	if len(changeAddr) == 0 {
		changeAddr = wal.Keys[0].PubKey
	}
	rawtx, err := CreateRawTx2(outputs, amount, form.Value, form.ToAddr, changeAddr)
	if err != nil {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.DbError))
		return
	}

	txid, err := sendRawTx(rawtx)
	if err != nil {
		writeResponse(r.RequestURI, w, nil, errors.NewError(errors.DbError))
		return
	}

	redis.Transaction(user.Id, receiver.Id, form.Value)
	// ws push
	event := &models.Event{
		Type: models.EventWallet,
		Time: time.Now().Unix(),
	}

	//log.Println("tx type:", strings.ToLower(form.Type))

	switch strings.ToLower(form.Type) {
	case "reward":

		article.Reward(user.Id, form.Value)

		event.Data = models.EventData{
			Type: models.EventReward,
			Id:   article.Id.Hex(),
			From: user.Id,
			To:   receiver.Id,
			Body: []models.MsgBody{
				{Type: "nikename", Content: user.Nickname},
				{Type: "image", Content: article.Image},
				{Type: "total_count", Content: strconv.FormatInt(article.TotalReward, 10)},
				//{Type: "new_count", Content: strconv.Itoa(models.EventCount(models.EventReward, article.Id.Hex()) + 1)},
			},
		}

	default:
		event.Data = models.EventData{
			Type: models.EventTx,
			Id:   user.Id + "-" + receiver.Id,
			From: user.Id,
			To:   receiver.Id,
			Body: []models.MsgBody{
				{Type: "nikename", Content: user.Nickname},
				{Type: "image", Content: user.Profile},
				{Type: "total_count", Content: strconv.FormatInt(form.Value, 10)},
			},
		}
	}

	if user.Id != receiver.Id {
		/*
			if err := event.Save(); err == nil {
				redis.IncrEventCount(receiver.Id, event.Data.Type, 1)
			}
		*/
		event.Save()
		event.Data.Body = append(event.Data.Body,
			models.MsgBody{Type: "new_count",
				Content: strconv.Itoa(models.EventCount(event.Data.Type, event.Data.Id, event.Data.To))})
		redis.PubMsg("wallet", receiver.Id, event.Bytes())
	}

	if receiver.Push {
		msg := user.Nickname + "通过转帐发送给你" +
			strconv.FormatFloat(float64(form.Value)/float64(models.Satoshi), 'f', 8, 64) + "个贝币"
		if event.Data.Type == models.EventReward {
			msg = user.Nickname + "给你的文章打赏了" +
				strconv.FormatFloat(float64(form.Value)/float64(models.Satoshi), 'f', 8, 64) + "个贝币"
		}
		go sendApn(client, msg, receiver.EventCount("", ""), receiver.Devs...)
	}

	writeResponse(r.RequestURI, w, map[string]string{"txid": txid}, nil)
}
Example #11
0
func wsPushHandler(request *http.Request, resp http.ResponseWriter, redisLogger *models.RedisLogger) {
	conn, err := upgrader.Upgrade(resp, request, nil)
	if err != nil {
		conn.WriteJSON(errors.NewError(errors.HttpError, err.Error()))
		return
	}
	defer conn.Close()

	r := wsAuthResp{}
	var auth wsAuth
	conn.ReadJSON(&auth)

	//log.Println("check token:", auth.Token)
	if !checkTokenValid(auth.Token) {
		//log.Println("check token valid")
		redisLogger.DelOnlineUser(auth.Token)
		conn.WriteJSON(r)
		return
	}

	uid := redisLogger.OnlineUser(auth.Token)

	user := &models.Account{}
	if find, _ := user.FindByUserid(uid); !find || user.TimeLimit < 0 {
		r.TimeLimit = user.TimeLimit
		conn.WriteJSON(r)
		return
	}

	//redisLogger.LogLogin(user.Id)

	days := user.LoginDays
	loginCount := user.LoginCount + 1
	d := nowDate()
	if user.LastLogin.Unix() < d.Unix() { // check wether first time login of one day
		days++
		if user.LastLogin.Unix() < d.Unix()-24*3600 {
			days = 1
		}
		loginCount = 1
	}
	//fmt.Println(uid, "loginCount", loginCount)
	user.SetLastLogin(days, loginCount, time.Now())

	r.Userid = uid
	r.LastLog = user.LastLogin.Unix()
	r.LoginCount = loginCount

	if err := conn.WriteJSON(r); err != nil {
		return
	}

	if len(uid) == 0 {
		return
	}

	redisLogger.LogVisitor(user.Id)
	psc := redisLogger.PubSub(user.Id)

	go func(conn *websocket.Conn) {
		//wg.Add(1)
		//defer log.Println("ws thread closed")
		//defer wg.Done()
		redisLogger.SetOnline(user.Id, user.Actor, true, 0)
		start := time.Now()

		defer psc.Close()

		for {
			event := &models.Event{}
			err := conn.ReadJSON(event)
			if err != nil {
				//log.Println(err)

				dur := int64(time.Since(start) / time.Second)
				redisLogger.SetOnline(user.Id, user.Actor, false, dur)
				user.UpdateStat(models.StatOnlineTime, dur)
				return
			}
			//log.Println("recv msg:", event.Type)
			switch event.Type {
			case models.EventMsg:
				m := &models.Message{
					From: event.Data.From,
					To:   event.Data.To,
					Body: event.Data.Body,
					Time: time.Now(),
				}
				if event.Data.Type == models.EventChat || event.Data.Type == models.EventGChat {
					m.Type = event.Data.Type
					m.Save()
					event.Data.Id = m.Id.Hex()
					event.Time = m.Time.Unix()

					redisLogger.PubMsg(m.Type, m.To, event.Bytes())
				}
			case models.EventStatus:
				//fmt.Println(user.Id, event.Data.Body)
				switch event.Data.Type {
				case "loc":
					var lat, lng float64
					var locaddr string
					for _, body := range event.Data.Body {
						switch body.Type {
						case "latlng":
							//log.Println("latlng:", body.Content)
							loc := strings.Split(body.Content, ",")
							if len(loc) != 2 {
								break
							}
							lat, _ = strconv.ParseFloat(loc[0], 64)
							lng, _ = strconv.ParseFloat(loc[1], 64)
						case "locaddr":
							//log.Println("locaddr:", body.Content)
							locaddr = body.Content
						}
					}
					user.UpdateLocation(models.Location{Lat: lat, Lng: lng}, locaddr)
				case "device":
					for _, body := range event.Data.Body {
						switch body.Type {
						case "token":
							token := body.Content
							//log.Println("device token:", token)
							user.AddDevice(token)
						}
					}
				}

			default:
				log.Println("unhandled message type:", event.Type)
			}
		}
	}(conn)

	for {
		switch v := psc.Receive().(type) {
		case redis.Message:
			//log.Printf("%s: message: %s\n", v.Channel, v.Data)
			event := &models.Event{}
			if err := json.Unmarshal(v.Data, event); err != nil {
				log.Println("parse push message error:", err)
				continue
			}

			// subscribe group
			if event.Data.Type == models.EventSub && event.Data.From == user.Id {
				if err := redisLogger.Subscribe(psc, event.Data.To); err != nil {
					log.Println(err)
				}
				continue
			}
			// unsubscribe group
			if event.Data.Type == models.EventUnsub && event.Data.From == user.Id {
				if err := redisLogger.Unsubscribe(psc, event.Data.To); err != nil {
					log.Println(err)
				}
				continue
			}

			if err := conn.WriteMessage(websocket.TextMessage, v.Data); err != nil {
				log.Println(err)
				return
			}
		case redis.Subscription:
			//log.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
		case error:
			//log.Println(v)
			return
		}
	}
}
Example #12
0
func taskAuthFunc(userid string, auth *taskAuth, redis *models.RedisLogger) error {
	user := &models.Account{}
	user.FindByUserid(auth.Userid)

	record := &models.Record{Uid: user.Id, Task: auth.Id}
	record.FindByTask(auth.Id)
	awards := controllers.Awards{}

	parent := &models.Article{}
	parent.FindByRecord(record.Id.Hex())
	if len(parent.Id) > 0 && len(auth.Reason) > 0 {
		review := &models.Article{
			Parent:   parent.Id.Hex(),
			Author:   userid,
			Title:    auth.Reason,
			Type:     models.ArticleCoach,
			Contents: []models.Segment{{ContentType: "TEXT", ContentText: auth.Reason}},
			PubTime:  time.Now(),
		}
		review.Save()
	}

	if auth.Pass {
		level := user.Level()
		awards = controllers.Awards{
			Physical: 3 + level,
			Wealth:   3 * models.Satoshi,
			Score:    3 + level,
		}
		awards.Level = models.Score2Level(user.Props.Score+awards.Score) - level

		controllers.GiveAwards(user, awards, redis)

		if record.Sport != nil {
			redis.UpdateRecLB(user.Id, record.Sport.Distance, int(record.Sport.Duration))
		}

		record.SetStatus(models.StatusFinish, auth.Reason, awards.Wealth)
		if auth.Id < 1000 {
			user.UpdateTask(int(auth.Id), models.StatusFinish)
		}
	} else {
		record.SetStatus(models.StatusUnFinish, auth.Reason, 0)
		if auth.Id < 1000 {
			user.UpdateTask(int(auth.Id), models.StatusUnFinish)
		}
		parent.SetPrivilege(models.PrivPrivate)
	}

	// ws push
	event := &models.Event{
		Type: models.EventNotice,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Type: models.EventTaskDone,
			To:   user.Id,
			Body: []models.MsgBody{
				{Type: "physique_value", Content: strconv.FormatInt(awards.Physical, 10)},
				{Type: "coin_value", Content: strconv.FormatInt(awards.Wealth, 10)},
			},
		},
	}
	if auth.Id < 1000 {
		event.Data.Body = append(event.Data.Body, models.MsgBody{Type: "task_id", Content: strconv.Itoa(int(auth.Id))})
	}

	if !auth.Pass {
		event.Data.Type = models.EventTaskFailure
	}
	redis.PubMsg(event.Type, event.Data.To, event.Bytes())
	event.Save()

	event = &models.Event{
		Type: models.EventArticle,
		Time: time.Now().Unix(),
		Data: models.EventData{
			Type: models.EventCoachPass,
			Id:   parent.Id.Hex(),
			From: userid,
			To:   parent.Author,
			Body: []models.MsgBody{
				{Type: "total_count", Content: strconv.Itoa(parent.CoachReviewCount + 1)},
				{Type: "image", Content: ""},
			},
		},
	}
	if !auth.Pass {
		event.Data.Type = models.EventCoachNPass
	}
	event.Save()
	redis.PubMsg(event.Type, event.Data.To, event.Bytes())

	return nil
}