package device import ( "encoding/json" "fmt" "github.com/gomodule/redigo/redis" log "github.com/sirupsen/logrus" "math/rand" "miads/adslib/ads_redis" "strconv" "strings" "time" ) type DeviceConf struct { Imei string `json:"imei"` OriginImei string `json:"origin_imei"` Ua string `json:"ua"` } func SetAdsTagLog(adv string, reqSource string, key string, cityCode int) { k := fmt.Sprintf("%s___%s___%s___%d", adv, reqSource, key, cityCode) setTagLog(k) } func setTagLog(key string) { conn := ads_redis.RedisConn.Get() defer conn.Close() dateInt, _ := strconv.Atoi(time.Now().Format("20060102")) k := fmt.Sprintf("{%s}___{%d}", key, dateInt) _, _ = conn.Do("INCR", k) _, _ = conn.Do("SADD", "fresh_all_keys", k) } // 存储ip上一次请求时间 func SetIpReqTime(ip string, reqTime int64) { conn := ads_redis.RedisConn.Get() defer conn.Close() ipKey := strings.ReplaceAll(ip, ".", "") redisKey := "adip_" + ipKey _, _ = conn.Do("SET", redisKey, reqTime) } // 获取这个ip最近一次请求的时间 func GetIpReqTime(ip string) (int64, error) { conn := ads_redis.RedisConn.Get() defer conn.Close() ipKey := strings.ReplaceAll(ip, ".", "") redisKey := "adip_" + ipKey rsp, err := conn.Do("GET", redisKey) if err != nil { return 0, err } if rsp == nil { return 0, err } lastReqTime, _ := redis.Int64(rsp, err) return lastReqTime, nil } func SetMiDeviceConf(key string, d DeviceConf) error { conn := ads_redis.RedisConn.Get() defer conn.Close() deviceConfBytes, err := json.Marshal(d) if err != nil { return err } _, _ = conn.Do("set", key, deviceConfBytes, 86400) return nil } // 获取设备 func GetMiDeviceConf(ip string, randNum int, specialDeviceNum int) (*DeviceConf, string, error) { conn := ads_redis.RedisConn.Get() defer conn.Close() dateInt, _ := strconv.Atoi(time.Now().Format("20060102")) rd := 0 if specialDeviceNum == 0 { rd = rand.Intn(randNum-1) + 1 } else { rd = specialDeviceNum } redisKey := fmt.Sprintf("adur_%s_%d_%d_v4", ip, dateInt, rd) rsp, err := conn.Do("GET", redisKey) if err != nil { return nil, redisKey, err } if rsp == nil { return nil, redisKey, nil } rspBytes, _ := redis.Bytes(rsp, err) rspStr := strings.ReplaceAll(string(rspBytes), "u", "") rspStr = strings.ReplaceAll(string(rspStr), "'", "\"") d := DeviceConf{} err = json.Unmarshal([]byte(rspStr), &d) if err != nil { return nil, redisKey, err } return &d, redisKey, nil } // 设置每天的city_code的值 func SetDailyFakeDeviceConfByCityCode(cityCode int, d DeviceConf, dateInt int) error { conn := ads_redis.RedisConn.Get() defer conn.Close() redisKey := fmt.Sprintf("amdu_%d_%d", cityCode, dateInt) deviceConfBytes, err := json.Marshal(d) if err != nil { return err } _, _ = conn.Do("SADD", redisKey, deviceConfBytes) _, _ = conn.Do("expire", redisKey, 129600) return nil } // 获取每天的设备imei func GetDailyFakeDeviceConfByCityCode(cityCode int) (*DeviceConf, int, error) { conn := ads_redis.RedisConn.Get() defer conn.Close() dateInt, _ := strconv.Atoi(time.Now().Format("20060102")) redisKey := fmt.Sprintf("amdu_%d_%d", cityCode, dateInt) var validDeviceConf *DeviceConf // 防止无限跑 maxLoopCnt := 6 for i := 0; i < maxLoopCnt; i++ { rsp, err := conn.Do("srandmember", redisKey) if err != nil { return nil, 0, err } if rsp == nil { return nil, 0, nil } rspBytes, _ := redis.Bytes(rsp, err) d := DeviceConf{} err = json.Unmarshal(rspBytes, &d) if err != nil { continue } isBlackItem, err := CheckIsBlackImei(d.Imei) if err != nil { continue } if !isBlackItem { validDeviceConf = &d break } AddCityCodeBlackImei(cityCode, d.Imei) } if validDeviceConf != nil { // 用过的device_id放入明天的key中 tomorrowDateInt, _ := strconv.Atoi(time.Now().AddDate(0, 0, 1).Format("20060102")) err := SetDailyFakeDeviceConfByCityCode(cityCode, *validDeviceConf, tomorrowDateInt) if err != nil { log.Errorf("set daily fake device conf by city code failed: %s", err) } } // 获取剩余的量 leftCnt, err := redis.Int(conn.Do("SCARD", redisKey)) if err != nil { return nil, 0, err } return validDeviceConf, leftCnt, nil } // 检查是否是黑名单 func CheckIsBlackImei(imei string) (bool, error) { conn := ads_redis.RedisConn.Get() defer conn.Close() redisKey := "ads_black_device_" + imei[0:2] isBlackImei, err := redis.Bool(conn.Do("SISMEMBER", redisKey, imei)) if err != nil { return false, err } return isBlackImei, nil } // 存储city_code对应下的设备黑名单 func AddCityCodeBlackImei(cityCode int, imei string) { conn := ads_redis.RedisConn.Get() defer conn.Close() redisKey := fmt.Sprintf("blic_%d", cityCode) _, _ = conn.Do("sadd", redisKey, imei) }