smartpush 1.4.7__py3-none-any.whl → 1.4.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smartpush/base/__init__.py +0 -0
- smartpush/base/faker_data.py +679 -0
- smartpush/base/request_base.py +22 -0
- smartpush/base/url_enum.py +30 -0
- smartpush/export/basic/ExcelExportChecker.py +67 -3
- smartpush/form/__init__.py +0 -0
- smartpush/form/form_after.py +143 -0
- smartpush/form/form_assert.py +17 -0
- smartpush/form/form_before.py +9 -0
- smartpush/form/form_client_operation.py +19 -0
- smartpush/utils/form_utils.py +34 -0
- {smartpush-1.4.7.dist-info → smartpush-1.4.8.dist-info}/METADATA +1 -1
- smartpush-1.4.8.dist-info/RECORD +28 -0
- {smartpush-1.4.7.dist-info → smartpush-1.4.8.dist-info}/WHEEL +1 -1
- smartpush/test.py +0 -215
- smartpush-1.4.7.dist-info/RECORD +0 -19
- {smartpush-1.4.7.dist-info → smartpush-1.4.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
from enum import Enum, unique
|
2
|
+
|
3
|
+
|
4
|
+
@unique
|
5
|
+
class URL(Enum):
|
6
|
+
"""
|
7
|
+
:type:表单报告
|
8
|
+
"""
|
9
|
+
pageFormReportDetail = '/formReport/detail/pageFormReportDetail', 'POST' # 获取表单收集数据
|
10
|
+
getFormReportDetail = '/formReport/getFormReportDetail', 'POST' # 获取表单报告数据(曝光/点击)
|
11
|
+
getFormPerformanceTrend = 'formReport/getFormPerformanceTrend', 'POST'
|
12
|
+
|
13
|
+
"""
|
14
|
+
:type 群组
|
15
|
+
"""
|
16
|
+
editCrowdPackage = '/crowdPackage/editCrowdPackage', 'POST'
|
17
|
+
crowdPersonList = '/crowdPackage/crowdPersonList', 'POST'
|
18
|
+
|
19
|
+
@property
|
20
|
+
def method(self):
|
21
|
+
return self.value[1]
|
22
|
+
|
23
|
+
@property
|
24
|
+
def url(self):
|
25
|
+
return self.value[0]
|
26
|
+
|
27
|
+
|
28
|
+
if __name__ == '__main__':
|
29
|
+
print(URL.pageFormReportDetail.method)
|
30
|
+
print(URL.getFormReportDetail.url)
|
@@ -285,6 +285,68 @@ def check_excel_header(actual, expected, **kwargs):
|
|
285
285
|
return False, f"表头校验异常 {e}"
|
286
286
|
|
287
287
|
|
288
|
+
def check_excel_header_by_list(actual, expected, **kwargs):
|
289
|
+
"""
|
290
|
+
比较导出表头是否一致是否一致
|
291
|
+
@param actual: 可以传oss链接
|
292
|
+
@param expected:期望的表头list
|
293
|
+
@return:
|
294
|
+
@return:
|
295
|
+
"""
|
296
|
+
|
297
|
+
global diff
|
298
|
+
try:
|
299
|
+
if not isinstance(actual, io.BytesIO):
|
300
|
+
actual = read_excel_from_oss(actual)
|
301
|
+
actual1, expected1 = read_excel_header(actual, **kwargs)[0], get_header_map_data(
|
302
|
+
expected)
|
303
|
+
actual1.sort()
|
304
|
+
try:
|
305
|
+
diff = compare_lists(actual1, expected1)
|
306
|
+
assert not diff # 为空则错误
|
307
|
+
return True, "表头校验值与顺序一致"
|
308
|
+
except AssertionError as e:
|
309
|
+
print("actual:", actual1)
|
310
|
+
print("expected:", expected1)
|
311
|
+
return False, f"表头校验值与顺序失败 {diff}"
|
312
|
+
except Exception as e:
|
313
|
+
return False, e
|
314
|
+
|
315
|
+
|
316
|
+
def get_header_map_data(name_list):
|
317
|
+
"""
|
318
|
+
获取头映射关系--中文
|
319
|
+
:param name_list:
|
320
|
+
:return:
|
321
|
+
"""
|
322
|
+
header_dict_zh_cn = {
|
323
|
+
"sendTypeName": "活动类型",
|
324
|
+
"activityName": "活动名称",
|
325
|
+
"sendTotal": "发送数",
|
326
|
+
"deliveryTotal": "送达数",
|
327
|
+
"deliveryRate": "送达率",
|
328
|
+
"openRate": ["打开率(打开数/送达数)", "打开数"],
|
329
|
+
"noRepeatOpenRate": ["不重复打开率", "不重复打开"],
|
330
|
+
"clickRate": ["点击率(点击数/送达数)", "点击数"],
|
331
|
+
"noRepeatClickRate": ["不重复点击率", "不重复点击"],
|
332
|
+
"salesPriceTotal": "销售额",
|
333
|
+
"orderTotal": "订单数",
|
334
|
+
"averageOrderValue": "平均订单价值",
|
335
|
+
"conversionRate": "转化率",
|
336
|
+
"unsubTotal": "退订数",
|
337
|
+
"unsubRate": "退订率",
|
338
|
+
"complainRate": "弹回率",
|
339
|
+
"bounceRate": "投诉率",
|
340
|
+
"sendStartTime": "发送时间"
|
341
|
+
}
|
342
|
+
header_list = []
|
343
|
+
for key, value in header_dict_zh_cn.items():
|
344
|
+
if key in name_list:
|
345
|
+
header_list.append(value) if not isinstance(value, list) else header_list.extend(value)
|
346
|
+
header_list.sort()
|
347
|
+
return header_list
|
348
|
+
|
349
|
+
|
288
350
|
def del_temp_file(file_name=""):
|
289
351
|
"""删除temp下临时文件"""
|
290
352
|
file_path = os.path.join(os.path.dirname(os.getcwd()) + "/temp_file/" + file_name)
|
@@ -378,12 +440,14 @@ def check_field_format(actual_oss, **kwargs):
|
|
378
440
|
if kwargs["fileds"][key][filed_key] == "email":
|
379
441
|
fool = DataTypeUtils.DataTypeUtils().check_email_format(email=row[filed_key])
|
380
442
|
if not fool:
|
381
|
-
errors.append(
|
443
|
+
errors.append(
|
444
|
+
f"{actual_dict_key[key]} 表, 第{num}行{filed_key}列{kwargs['fileds'][key][filed_key]}格式不符合规范, 值为:{row[filed_key]}")
|
382
445
|
elif kwargs["fileds"][key][filed_key] == "time":
|
383
|
-
fool = DataTypeUtils.DataTypeUtils().check_time_format(time_str=row[filed_key],
|
446
|
+
fool = DataTypeUtils.DataTypeUtils().check_time_format(time_str=row[filed_key],
|
447
|
+
precision=kwargs.get('precision', 's'))
|
384
448
|
if not fool:
|
385
449
|
errors.append(
|
386
450
|
f"{actual_dict_key[key]} 表, 第{num}行{filed_key}列{kwargs['fileds'][key][filed_key]}格式不符合规范, 值为:{row[filed_key]}")
|
387
451
|
num += 1
|
388
452
|
print(errors if len(errors) > 0 else "都校验成功")
|
389
|
-
return False if len(errors) > 0 else True
|
453
|
+
return False if len(errors) > 0 else True
|
File without changes
|
@@ -0,0 +1,143 @@
|
|
1
|
+
import json
|
2
|
+
from tenacity import retry, stop_after_attempt, wait_fixed
|
3
|
+
from smartpush.base.request_base import RequestBase
|
4
|
+
from smartpush.base.url_enum import URL
|
5
|
+
from smartpush.export.basic.GetOssUrl import log_attempt
|
6
|
+
|
7
|
+
|
8
|
+
class FormAfter(RequestBase):
|
9
|
+
def __init__(self, form_id, headers, host):
|
10
|
+
super().__init__(headers, host)
|
11
|
+
self.form_id = form_id
|
12
|
+
|
13
|
+
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2), after=log_attempt)
|
14
|
+
def callPageFormReportDetail(self, reportDetailType, start_time=None, end_time=None):
|
15
|
+
"""
|
16
|
+
获取PageFormReportDetail数据
|
17
|
+
:param end_time:
|
18
|
+
:param start_time:
|
19
|
+
:param reportDetailType:
|
20
|
+
:return:
|
21
|
+
"""
|
22
|
+
requestParam = {"page": 1, "pageSize": 20, "reportDetailType": reportDetailType, "formId": self.form_id}
|
23
|
+
if start_time is not None and end_time is not None:
|
24
|
+
requestParam["startTime"] = start_time
|
25
|
+
requestParam["endTime"] = end_time
|
26
|
+
result = self.post(url=self.host + URL.pageFormReportDetail.url, data=json.dumps(requestParam)).json()
|
27
|
+
result.raise_for_status()
|
28
|
+
persons_list = result["resultData"]["reportDetailData"]["datas"]
|
29
|
+
return persons_list
|
30
|
+
|
31
|
+
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2), after=log_attempt)
|
32
|
+
def callGetFormReportDetail(self):
|
33
|
+
requestParam = {"formId": self.form_id}
|
34
|
+
result = self.post(url=self.host + URL.getFormReportDetail.url, data=json.dumps(requestParam)).json()
|
35
|
+
result.raise_for_status()
|
36
|
+
resultData = result["resultData"]
|
37
|
+
return resultData
|
38
|
+
|
39
|
+
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2), after=log_attempt)
|
40
|
+
def callGetFormPerformanceTrend(self):
|
41
|
+
requestParam = {"formId": self.form_id}
|
42
|
+
result = self.post(url=self.host + URL.getFormPerformanceTrend.url, data=json.dumps(requestParam)).json()
|
43
|
+
result.raise_for_status()
|
44
|
+
resultData = result["resultData"]
|
45
|
+
return resultData
|
46
|
+
|
47
|
+
@retry(stop=stop_after_attempt(3), wait=wait_fixed(2), after=log_attempt)
|
48
|
+
def callEditCrowdPackage(self, _id=None, groupRules=None, groupRelation="$AND"):
|
49
|
+
"""
|
50
|
+
更新群组条件id
|
51
|
+
:param _id:
|
52
|
+
:param groupRules:
|
53
|
+
:param groupRelation:
|
54
|
+
:return:
|
55
|
+
"""
|
56
|
+
requestParam = {"id": _id, "crowdName": "表单查询群组-自动化", "groupRelation": groupRelation,
|
57
|
+
"groupRules": groupRules, "triggerStock": False}
|
58
|
+
result = self.post(url=self.host + URL.editCrowdPackage.url, data=json.dumps(requestParam)).json()
|
59
|
+
result.raise_for_status()
|
60
|
+
assert result.get("code") == 1
|
61
|
+
resultData = result["resultData"]
|
62
|
+
assert resultData.get("status") == 2
|
63
|
+
return resultData["id"]
|
64
|
+
|
65
|
+
def callCrowdPersonList(self, _id, page, pageSize, filter_type, filter_value):
|
66
|
+
requestParam = {"id": _id, "page": page, "pageSize": pageSize}
|
67
|
+
if filter_value is not None:
|
68
|
+
requestParam["filter"] = {filter_type: {"in": filter_value}}
|
69
|
+
result = self.post(url=self.host + URL.crowdPersonList.url, data=json.dumps(requestParam)).json()
|
70
|
+
result.raise_for_status()
|
71
|
+
return result['resultData']
|
72
|
+
|
73
|
+
# -------- 处理数据 --------------
|
74
|
+
def collectFormDetails(self, key, start_time=None, end_time=None):
|
75
|
+
"""
|
76
|
+
从表单收集明细中获取信息,判断是否收集成功
|
77
|
+
:param self:
|
78
|
+
:param key: 关键词
|
79
|
+
:param start_time: 开始时间
|
80
|
+
:param end_time: 结束时间
|
81
|
+
"""
|
82
|
+
persons_list = self.callPageFormReportDetail("FORM_COLLECT", start_time, end_time)
|
83
|
+
if persons_list:
|
84
|
+
for person in persons_list:
|
85
|
+
if person['email'] == key:
|
86
|
+
return True, person
|
87
|
+
elif person['phone'] == key:
|
88
|
+
return True, person
|
89
|
+
else:
|
90
|
+
return False, None
|
91
|
+
|
92
|
+
def FormReportNumQuery(self, num_type="viewNum", assertNum=None):
|
93
|
+
"""
|
94
|
+
表单数据数据统计
|
95
|
+
:param assertNum:
|
96
|
+
:param num_type:viewNum/clickNum/collectNum/orderNum
|
97
|
+
"""
|
98
|
+
data = self.callGetFormReportDetail()
|
99
|
+
if data is not None:
|
100
|
+
if assertNum is None:
|
101
|
+
var = data.get(num_type)
|
102
|
+
return var
|
103
|
+
else:
|
104
|
+
return data.get(num_type) == assertNum
|
105
|
+
|
106
|
+
def getFormAttributionSales(self, key, start_time=None, end_time=None):
|
107
|
+
"""
|
108
|
+
判断折扣码是否能正确归因
|
109
|
+
:param key:
|
110
|
+
:param start_time:
|
111
|
+
:param end_time:
|
112
|
+
:return:
|
113
|
+
"""
|
114
|
+
order_list = self.callPageFormReportDetail("FORM_SALES", start_time, end_time)
|
115
|
+
if order_list:
|
116
|
+
for order in order_list:
|
117
|
+
if order['email'] == key:
|
118
|
+
return True, order
|
119
|
+
elif order['phone'] == key:
|
120
|
+
return True, order
|
121
|
+
elif order['orderId'] == key:
|
122
|
+
return True, order
|
123
|
+
else:
|
124
|
+
return False, None
|
125
|
+
|
126
|
+
def getFormLineChart(self, date=None, num_type="viewNum", assertNum=None):
|
127
|
+
"""
|
128
|
+
获取表单折线图
|
129
|
+
:param assertNum:
|
130
|
+
:param date:
|
131
|
+
:param num_type:viewNum/clickNum/collectNum
|
132
|
+
"""
|
133
|
+
datas = dict(self.callGetFormPerformanceTrend())
|
134
|
+
if datas is not None:
|
135
|
+
for data in datas:
|
136
|
+
if data.get(date):
|
137
|
+
if assertNum is not None:
|
138
|
+
assert data.get(num_type) == assertNum
|
139
|
+
else:
|
140
|
+
return data.get(num_type)
|
141
|
+
|
142
|
+
def getCrowdPersonList(self, _id, page=1, pageSize=20, filter_type="email", filter_value=""):
|
143
|
+
self.callCrowdPersonList(self,_id,page,pageSize,filter_type,filter_value)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import base64
|
2
|
+
from Crypto.Cipher import AES
|
3
|
+
from Crypto.Util.Padding import pad, unpad
|
4
|
+
|
5
|
+
|
6
|
+
def aes_encrypt(data, key, iv):
|
7
|
+
"""
|
8
|
+
参数加密
|
9
|
+
:param data:
|
10
|
+
:param key:
|
11
|
+
:param iv:
|
12
|
+
:return:
|
13
|
+
"""
|
14
|
+
key = key.encode('utf-8')
|
15
|
+
iv = iv.encode('utf-8')
|
16
|
+
cipher = AES.new(key, AES.MODE_CBC, iv)
|
17
|
+
ciphertext = cipher.encrypt(pad(data.encode('utf-8'), AES.block_size))
|
18
|
+
return base64.b64encode(ciphertext).decode('utf-8')
|
19
|
+
|
20
|
+
|
21
|
+
def aes_decrypt(ciphertext, key, iv):
|
22
|
+
"""
|
23
|
+
参数解密
|
24
|
+
:param ciphertext:
|
25
|
+
:param key:
|
26
|
+
:param iv:
|
27
|
+
:return:
|
28
|
+
"""
|
29
|
+
key = key.encode('utf-8')
|
30
|
+
iv = iv.encode('utf-8')
|
31
|
+
ciphertext = base64.b64decode(ciphertext)
|
32
|
+
cipher = AES.new(key, AES.MODE_CBC, iv)
|
33
|
+
decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)
|
34
|
+
return decrypted_data.decode('utf-8')
|
@@ -0,0 +1,28 @@
|
|
1
|
+
smartpush/__init__.py,sha256=XJrl1vhGATHSeSVqKmPXxYqxyseriUpvY5tLIXir3EE,24
|
2
|
+
smartpush/get_jira_info.py,sha256=OYaDV6VPAmkGKYLlRnsi1ZyKHU8xEiVnjsYrc41ZR0U,17910
|
3
|
+
smartpush/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
4
|
+
smartpush/base/faker_data.py,sha256=TOd5EKVImxZpsKEW_dtKa2iqiUGqU7OBkOM8pvqKVUc,24643
|
5
|
+
smartpush/base/request_base.py,sha256=Fn1uPWgaZQZdu8yyi2n13nuiKPVeR95iwx99sG6XGVU,574
|
6
|
+
smartpush/base/url_enum.py,sha256=REHYP_aa0xumLg8El-yrNRpablLnPEQpss8ZNPdkNtg,787
|
7
|
+
smartpush/export/__init__.py,sha256=D9GbWcmwnetEndFDty5XbVienFK1WjqV2yYcQp3CM84,99
|
8
|
+
smartpush/export/basic/ExcelExportChecker.py,sha256=CFTytcowwf1xfoRE5DZayY8kKJqppYQ0smVIokfxitM,19833
|
9
|
+
smartpush/export/basic/GetOssUrl.py,sha256=LeF1y1_uJaYXth1KvO6mEDS29ezb9tliBv5SrbqYkXc,6136
|
10
|
+
smartpush/export/basic/ReadExcel.py,sha256=ZnG2mtYqLY-xuYx9SyulbdYUP_0E5jIeKDewfakAsTw,7342
|
11
|
+
smartpush/export/basic/__init__.py,sha256=6tcrS-2NSlsJo-UwEsnGUmwCf7jgOsh_UEbM0FD-gYE,70
|
12
|
+
smartpush/flow/MockFlow.py,sha256=MI8WIMZyKlxrV5QVs8rXX6iD07Ldl37_L5Yb5FWqHzU,8595
|
13
|
+
smartpush/flow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
14
|
+
smartpush/form/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
+
smartpush/form/form_after.py,sha256=a7d5G8Es3gRIzXiFDkI2McW_zq3FACfMxjRVBwSmK24,5866
|
16
|
+
smartpush/form/form_assert.py,sha256=wPIRfQHhr7lN1fFd-mp0z_qKMtF4jfrNxRWvp2xfqCg,257
|
17
|
+
smartpush/form/form_before.py,sha256=CCvAC_2yWPlnQGtjEA8LPLy9853Nq3nNjcL2GewFWIs,175
|
18
|
+
smartpush/form/form_client_operation.py,sha256=gg-5uHXCyMa_ypBSYPYFVxXdwZdYBJsNtUCqayknMBw,303
|
19
|
+
smartpush/utils/DataTypeUtils.py,sha256=BC7ioztO3vAfKd1EOoNvXdVuXYY8qjNskV1DP7LhW-M,1082
|
20
|
+
smartpush/utils/EmailUtlis.py,sha256=DAHd73bJ8hiJCLEXtD0xcwxPD7SOPSmBB7Jvlf6gN6s,11201
|
21
|
+
smartpush/utils/ListDictUtils.py,sha256=Fm5_d7UyY6xB8gySMPdl5jIFSRhXZcYXdYW-_L1alcE,1640
|
22
|
+
smartpush/utils/StringUtils.py,sha256=n8mo9k0JQN63MReImgv-66JxmmymOGknR8pH2fkQrAo,4139
|
23
|
+
smartpush/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
+
smartpush/utils/form_utils.py,sha256=ld-g_Dm_ZlnagQt7imYfUc87bcBRVlTctywuLtzmjXQ,849
|
25
|
+
smartpush-1.4.8.dist-info/METADATA,sha256=_Fh1DOsWYzvBYYvSbFzc98qbWwEGBrsGgC3RjmStBno,131
|
26
|
+
smartpush-1.4.8.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
27
|
+
smartpush-1.4.8.dist-info/top_level.txt,sha256=5_CXqu08EfbPaKLjuSAOAqCmGU6shiatwDU_ViBGCmg,10
|
28
|
+
smartpush-1.4.8.dist-info/RECORD,,
|