jiantaoli 4 years ago
parent
commit
502ea89226
3 changed files with 373 additions and 152 deletions
  1. 1 0
      .idea/dictionaries/zhanlangpc.xml
  2. 197 152
      adslib/addata/custom.go
  3. 175 0
      adslib/redis_data/redis_data.go

+ 1 - 0
.idea/dictionaries/zhanlangpc.xml

@@ -2,6 +2,7 @@
2 2
   <dictionary name="zhanlangpc">
3 3
     <words>
4 4
       <w>smembers</w>
5
+      <w>srem</w>
5 6
     </words>
6 7
   </dictionary>
7 8
 </component>

+ 197 - 152
adslib/addata/custom.go

@@ -1,10 +1,13 @@
1 1
 package addata
2 2
 
3 3
 import (
4
+	"fmt"
4 5
 	"math/rand"
5 6
 	"miads/adslib/redis_data"
6 7
 	"miads/adslib/utils"
8
+	"strconv"
7 9
 	"strings"
10
+	"time"
8 11
 )
9 12
 
10 13
 func CombineOrderBy(adData *AdData, dsp *utils.DspParam) {
@@ -81,39 +84,52 @@ func getOneAds(dsp *utils.DspParam, orderType int, fixFlag int) (*redis_data.AdO
81 84
 	return nil, nil
82 85
 }
83 86
 
84
-func getSubTimeValue(adData *redis_data.AdOrderInfo, a) {
85
-	b_min = int(ads_item['begin_time'])
86
-	b_min = datetime.fromtimestamp(b_min)
87
+// 获取投放数量
88
+func getNeedDispatchCount(adData *redis_data.AdOrderInfo) (int,error) {
89
+	beginTime := time.Unix(adData.BeginTime, 0)
87 90
 
88 91
 	// 获取当前分钟值
89
-	now_minute = b_min.minute + (b_min.hour * 60)
92
+	beginMinute := beginTime.Minute() + (beginTime.Hour() * 60)
90 93
 
91
-	// 不足一天
92
-	all_count = 1587820.0
93
-	e_time = int(ads_item['end_time'])
94
+	// 获取起点分钟, 不知道原因, 不加会有bug
95
+	beginMinute += 2
94 96
 
95
-	// 获取起点分钟
96
-	be_minute = now_minute + 2
97 97
 	// 获取分钟数到24点还能跑多少值
98
-	key = "time_all_count_" + str(be_minute)
99
-	if int(ads_item['line_type']) == 1:
100
-	// 定制曲线
101
-	key = "time_all_count_{0}_{1}".format(ads_item['order_id'], str(be_minute))
98
+	key := "time_all_count_" + strconv.Itoa(beginMinute)
99
+	// 0 默认曲线, 1 定制曲线
100
+	if adData.LineType == 1 {
101
+		key = fmt.Sprintf("time_all_count_%d_%d", adData.OrderID, beginMinute)
102
+	}
103
+
102 104
 	// 起始剩余值
103
-	all_count = redis_tools.get_key_int_value(key)
105
+	beginRemainDispatchCount, err := redis_data.GetRemainDispatchCount(key)
106
+	if err != nil {
107
+		return 0, err
108
+	}
104 109
 
105 110
 	// 计算最后分钟
106
-	e_d = datetime.fromtimestamp(e_time)
107
-	e_d_min = e_d.minute + (e_d.hour * 60)
108
-	if e_d_min > 1439:
109
-	e_d_min = e_d_min - 1440 + 2
110
-	key = "time_all_count_" + str(e_d_min)
111
-	if int(ads_item['line_type']) == 1:
112
-	// 定制曲线
113
-	key = "time_all_count_{0}_{1}".format(ads_item['order_id'], str(e_d_min))
111
+	endTime := time.Unix(adData.EndTime, 0)
112
+
113
+	endMinute := endTime.Minute() + (endTime.Hour() * 60)
114
+	if endMinute > 1439 {
115
+		// 不懂这里逻辑
116
+		endMinute = endMinute - 1440 + 2
117
+	}
118
+
119
+	key = "time_all_count_" + strconv.Itoa(endMinute)
120
+	if adData.LineType == 1 {
121
+		// 定制曲线
122
+		key = fmt.Sprintf("time_all_count_%d_%d", adData.OrderID, endMinute)
123
+	}
124
+
125
+	endRemainDispatchCnt, err := redis_data.GetRemainDispatchCount(key)
126
+	if err != nil {
127
+		return 0, err
128
+	}
129
+
114 130
 	// 结束的剩余值 - 起始剩余值 = 获取区间能跑的值
115
-	all_count = all_count - redis_tools.get_key_int_value(key)
116
-	return all_count
131
+	needDispatchCount := beginRemainDispatchCount - endRemainDispatchCnt
132
+	return needDispatchCount, nil
117 133
 }
118 134
 
119 135
 func GetAdsInfos(dsp *utils.DspParam, advertiser string, orderType int, fixFlag int, xiaomiHasFlag int) {
@@ -137,138 +153,167 @@ func GetAdsInfos(dsp *utils.DspParam, advertiser string, orderType int, fixFlag
137 153
 		}
138 154
 	}
139 155
 
140
-	a = datetime.now()
141
-
142 156
 	// 获取剩余时间内的值
143
-	all_count = get_sub_time_value(ads_item, a)
144
-	all_count = all_count * 1.0
145
-
146
-	#已经投放的key
147
-	show_key = "order_kpi_%s_%d%d%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day)
148
-	click_key = "order_kpi_%s_%d%d%d_click_kpi" % (ads_item['order_id'], a.year, a.month, a.day)
149
-	over_kpi = redis_tools.get_key_int_value(show_key)
150
-	show_kpi = ads_item['show_kpi']
151
-	click_kpi = ads_item['click_kpi']
152
-	if all_count < 1:
153
-	raise
154
-	gen.Return((None, None))
155
-	plan_key = "plan_all_kpi_%s_%d%d%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day)
156
-	redis_common.redis_ads().set(plan_key, all_count, 60*24*60)
157
-
158
-	w_value, rate = get_now_min_value(ads_item, all_count, show_kpi, a)
159
-	if w_value < 1:
160
-	w_value = 1
161
-
162
-	plan_key = "plan_kpi_%s_%d%d%d_%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day, a.hour*60 + a.minute)
163
-	redis_common.redis_ads().set(plan_key, w_value, 60*24*60)
164
-
165
-	over_key = "order_kpi_%s_%d%d%d_%d_show_kpi" % (ads_item['order_id'], a.year, a.month, a.day, a.hour*60 + a.minute)
166
-	o_value = int(redis_tools.get_key_int_value(over_key))
167
-
168
-	js_order_id = int(ads_item['js_order_id'])
169
-	if o_value < w_value:
170
-	order_name = ads_item['title']
171
-	data =
172
-	{
173
-		"js_order_id":js_order_id,
174
-		"target":"",
175
-		"video_url":"",
176
-		"duration":5,
177
-		"target_addition":[],
178
-		"image_url":"",
179
-		"result":0,
180
-		"msg":0,
181
-		"user_agent":ua,
182
-		"order_name":order_name
157
+	needDispatchCnt, err := getNeedDispatchCount(order)
158
+	if err != nil {
159
+		return err
160
+	}
161
+
162
+	if needDispatchCnt < 1 {
163
+		return nil, nil
183 164
 	}
184 165
 
185
-	#放量
186
-	redis_tools.incr_key_value(over_key)
187
-	redis_tools.incr_key_value(show_key)
188
-	show_url = ads_item['show_url']
189
-	click_url = ads_item['click_url']
190
-
191
-	target = ads_item['target_url']
192
-
193
-	if order_name.find("_ios") > 0:
194
-	ios_imei, ios_ua = get_ios_ua_imei(dsp)
195
-	if ios_ua:
196
-	data['user_agent'] = ios_ua
197
-	if ads_item.get('imei_replace_flag', 0) == 1 and
198
-ios_imei:
199
-	show_url = show_url.replace('__IDFA__', ios_imei)
200
-	click_url = click_url.replace('__IDFA__', ios_imei)
201
-	target = target.replace('__IDFA__', ios_imei)
202
-	if order_name.find("__OS__") > 0:
203
-	show_url = show_url.replace('__OS__', '1')
204
-	click_url = click_url.replace('__OS__', '1')
205
-	target = target.replace('__OS__', '1')
206
-
207
-	elif
208
-	order_name.find("_android") > 0 :
209
-	### 判断是否需要替换imei
210
-	if ads_item.get('imei_replace_flag', 0) == 1:
211
-	show_url = show_url.replace('__IMEI__', dsp.real_md5_imei)
212
-	click_url = click_url.replace('__IMEI__', dsp.real_md5_imei)
213
-	target = target.replace('__IMEI__', dsp.real_md5_imei)
214
-
215
-	if order_name.find("__OS__") > 0:
216
-	show_url = show_url.replace('__OS__', '0')
217
-	click_url = click_url.replace('__OS__', '0')
218
-	target = target.replace('__OS__', '0')
166
+	curTime := time.Now()
219 167
 
220
-	else:
221
-	if r < 40:
222
-	ios_imei, ios_ua = get_ios_ua_imei(dsp)
223
-	if ios_ua:
224
-	data['user_agent'] = ios_ua
225
-	if ads_item.get('imei_replace_flag', 0) == 1 and
226
-ios_imei:
227
-	show_url = show_url.replace('__IDFA__', ios_imei)
228
-	click_url = click_url.replace('__IDFA__', ios_imei)
229
-	target = target.replace('__IDFA__', ios_imei)
230
-	if order_name.find("__OS__") > 0:
231
-	show_url = show_url.replace('__OS__', '1')
232
-	click_url = click_url.replace('__OS__', '1')
233
-	target = target.replace('__OS__', '1')
234
-	else:
235
-	if ads_item.get('imei_replace_flag', 0) == 1:
236
-	show_url = show_url.replace('__IMEI__', dsp.real_md5_imei)
237
-	click_url = click_url.replace('__IMEI__', dsp.real_md5_imei)
238
-	target = target.replace('__IMEI__', dsp.real_md5_imei)
239
-	if order_name.find("__OS__") > 0:
240
-	show_url = show_url.replace('__OS__', '0')
241
-	click_url = click_url.replace('__OS__', '0')
242
-	target = target.replace('__OS__', '0')
243
-
244
-	if order_name.find("__IP__") > 0:
245
-	show_url = show_url.replace('__IP__', dsp.ip)
246
-	click_url = click_url.replace('__IP__', dsp.ip)
247
-	target = target.replace('__IP__', dsp.ip)
248
-	if order_type == 0:
249
-	addi = get_monitor_url('VIEW', 5, order_name, req_source, show_url)
250
-	else:
251
-	addi = get_monitor_url('VIEW', 5, order_name, 'follow', show_url)
252
-
253
-	#addi['urls'].append(show_url)
254
-	data['target_addition'].append(addi)
255
-
256
-	r = random.randint(0, 1000)
257
-	c_rate = click_kpi * 1.0 / (ads_item['show_kpi']) * 1000
258
-	if r < c_rate:
259
-	#下发点击
260
-	addi = get_monitor_url('CLICK', 1, order_name, req_source, click_url)
261
-	#addi['urls'].append(click_url)
262
-	data['target_addition'].append(addi)
263
-	md5_skip = hashlib.md5(target).hexdigest()
264
-	redis_tools.incr_key_value(click_key)
265
-	real_target = ads_config.Host + "?action=LOADING&req_source={0}&advertiser={2}&skip={1}&skip_other={3}".format(
266
-		req_source, '', order_name, md5_skip)
267
-	### 塞入缓存中
268
-	redis_tools.set_skip_info(md5_skip, target)
269
-	data['target'] = real_target
270
-	raise
271
-	gen.Return((None, data))
168
+	// #已经投放的key
169
+	finishShowCnt, err := redis_data.GetFinishedDispatchCount(order.OrderID, "show", curTime)
170
+	if err != nil {
171
+		return nil, err
172
+	}
173
+	finishClickCnt, err := redis_data.GetFinishedDispatchCount(order.OrderID, "click", curTime)
174
+	if err != nil {
175
+		return nil, err
176
+	}
177
+
178
+	redis_data.SetPlanDispatchCount(order.OrderID, "show", needDispatchCount, time.Now().Unix())
179
+
180
+	// 计算曲线比例
181
+	rate := float32(order.ShowKpi) / float32(needDispatchCnt)
182
+
183
+	curMinutes := curTime.Hour() * 60 + curTime.Minute()
184
+	key := "time_" + strconv.Itoa(curMinutes)
185
+	if order.LineType == 1 {
186
+		// 定制曲线
187
+		key = fmt.Sprintf("time_%d_%d", order.OrderID, curMinutes)
188
+	}
189
+
190
+	lineValue, err := redis_data.GetPerMinuteNeedDispatchCnt(order.OrderID, curTime)
191
+	if err != nil {
192
+		return nil, err
193
+	}
194
+	// 当前分钟需要放出去的数量
195
+	curMinuteNeedDispatchCnt := int(float32(lineValue) * rate)
196
+	if dispatchCnt < 1 {
197
+		dispatchCnt = 1
198
+	}
199
+
200
+	redis_data.SetOrderPlanDispatchCount(order.OrderID, "show", dispatchCnt, curTime)
201
+
202
+	// 获取当前分钟已经完成的下发
203
+	curMinutefinishedDispatchCnt, err := redis_data.GetPreMinuteFinishedDispatchCount(order.OrderID, "show", curTime)
204
+
205
+	if curMinutefinishedDispatchCnt < curMinuteNeedDispatchCnt {
206
+		data =
207
+		{
208
+			"js_order_id":js_order_id,
209
+			"target":"",
210
+			"video_url":"",
211
+			"duration":5,
212
+			"target_addition":[],
213
+			"image_url":"",
214
+			"result":0,
215
+			"msg":0,
216
+			"user_agent":ua,
217
+			"order_name":order_name
218
+		}
219
+
220
+		//放量
221
+		newFinishCnt, err := redis_data.IncrFinishedDispatchCount(order.OrderID, "show", 1, curTime)
222
+		if err != nil {
223
+			return err
224
+		}
225
+		newCurMinutefinishedCnt, err := redis_data.IncrPreMinuteFinishedDispatchCount(order.OrderID, "show", 1, curTime)
226
+		if err != nil {
227
+			return err
228
+		}
229
+
230
+		show_url = ads_item['show_url']
231
+		click_url = ads_item['click_url']
232
+
233
+		target = ads_item['target_url']
234
+
235
+		orderName := ads_item['title']
236
+		if strings.Index(order.Title, "_ios") != -1 {
237
+			ios_imei, ios_ua = get_ios_ua_imei(dsp)
238
+		}
239
+		if ios_ua:
240
+		data['user_agent'] = ios_ua
241
+		if ads_item.get('imei_replace_flag', 0) == 1 and
242
+	ios_imei:
243
+		show_url = show_url.replace('__IDFA__', ios_imei)
244
+		click_url = click_url.replace('__IDFA__', ios_imei)
245
+		target = target.replace('__IDFA__', ios_imei)
246
+		if order_name.find("__OS__") > 0:
247
+		show_url = show_url.replace('__OS__', '1')
248
+		click_url = click_url.replace('__OS__', '1')
249
+		target = target.replace('__OS__', '1')
250
+
251
+		elif
252
+		order_name.find("_android") > 0 :
253
+		### 判断是否需要替换imei
254
+		if ads_item.get('imei_replace_flag', 0) == 1:
255
+		show_url = show_url.replace('__IMEI__', dsp.real_md5_imei)
256
+		click_url = click_url.replace('__IMEI__', dsp.real_md5_imei)
257
+		target = target.replace('__IMEI__', dsp.real_md5_imei)
258
+
259
+		if order_name.find("__OS__") > 0:
260
+		show_url = show_url.replace('__OS__', '0')
261
+		click_url = click_url.replace('__OS__', '0')
262
+		target = target.replace('__OS__', '0')
263
+
264
+		else:
265
+		if r < 40:
266
+		ios_imei, ios_ua = get_ios_ua_imei(dsp)
267
+		if ios_ua:
268
+		data['user_agent'] = ios_ua
269
+		if ads_item.get('imei_replace_flag', 0) == 1 and
270
+	ios_imei:
271
+		show_url = show_url.replace('__IDFA__', ios_imei)
272
+		click_url = click_url.replace('__IDFA__', ios_imei)
273
+		target = target.replace('__IDFA__', ios_imei)
274
+		if order_name.find("__OS__") > 0:
275
+		show_url = show_url.replace('__OS__', '1')
276
+		click_url = click_url.replace('__OS__', '1')
277
+		target = target.replace('__OS__', '1')
278
+		else:
279
+		if ads_item.get('imei_replace_flag', 0) == 1:
280
+		show_url = show_url.replace('__IMEI__', dsp.real_md5_imei)
281
+		click_url = click_url.replace('__IMEI__', dsp.real_md5_imei)
282
+		target = target.replace('__IMEI__', dsp.real_md5_imei)
283
+		if order_name.find("__OS__") > 0:
284
+		show_url = show_url.replace('__OS__', '0')
285
+		click_url = click_url.replace('__OS__', '0')
286
+		target = target.replace('__OS__', '0')
287
+
288
+		if order_name.find("__IP__") > 0:
289
+		show_url = show_url.replace('__IP__', dsp.ip)
290
+		click_url = click_url.replace('__IP__', dsp.ip)
291
+		target = target.replace('__IP__', dsp.ip)
292
+		if order_type == 0:
293
+		addi = get_monitor_url('VIEW', 5, order_name, req_source, show_url)
294
+		else:
295
+		addi = get_monitor_url('VIEW', 5, order_name, 'follow', show_url)
296
+
297
+		#addi['urls'].append(show_url)
298
+		data['target_addition'].append(addi)
299
+
300
+		r = random.randint(0, 1000)
301
+		c_rate = click_kpi * 1.0 / (ads_item['show_kpi']) * 1000
302
+		if r < c_rate:
303
+		#下发点击
304
+		addi = get_monitor_url('CLICK', 1, order_name, req_source, click_url)
305
+		#addi['urls'].append(click_url)
306
+		data['target_addition'].append(addi)
307
+		md5_skip = hashlib.md5(target).hexdigest()
308
+		redis_tools.incr_key_value(click_key)
309
+		real_target = ads_config.Host + "?action=LOADING&req_source={0}&advertiser={2}&skip={1}&skip_other={3}".format(
310
+			req_source, '', order_name, md5_skip)
311
+		### 塞入缓存中
312
+		redis_tools.set_skip_info(md5_skip, target)
313
+		data['target'] = real_target
314
+		raise
315
+		gen.Return((None, data))
316
+	}
272 317
 	#获取当前已经放出去的次数
273 318
 	raise gen.Return((None, None))
274 319
 }~

+ 175 - 0
adslib/redis_data/redis_data.go

@@ -251,3 +251,178 @@ func SetReqSourceView(adv string, reqSource string, source string) {
251 251
 	key := fmt.Sprintf("view3_%s_%s_%d_%s", adv, reqSource, dateInt, source)
252 252
 	conn.Do("incr", key)
253 253
 }
254
+
255
+// 获取剩余总投放量
256
+func GetRemainDispatchCount(key string) (int, error)  {
257
+	conn := ads_redis.RedisConn.Get()
258
+	defer conn.Close()
259
+
260
+	rsp, err := conn.Do("GET", key)
261
+	if err != nil {
262
+		return 0, err
263
+	}
264
+
265
+	if rsp == nil {
266
+		return 0, nil
267
+	}
268
+
269
+	count, _ := redis.Int(rsp, err)
270
+	return count, nil
271
+}
272
+
273
+
274
+// 获取已经投放的量
275
+// dispatchType: "click", "show"
276
+func GetFinishedDispatchCount(orderId int64, dispatchType string, curTime time.Time) (int, error)  {
277
+	conn := ads_redis.RedisConn.Get()
278
+	defer conn.Close()
279
+
280
+	key := fmt.Sprintf("order_kpi_%d_%d%d%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), dispatchType)
281
+	rsp, err := conn.Do("GET", key)
282
+	if err != nil {
283
+		return 0, err
284
+	}
285
+
286
+	if rsp == nil {
287
+		return 0, nil
288
+	}
289
+
290
+	count, _ := redis.Int(rsp, err)
291
+	return count, nil
292
+}
293
+
294
+// 增加已经投放的量
295
+// dispatchType: "click", "show"
296
+func IncrFinishedDispatchCount(orderId int64, dispatchType string, incrCnt int, curTime time.Time) (int, error)  {
297
+	conn := ads_redis.RedisConn.Get()
298
+	defer conn.Close()
299
+
300
+	key := fmt.Sprintf("order_kpi_%d_%d%d%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), dispatchType)
301
+	rsp, err := conn.Do("INCR", key, incrCnt)
302
+	if err != nil {
303
+		return 0, err
304
+	}
305
+
306
+	count, _ := redis.Int(rsp, err)
307
+	return count, nil
308
+}
309
+
310
+// 获取当前分钟已经投放的量
311
+// dispatchType: "click", "show"
312
+func GetPreMinuteFinishedDispatchCount(orderId int64, dispatchType string, curTime time.Time) (int, error)  {
313
+	conn := ads_redis.RedisConn.Get()
314
+	defer conn.Close()
315
+
316
+	curMinutes := curTime.Hour() * 60 + curTime.Minute()
317
+	key := fmt.Sprintf("order_kpi_%d_%d%d%d_%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), curMinutes, dispatchType)
318
+	rsp, err := conn.Do("GET", key)
319
+	if err != nil {
320
+		return 0, err
321
+	}
322
+
323
+	if rsp == nil {
324
+		return 0, nil
325
+	}
326
+
327
+	count, _ := redis.Int(rsp, err)
328
+	return count, nil
329
+}
330
+
331
+// 增加当前分钟已经投放的量
332
+// dispatchType: "click", "show"
333
+func IncrPreMinuteFinishedDispatchCount(orderId int64, dispatchType string, incrCnt int, curTime time.Time) (int, error)  {
334
+	conn := ads_redis.RedisConn.Get()
335
+	defer conn.Close()
336
+
337
+	curMinutes := curTime.Hour() * 60 + curTime.Minute()
338
+	key := fmt.Sprintf("order_kpi_%d_%d%d%d_%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), curMinutes, dispatchType)
339
+	rsp, err := conn.Do("INCR", key, incrCnt)
340
+	if err != nil {
341
+		return 0, err
342
+	}
343
+	count, _ := redis.Int(rsp, err)
344
+	return count, nil
345
+}
346
+
347
+// 设置总计划投放数量
348
+// dispatchType: "click", "show"
349
+func SetPlanDispatchCount(orderId int64, dispatchType string, cnt int, curTime time.Time) {
350
+	conn := ads_redis.RedisConn.Get()
351
+	defer conn.Close()
352
+
353
+	key := fmt.Sprintf("plan_all_kpi_%d_%d%d%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), dispatchType)
354
+	conn.Do("SET", key, cnt, 3600*24)
355
+}
356
+
357
+// 设置订单计划投放数量
358
+// dispatchType: "click", "show"
359
+func SetOrderPlanDispatchCount(orderId int64, dispatchType string, cnt int, curTime time.Time) {
360
+	conn := ads_redis.RedisConn.Get()
361
+	defer conn.Close()
362
+
363
+	curMinutes := curTime.Hour() * 60 + curTime.Minute()
364
+	key := fmt.Sprintf("plan_kpi_%d_%d%d%d_%d_%s_kpi", orderId, curTime.Year(), curTime.Month(), curTime.Day(), curMinutes, dispatchType)
365
+	conn.Do("SET", key, cnt, 3600*24)
366
+}
367
+
368
+// 获取每分钟要投放的量
369
+func GetPerMinuteNeedDispatchCnt(orderId int64, curTime time.Time) (int, error){
370
+	conn := ads_redis.RedisConn.Get()
371
+	defer conn.Close()
372
+
373
+	curMinutes := curTime.Minute() + (curTime.Hour() * 60)
374
+	key := fmt.Sprintf("time_%d_%d", orderId, curMinutes)
375
+	rsp, err := conn.Do("GET", key)
376
+
377
+	if err != nil {
378
+		return 0, err
379
+	}
380
+
381
+	if rsp == nil {
382
+		return 0, nil
383
+	}
384
+
385
+	count, _ := redis.Int(rsp, err)
386
+	return count, nil
387
+}
388
+
389
+// 获取ios的ua和imei
390
+func GetIosUaImei(ip string) (string, string, error){
391
+	conn := ads_redis.RedisConn.Get()
392
+	defer conn.Close()
393
+
394
+	dateInt, _ := strconv.Atoi(time.Now().Format("20060102"))
395
+	redisKey := fmt.Sprintf("ads_ios_%d_%s", dateInt, ip)
396
+
397
+	// "{'imei': 'F389E3E1-5459-4B30-83A9-1AD504F6293F', 'ua': 'Mozilla/5.0 (iPhone; CPU iPhone OS 12_3_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML like Gecko) Mobile/15E148'}"
398
+	rsp, err := conn.Do("GET", redisKey)
399
+	if err != nil {
400
+		return "", "", err
401
+	}
402
+
403
+	if rsp == nil {
404
+		redisKey = fmt.Sprintf("new_ios_ua_v2_%d", dateInt)
405
+		rsp, err = conn.Do("SRANDMEMBER", redisKey)
406
+		if err != nil {
407
+			return "", "", err
408
+		}
409
+		if rsp == nil {
410
+			return "", "", nil
411
+		}
412
+
413
+		conn.Do("SREM", redisKey, rsp)
414
+
415
+		tomorrowDateInt := time.Unix(time.Now().Unix()+86400, 0).Format("20060102")
416
+		set_new_ios_ua(redis_value,tomorrow_day_id)
417
+		return eval(redis_value)
418
+	}
419
+
420
+	redis_ua_value = redis_ua.get_ip_ios_ua(ip)
421
+	if not redis_ua_value:
422
+	redis_ua_value = redis_ua.get_new_ios_ua()
423
+	if redis_ua_value:
424
+	redis_ua.set_ip_ios_ua(ip,redis_ua_value)
425
+	imei = redis_ua_value.get('imei','')
426
+	ua = redis_ua_value.get('ua','')
427
+	return imei,ua
428
+}