device.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. package device
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "github.com/gomodule/redigo/redis"
  6. log "github.com/sirupsen/logrus"
  7. "math/rand"
  8. "miads/adslib"
  9. "miads/adslib/ads_redis"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. type DeviceConf struct {
  15. Imei string `json:"imei"`
  16. OriginImei string `json:"origin_imei"`
  17. Ua string `json:"ua"`
  18. }
  19. func SetAdsTagLog(adv string, reqSource string, key string, cityCode int) {
  20. k := fmt.Sprintf("%s___%s___%s___%d", adv, reqSource, key, cityCode)
  21. setTagLog(k)
  22. }
  23. func setTagLog(key string) {
  24. if adslib.GetConf().TestMode {
  25. return
  26. }
  27. conn := ads_redis.RedisConn.Get()
  28. defer conn.Close()
  29. dateInt, _ := strconv.Atoi(time.Now().Format("20060102"))
  30. k := fmt.Sprintf("{%s}___{%d}", key, dateInt)
  31. _, _ = conn.Do("INCR", k)
  32. _, _ = conn.Do("SADD", "fresh_all_keys", k)
  33. }
  34. // 存储ip上一次请求时间
  35. func SetIpReqTime(ip string, reqTime int64) {
  36. if adslib.GetConf().TestMode {
  37. return
  38. }
  39. conn := ads_redis.RedisConn.Get()
  40. defer conn.Close()
  41. ipKey := strings.ReplaceAll(ip, ".", "")
  42. redisKey := "adip_" + ipKey
  43. _, _ = conn.Do("SET", redisKey, reqTime)
  44. }
  45. // 获取这个ip最近一次请求的时间
  46. func GetIpReqTime(ip string) (int64, error) {
  47. conn := ads_redis.RedisConn.Get()
  48. defer conn.Close()
  49. ipKey := strings.ReplaceAll(ip, ".", "")
  50. redisKey := "adip_" + ipKey
  51. rsp, err := conn.Do("GET", redisKey)
  52. if err != nil {
  53. return 0, err
  54. }
  55. if rsp == nil {
  56. return 0, err
  57. }
  58. lastReqTime, _ := redis.Int64(rsp, err)
  59. return lastReqTime, nil
  60. }
  61. func SetMiDeviceConf(key string, d DeviceConf) error {
  62. if adslib.GetConf().TestMode {
  63. return nil
  64. }
  65. conn := ads_redis.RedisConn.Get()
  66. defer conn.Close()
  67. deviceConfBytes, err := json.Marshal(d)
  68. if err != nil {
  69. return err
  70. }
  71. _, _ = conn.Do("set", key, deviceConfBytes, 86400)
  72. return nil
  73. }
  74. // 获取设备
  75. func GetMiDeviceConf(ip string, randNum int, specialDeviceNum int) (*DeviceConf, string, error) {
  76. conn := ads_redis.RedisConn.Get()
  77. defer conn.Close()
  78. dateInt, _ := strconv.Atoi(time.Now().Format("20060102"))
  79. rd := 0
  80. if specialDeviceNum == 0 {
  81. rd = rand.Intn(randNum-1) + 1
  82. } else {
  83. rd = specialDeviceNum
  84. }
  85. redisKey := fmt.Sprintf("adur_%s_%d_%d_v4", ip, dateInt, rd)
  86. rsp, err := conn.Do("GET", redisKey)
  87. if err != nil {
  88. return nil, redisKey, err
  89. }
  90. if rsp == nil {
  91. return nil, redisKey, nil
  92. }
  93. rspBytes, _ := redis.Bytes(rsp, err)
  94. rspStr := strings.ReplaceAll(string(rspBytes), "u", "")
  95. rspStr = strings.ReplaceAll(string(rspStr), "'", "\"")
  96. d := DeviceConf{}
  97. err = json.Unmarshal([]byte(rspStr), &d)
  98. if err != nil {
  99. return nil, redisKey, err
  100. }
  101. return &d, redisKey, nil
  102. }
  103. // 设置每天的city_code的值
  104. func SetDailyFakeDeviceConfByCityCode(cityCode int, d DeviceConf, dateInt int) error {
  105. if adslib.GetConf().TestMode {
  106. return nil
  107. }
  108. conn := ads_redis.RedisConn.Get()
  109. defer conn.Close()
  110. redisKey := fmt.Sprintf("amdu_%d_%d", cityCode, dateInt)
  111. deviceConfBytes, err := json.Marshal(d)
  112. if err != nil {
  113. return err
  114. }
  115. _, _ = conn.Do("SADD", redisKey, deviceConfBytes)
  116. _, _ = conn.Do("expire", redisKey, 129600)
  117. return nil
  118. }
  119. // 获取每天的设备imei
  120. func GetDailyFakeDeviceConfByCityCode(cityCode int) (*DeviceConf, int, error) {
  121. conn := ads_redis.RedisConn.Get()
  122. defer conn.Close()
  123. dateInt, _ := strconv.Atoi(time.Now().Format("20060102"))
  124. redisKey := fmt.Sprintf("amdu_%d_%d", cityCode, dateInt)
  125. var validDeviceConf *DeviceConf
  126. // 防止无限跑
  127. maxLoopCnt := 6
  128. for i := 0; i < maxLoopCnt; i++ {
  129. rsp, err := conn.Do("srandmember", redisKey)
  130. if err != nil {
  131. return nil, 0, err
  132. }
  133. if rsp == nil {
  134. return nil, 0, nil
  135. }
  136. rspBytes, _ := redis.Bytes(rsp, err)
  137. d := DeviceConf{}
  138. err = json.Unmarshal(rspBytes, &d)
  139. if err != nil {
  140. continue
  141. }
  142. isBlackItem, err := CheckIsBlackImei(d.Imei)
  143. if err != nil {
  144. continue
  145. }
  146. if !isBlackItem {
  147. validDeviceConf = &d
  148. break
  149. }
  150. AddCityCodeBlackImei(cityCode, d.Imei)
  151. }
  152. if validDeviceConf != nil {
  153. // 用过的device_id放入明天的key中
  154. tomorrowDateInt, _ := strconv.Atoi(time.Now().AddDate(0, 0, 1).Format("20060102"))
  155. err := SetDailyFakeDeviceConfByCityCode(cityCode, *validDeviceConf, tomorrowDateInt)
  156. if err != nil {
  157. log.Errorf("set daily fake device conf by city code failed: %s", err)
  158. }
  159. }
  160. // 获取剩余的量
  161. leftCnt, err := redis.Int(conn.Do("SCARD", redisKey))
  162. if err != nil {
  163. return nil, 0, err
  164. }
  165. return validDeviceConf, leftCnt, nil
  166. }
  167. // 检查是否是黑名单
  168. func CheckIsBlackImei(imei string) (bool, error) {
  169. conn := ads_redis.RedisConn.Get()
  170. defer conn.Close()
  171. redisKey := "ads_black_device_" + imei[0:2]
  172. isBlackImei, err := redis.Bool(conn.Do("SISMEMBER", redisKey, imei))
  173. if err != nil {
  174. return false, err
  175. }
  176. return isBlackImei, nil
  177. }
  178. // 存储city_code对应下的设备黑名单
  179. func AddCityCodeBlackImei(cityCode int, imei string) {
  180. conn := ads_redis.RedisConn.Get()
  181. defer conn.Close()
  182. redisKey := fmt.Sprintf("blic_%d", cityCode)
  183. _, _ = conn.Do("sadd", redisKey, imei)
  184. }