273 lines
9.0 KiB
Go
273 lines
9.0 KiB
Go
|
package data
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"crypto/md5"
|
||
|
"encoding/hex"
|
||
|
"sort"
|
||
|
"strconv"
|
||
|
"time"
|
||
|
|
||
|
"go-common/app/interface/main/creative/model/data"
|
||
|
"go-common/library/ecode"
|
||
|
"go-common/library/log"
|
||
|
|
||
|
"github.com/tsuna/gohbase/hrpc"
|
||
|
|
||
|
"golang.org/x/net/context"
|
||
|
)
|
||
|
|
||
|
func hbaseMd5Key(aid int64) string {
|
||
|
hasher := md5.New()
|
||
|
hasher.Write([]byte(strconv.Itoa(int(aid))))
|
||
|
return hex.EncodeToString(hasher.Sum(nil))
|
||
|
}
|
||
|
|
||
|
// VideoQuitPoints get video quit points.
|
||
|
func (d *Dao) VideoQuitPoints(c context.Context, cid int64) (res []int64, err error) {
|
||
|
var (
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
|
||
|
tableName = HBaseVideoTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
backupTableName = HBaseVideoTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
key = hbaseMd5Key(cid)
|
||
|
)
|
||
|
defer cancel()
|
||
|
result, err := d.hbase.GetStr(ctx, tableName, key)
|
||
|
if err != nil {
|
||
|
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
|
||
|
log.Error("VideoQuitPoints d.hbase.GetStr backupTableName(%s)|cid(%d)|key(%v)|error(%v)", backupTableName, cid, key, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if result == nil {
|
||
|
return
|
||
|
}
|
||
|
// get parts and max part for fill res
|
||
|
partMap := make(map[int]int64)
|
||
|
maxPart := 0
|
||
|
for _, c := range result.Cells {
|
||
|
if c != nil {
|
||
|
part, _ := strconv.Atoi(string(c.Qualifier[:]))
|
||
|
per, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
|
||
|
partMap[part] = per
|
||
|
if part > maxPart {
|
||
|
maxPart = part
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
var restPercent int64 = 10000 // start from 100%
|
||
|
for i := 1; i <= maxPart; i++ {
|
||
|
if _, ok := partMap[i]; ok {
|
||
|
restPercent = restPercent - partMap[i]
|
||
|
}
|
||
|
res = append(res, restPercent)
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ArchiveStat get the stat of archive.
|
||
|
func (d *Dao) ArchiveStat(c context.Context, aid int64) (stat *data.ArchiveData, err error) {
|
||
|
var (
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
|
||
|
tableName = HBaseArchiveTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
backupTableName = HBaseArchiveTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
key = hbaseMd5Key(aid)
|
||
|
)
|
||
|
defer cancel()
|
||
|
result, err := d.hbase.GetStr(ctx, tableName, key)
|
||
|
if err != nil {
|
||
|
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
|
||
|
log.Error("ArchiveStat d.hbase.GetStr backupTableName(%s)|aid(%d)|key(%v)|error(%v)", backupTableName, aid, key, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if result == nil {
|
||
|
return
|
||
|
}
|
||
|
stat = &data.ArchiveData{}
|
||
|
stat.ArchiveSource = &data.ArchiveSource{}
|
||
|
stat.ArchiveGroup = &data.ArchiveGroup{}
|
||
|
stat.ArchiveStat = &data.ArchiveStat{}
|
||
|
for _, c := range result.Cells {
|
||
|
if c == nil {
|
||
|
continue
|
||
|
}
|
||
|
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
|
||
|
if !bytes.Equal(c.Family, HBaseFamilyPlat) {
|
||
|
continue
|
||
|
}
|
||
|
switch {
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnWebPC):
|
||
|
stat.ArchiveSource.WebPC = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnWebH5):
|
||
|
stat.ArchiveSource.WebH5 = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnOutsite):
|
||
|
stat.ArchiveSource.Outsite = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnIOS):
|
||
|
stat.ArchiveSource.IOS = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnAndroid):
|
||
|
stat.ArchiveSource.Android = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnElse):
|
||
|
stat.ArchiveSource.Others = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnFans):
|
||
|
stat.ArchiveGroup.Fans = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnGuest):
|
||
|
stat.ArchiveGroup.Guest = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnAll):
|
||
|
stat.ArchiveStat.Play = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnCoin):
|
||
|
stat.ArchiveStat.Coin = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnElec):
|
||
|
stat.ArchiveStat.Elec = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnFav):
|
||
|
stat.ArchiveStat.Fav = v
|
||
|
case bytes.Equal(c.Qualifier, HBaseColumnShare):
|
||
|
stat.ArchiveStat.Share = v
|
||
|
//【稿件分析】增加:播放、弹幕、评论、点赞 v:play v:danmu v:reply v:likes
|
||
|
case bytes.Equal(c.Qualifier, []byte("play")):
|
||
|
stat.ArchiveStat.Play = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("danmu")):
|
||
|
stat.ArchiveStat.Dm = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("reply")):
|
||
|
stat.ArchiveStat.Reply = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("likes")):
|
||
|
stat.ArchiveStat.Like = v
|
||
|
}
|
||
|
}
|
||
|
stat.ArchiveSource.Mainsite = stat.ArchiveSource.WebPC + stat.ArchiveSource.WebH5
|
||
|
stat.ArchiveSource.Mobile = stat.ArchiveSource.Android + stat.ArchiveSource.IOS
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ArchiveArea get the count of area.
|
||
|
func (d *Dao) ArchiveArea(c context.Context, aid int64) (res []*data.ArchiveArea, err error) {
|
||
|
var (
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
|
||
|
tableName = HBaseAreaTablePrefix + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
backupTableName = HBaseAreaTablePrefix + time.Now().AddDate(0, 0, -2).Add(-12*time.Hour).Format("20060102") // change table at 12:00am
|
||
|
key = hbaseMd5Key(aid)
|
||
|
)
|
||
|
defer cancel()
|
||
|
result, err := d.hbase.GetStr(ctx, tableName, key)
|
||
|
if err != nil {
|
||
|
if result, err = d.hbase.GetStr(ctx, backupTableName, key); err != nil {
|
||
|
log.Error("ArchiveArea d.hbase.GetStr backupTableName(%s)|aid(%d)|key(%v)|error(%v)", backupTableName, aid, key, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
if result == nil {
|
||
|
return
|
||
|
}
|
||
|
var countArr []int
|
||
|
countMap := make(map[int64][]*data.ArchiveArea)
|
||
|
countSet := make(map[int]struct{}) // empty struct{} for saving memory
|
||
|
for _, c := range result.Cells {
|
||
|
if c != nil {
|
||
|
area := &data.ArchiveArea{}
|
||
|
area.Location = string(c.Qualifier[:])
|
||
|
area.Count, _ = strconv.ParseInt(string(c.Value[:]), 10, 64)
|
||
|
countMap[area.Count] = append(countMap[area.Count], area)
|
||
|
countSet[int(area.Count)] = struct{}{}
|
||
|
}
|
||
|
}
|
||
|
for key := range countSet {
|
||
|
countArr = append(countArr, key)
|
||
|
}
|
||
|
sort.Sort(sort.Reverse(sort.IntSlice(countArr)))
|
||
|
for _, c := range countArr {
|
||
|
if _, ok := countMap[int64(c)]; ok {
|
||
|
res = append(res, countMap[int64(c)]...)
|
||
|
}
|
||
|
if len(res) >= 10 {
|
||
|
res = res[:10] // exact 10 item
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// BaseUpStat get base up stat.
|
||
|
func (d *Dao) BaseUpStat(c context.Context, mid int64, date string) (stat *data.UpBaseStat, err error) {
|
||
|
var (
|
||
|
result *hrpc.Result
|
||
|
ctx, cancel = context.WithTimeout(c, d.hbaseTimeOut)
|
||
|
tableName = HBaseUpStatTablePrefix + date // change table at 12:00am
|
||
|
key = hbaseMd5Key(mid)
|
||
|
)
|
||
|
defer cancel()
|
||
|
if result, err = d.hbase.GetStr(ctx, tableName, key); err != nil {
|
||
|
log.Error("BaseUpStat d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|error(%v)", tableName, mid, key, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
if result == nil {
|
||
|
return
|
||
|
}
|
||
|
stat = &data.UpBaseStat{}
|
||
|
for _, c := range result.Cells {
|
||
|
if c == nil {
|
||
|
continue
|
||
|
}
|
||
|
v, _ := strconv.ParseInt(string(c.Value[:]), 10, 64)
|
||
|
if !bytes.Equal(c.Family, []byte("u")) {
|
||
|
continue
|
||
|
}
|
||
|
switch {
|
||
|
case bytes.Equal(c.Qualifier, []byte("play")):
|
||
|
stat.View = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("dm")):
|
||
|
stat.Dm = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("reply")):
|
||
|
stat.Reply = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("fans")):
|
||
|
stat.Fans = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("fav")):
|
||
|
stat.Fav = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("like")):
|
||
|
stat.Like = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("sh")):
|
||
|
stat.Share = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("elec")): //【视频数据总览】增加:硬币、充电
|
||
|
stat.Elec = v
|
||
|
case bytes.Equal(c.Qualifier, []byte("coin")):
|
||
|
stat.Coin = v
|
||
|
}
|
||
|
}
|
||
|
log.Info("BaseUpStat d.hbase.GetStr tableName(%s)|mid(%d)|key(%v)|stat(%+v)", tableName, mid, key, stat)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// UpArchiveStatQuery 获取最高播放/评论/弹幕/...数
|
||
|
func (d *Dao) UpArchiveStatQuery(c context.Context, mid int64, date string) (res *data.ArchiveMaxStat, err error) {
|
||
|
var (
|
||
|
result *hrpc.Result
|
||
|
ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
|
||
|
tableName = HBaseupArchiveStatQuery + date // change table at 12:00am
|
||
|
rowkey = hbaseMd5Key(mid)
|
||
|
)
|
||
|
defer cancel()
|
||
|
log.Info("UpArchiveStatQuery aid(%d)|rowkey(%s)", mid, rowkey)
|
||
|
if result, err = d.hbase.GetStr(ctx, tableName, rowkey); err != nil {
|
||
|
log.Error("UpArchiveStatQuery d.hbase.GetStr tableName(%s)|mid(%d)|rowkey(%+v)|error(%v)", tableName, mid, rowkey, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
if result == nil || len(result.Cells) == 0 {
|
||
|
log.Warn("UpArchiveStatQuery no data tableName(%s)|mid(%d)|rowkey(%+v)", tableName, mid, rowkey)
|
||
|
return
|
||
|
}
|
||
|
var cells data.ArchiveMaxStat
|
||
|
err = parser.Parse(result.Cells, &cells)
|
||
|
if err != nil {
|
||
|
log.Error("UpArchiveStatQuery parser.Parse tableName(%s)|mid(%d)|rowkey(%+v)|error(%v)", tableName, mid, rowkey, err)
|
||
|
err = ecode.CreativeDataErr
|
||
|
return
|
||
|
}
|
||
|
res = &cells
|
||
|
log.Info("UpArchiveStatQuery mid(%d)|rowkey(%s)|res(%+v)", mid, rowkey, *res)
|
||
|
return
|
||
|
}
|