archive_play.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. package data
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "strconv"
  6. "time"
  7. "go-common/app/admin/main/up/util/hbaseutil"
  8. "go-common/app/interface/main/creative/model/data"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. "github.com/tsuna/gohbase/hrpc"
  12. )
  13. var (
  14. //播放端占比
  15. playProportion = map[string]string{
  16. "pc": "pc", //pc端播放占比*10000
  17. "h5": "h5", //h5端播放占比*10000
  18. "out": "out", //站外播放占比*10000
  19. "adr": "android", //android端播放占比*10000
  20. "ios": "ios", //ios端播放占比*10000
  21. }
  22. //播放来源页面占比
  23. pageSource = map[string]string{
  24. "pv0": "other", //其他
  25. "pv1": "tenma", //天马推荐
  26. "pv2": "related_video", //相关视频
  27. "pv3": "search", //搜索
  28. "pv4": "h5", //H5页面
  29. "pv5": "space", //空间
  30. "pv6": "dynamic", //动态
  31. "pv7": "history", //播放历史
  32. "pv8": "tag", //标签
  33. "pv9": "cache", //离线缓存
  34. "pv10": "rank", //排行榜
  35. "pv11": "type", //分区
  36. }
  37. //粉丝来源页面占比
  38. fanSource = map[string]string{
  39. "pf0": "other", //其他
  40. "pf1": "space", //主站空间
  41. "pf2": "main", //主站播放页
  42. "pf3": "main_other", //主站其他
  43. "pf4": "live", //直播
  44. "pf5": "audio", // 音乐
  45. "pf6": "article", // 文章
  46. }
  47. parser = hbaseutil.Parser{}
  48. )
  49. func sourceOtherMerge(v string) bool { //合并这些页面来源为其他
  50. if v == "other" || v == "h5" || v == "history" || v == "cache" ||
  51. v == "rank" || v == "type" || v == "tag" {
  52. return true
  53. }
  54. return false
  55. }
  56. // reverse for string.
  57. func reverseString(s string) string {
  58. rs := []rune(s)
  59. l := len(rs)
  60. for f, t := 0, l-1; f < t; f, t = f+1, t-1 {
  61. rs[f], rs[t] = rs[t], rs[f]
  62. }
  63. ns := string(rs)
  64. if l < 10 {
  65. for i := 0; i < 10-l; i++ {
  66. ns = ns + "0"
  67. }
  68. }
  69. return ns
  70. }
  71. // 播放来源 - up_play_analysis
  72. // mid倒置补(10位)+ yyyyMMdd
  73. func playSourceKey(id int64) string {
  74. idStr := strconv.FormatInt(id, 10)
  75. s := reverseString(idStr)
  76. s = s + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102")
  77. return s
  78. }
  79. // 平均观看时长、播放用户数、留存率 - up_archive_play_analysis
  80. // avid倒置补(10位)+ yyyyMMdd
  81. func arcPlayKey(id int64) string {
  82. idStr := strconv.FormatInt(id, 10)
  83. s := reverseString(idStr)
  84. s = s + time.Now().AddDate(0, 0, -1).Add(-12*time.Hour).Format("20060102")
  85. return s
  86. }
  87. // 稿件索引表 - up_archive_query
  88. // [mid倒置补0(10位)] + [投稿年月(4位)] + [原创/转载(1位)]
  89. func arcQueryKey(id int64, dt string, cp int) string {
  90. idStr := strconv.FormatInt(id, 10)
  91. cpStr := strconv.Itoa(cp)
  92. s := reverseString(idStr)
  93. s = s + dt + cpStr
  94. return s
  95. }
  96. // UpPlaySourceAnalysis for play analysis.
  97. func (d *Dao) UpPlaySourceAnalysis(c context.Context, mid int64) (res *data.PlaySource, err error) {
  98. var (
  99. result *hrpc.Result
  100. ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
  101. tableName = HBaseUpPlaySourceAnalysis
  102. rowkey = playSourceKey(mid)
  103. )
  104. defer cancel()
  105. log.Info("UpPlaySourceAnalysis mid(%d)|rowkey(%s)", mid, rowkey)
  106. if result, err = d.hbase.GetStr(ctx, tableName, rowkey); err != nil {
  107. log.Error("d.hbase.GetStr tableName(%s)|mid(%d)|rowkey(%s)|error(%v)", tableName, mid, rowkey, err)
  108. err = ecode.CreativeDataErr
  109. return
  110. }
  111. if result == nil || len(result.Cells) == 0 {
  112. log.Warn("UpPlaySourceAnalysis no data tableName(%s)|mid(%d)|rowkey(%s)", tableName, mid, rowkey)
  113. return
  114. }
  115. pp := make(map[string]int32)
  116. ps := make(map[string]int32)
  117. for _, c := range result.Cells {
  118. if c == nil {
  119. continue
  120. }
  121. if string(c.Family) == "s" {
  122. var v int32
  123. if len(c.Value) == 4 {
  124. v = int32(binary.BigEndian.Uint32(c.Value))
  125. } else {
  126. log.Error("UpPlaySourceAnalysis family[s] get dirty value tableName(%s)|mid(%d)|rowkey(%s)", tableName, mid, rowkey)
  127. }
  128. if pyk, ok := playProportion[string(c.Qualifier[:])]; ok {
  129. pp[pyk] = v
  130. }
  131. if pk, ok := pageSource[string(c.Qualifier[:])]; ok {
  132. ps[pk] = v
  133. }
  134. }
  135. }
  136. for _, k := range playProportion { //播放平台设置数据平台未返回的key
  137. if _, ok := pp[k]; !ok {
  138. pp[k] = 0
  139. }
  140. }
  141. for _, k := range pageSource { //播放页面设置数据平台未返回的key
  142. if _, ok := ps[k]; !ok {
  143. ps[k] = 0
  144. }
  145. }
  146. var other int32
  147. for k, v := range ps {
  148. if sourceOtherMerge(k) { //如果该页面来源被计算入其他则删除该页面来源对应的key
  149. other = other + v
  150. delete(ps, k)
  151. }
  152. }
  153. ps["other"] = other
  154. res = &data.PlaySource{
  155. PlayProportion: pp,
  156. PageSource: ps,
  157. }
  158. log.Info("UpPlaySourceAnalysis PlayProportion(%+v)|PageSource(%+v)|rowkey(%s)", pp, ps, rowkey)
  159. return
  160. }
  161. // UpArcPlayAnalysis for arc play analysis.
  162. func (d *Dao) UpArcPlayAnalysis(c context.Context, aid int64) (res *data.ArchivePlay, err error) {
  163. var (
  164. result *hrpc.Result
  165. ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
  166. tableName = HBaseUpArcPlayAnalysis
  167. rowkey = arcPlayKey(aid)
  168. )
  169. defer cancel()
  170. log.Info("UpArcPlayAnalysis aid(%d)|rowkey(%s)", aid, rowkey)
  171. if result, err = d.hbase.GetStr(ctx, tableName, rowkey); err != nil {
  172. log.Error("d.hbase.GetStr tableName(%s)|aid(%d)|rowkey(%+v)|error(%v)", tableName, aid, rowkey, err)
  173. err = ecode.CreativeDataErr
  174. return
  175. }
  176. if result == nil || len(result.Cells) == 0 {
  177. log.Warn("UpArcPlayAnalysis no data tableName(%s)|aid(%d)|rowkey(%+v)", tableName, aid, rowkey)
  178. return
  179. }
  180. ap := &data.ArchivePlay{}
  181. for _, c := range result.Cells {
  182. if c == nil {
  183. continue
  184. }
  185. if string(c.Family) == "v" {
  186. ap.AID = aid
  187. switch string(c.Qualifier[:]) {
  188. case "ctime":
  189. if len(c.Value) == 4 {
  190. ap.CTime = int32(binary.BigEndian.Uint32(c.Value))
  191. } else {
  192. log.Error("UpArcPlayAnalysis family[ctime] get dirty value tableName(%s)|aid(%d)|rowkey(%s)", tableName, aid, rowkey)
  193. }
  194. case "uv":
  195. if len(c.Value) == 4 {
  196. ap.View = int32(binary.BigEndian.Uint32(c.Value))
  197. } else {
  198. log.Error("UpArcPlayAnalysis family[uv] get dirty value tableName(%s)|aid(%d)|rowkey(%s)", tableName, aid, rowkey)
  199. }
  200. case "dur":
  201. if len(c.Value) == 8 {
  202. ap.Duration = int64(binary.BigEndian.Uint64(c.Value))
  203. } else {
  204. log.Error("UpArcPlayAnalysis family[dur] get dirty value tableName(%s)|aid(%d)|rowkey(%s)", tableName, aid, rowkey)
  205. }
  206. case "avg_dur":
  207. if len(c.Value) == 8 {
  208. ap.AvgDuration = int64(binary.BigEndian.Uint64(c.Value))
  209. } else {
  210. log.Error("UpArcPlayAnalysis family[avg_dur] get dirty value tableName(%s)|aid(%d)|rowkey(%s)", tableName, aid, rowkey)
  211. }
  212. case "rate":
  213. if len(c.Value) == 4 {
  214. ap.Rate = int32(binary.BigEndian.Uint32(c.Value))
  215. } else {
  216. log.Error("UpArcPlayAnalysis family[rate] get dirty value tableName(%s)|aid(%d)|rowkey(%s)", tableName, aid, rowkey)
  217. }
  218. }
  219. }
  220. }
  221. res = ap
  222. log.Info("UpArcPlayAnalysis aid(%d)|rowkey(%s)|res(%+v)", aid, rowkey, res)
  223. return
  224. }
  225. // UpArcQuery for play aids by mid.
  226. func (d *Dao) UpArcQuery(c context.Context, mid int64, dt string, cp int) (res []int64, err error) {
  227. var (
  228. result *hrpc.Result
  229. ctx, cancel = context.WithTimeout(c, time.Duration(d.c.HBase.ReadTimeout))
  230. tableName = HBaseUpArcQuery
  231. rowkey = arcQueryKey(mid, dt, cp)
  232. )
  233. defer cancel()
  234. log.Info("UpArcQuery mid(%d)|rowkey(%s)", mid, rowkey)
  235. if result, err = d.hbase.GetStr(ctx, tableName, rowkey); err != nil {
  236. log.Error("d.hbase.GetStr tableName(%s)|mid(%d)|rowkey(%s)|error(%v)", tableName, mid, rowkey, err)
  237. err = ecode.CreativeDataErr
  238. return
  239. }
  240. if result == nil || len(result.Cells) == 0 {
  241. log.Warn("UpArcQuery no data tableName(%s)|mid(%d)|rowkey(%s)", tableName, mid, rowkey)
  242. return
  243. }
  244. res = make([]int64, 0)
  245. for _, c := range result.Cells {
  246. if c == nil {
  247. continue
  248. }
  249. if string(c.Family) == "av" {
  250. var v int64
  251. if len(c.Value) == 4 {
  252. v = int64(binary.BigEndian.Uint32(c.Value))
  253. } else {
  254. log.Error("UpArcQuery family[av] get dirty value tableName(%s)|rowkey(%s)", tableName, rowkey)
  255. }
  256. res = append(res, v)
  257. }
  258. }
  259. log.Info("UpArcQuery mid(%d)|rowkey(%s)|res(%+v)", mid, rowkey, res)
  260. return
  261. }