re-common 10.0.22__py3-none-any.whl → 10.0.24__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.
- re_common/baselibrary/__init__.py +4 -4
- re_common/baselibrary/baseabs/__init__.py +6 -6
- re_common/baselibrary/baseabs/baseabs.py +26 -26
- re_common/baselibrary/database/mbuilder.py +132 -132
- re_common/baselibrary/database/moudle.py +93 -93
- re_common/baselibrary/database/msqlite3.py +194 -194
- re_common/baselibrary/database/mysql.py +169 -169
- re_common/baselibrary/database/sql_factory.py +26 -26
- re_common/baselibrary/mthread/MThreadingRun.py +486 -486
- re_common/baselibrary/mthread/MThreadingRunEvent.py +349 -349
- re_common/baselibrary/mthread/__init__.py +2 -2
- re_common/baselibrary/mthread/mythreading.py +695 -695
- re_common/baselibrary/pakge_other/socks.py +404 -404
- re_common/baselibrary/readconfig/config_factory.py +18 -18
- re_common/baselibrary/readconfig/ini_config.py +317 -317
- re_common/baselibrary/readconfig/toml_config.py +49 -49
- re_common/baselibrary/temporary/envdata.py +36 -36
- re_common/baselibrary/tools/all_requests/aiohttp_request.py +118 -118
- re_common/baselibrary/tools/all_requests/httpx_requet.py +102 -102
- re_common/baselibrary/tools/all_requests/mrequest.py +412 -412
- re_common/baselibrary/tools/all_requests/requests_request.py +81 -81
- re_common/baselibrary/tools/batch_compre/bijiao_batch.py +31 -31
- re_common/baselibrary/tools/contrast_db3.py +123 -123
- re_common/baselibrary/tools/copy_file.py +39 -39
- re_common/baselibrary/tools/db3_2_sizedb3.py +102 -102
- re_common/baselibrary/tools/foreachgz.py +39 -39
- re_common/baselibrary/tools/get_attr.py +10 -10
- re_common/baselibrary/tools/image_to_pdf.py +61 -61
- re_common/baselibrary/tools/java_code_deal.py +139 -139
- re_common/baselibrary/tools/javacode.py +79 -79
- re_common/baselibrary/tools/mdb_db3.py +48 -48
- re_common/baselibrary/tools/merge_file.py +171 -171
- re_common/baselibrary/tools/merge_gz_file.py +165 -165
- re_common/baselibrary/tools/mhdfstools/down_hdfs_files.py +42 -42
- re_common/baselibrary/tools/mhdfstools/hdfst.py +42 -42
- re_common/baselibrary/tools/mhdfstools/up_hdfs_files.py +38 -38
- re_common/baselibrary/tools/mongo_tools.py +50 -50
- re_common/baselibrary/tools/move_file.py +170 -170
- re_common/baselibrary/tools/move_mongo/mongo_table_to_file.py +63 -63
- re_common/baselibrary/tools/move_mongo/move_mongo_table.py +354 -354
- re_common/baselibrary/tools/move_mongo/use_mttf.py +18 -18
- re_common/baselibrary/tools/move_mongo/use_mv.py +93 -93
- re_common/baselibrary/tools/mpandas/mpandasreadexcel.py +125 -125
- re_common/baselibrary/tools/mpandas/pandas_visualization.py +7 -7
- re_common/baselibrary/tools/myparsel.py +104 -104
- re_common/baselibrary/tools/rename_dir_file.py +37 -37
- re_common/baselibrary/tools/sequoiadb_utils.py +398 -398
- re_common/baselibrary/tools/split_line_to_many.py +25 -25
- re_common/baselibrary/tools/stringtodicts.py +33 -33
- re_common/baselibrary/tools/workwechant_bot.py +84 -84
- re_common/baselibrary/utils/baseaiohttp.py +296 -296
- re_common/baselibrary/utils/baseaiomysql.py +87 -87
- re_common/baselibrary/utils/baseallstep.py +191 -191
- re_common/baselibrary/utils/baseavro.py +19 -19
- re_common/baselibrary/utils/baseboto3.py +291 -291
- re_common/baselibrary/utils/basecsv.py +32 -32
- re_common/baselibrary/utils/basedict.py +133 -133
- re_common/baselibrary/utils/basedir.py +241 -241
- re_common/baselibrary/utils/baseencode.py +351 -351
- re_common/baselibrary/utils/baseencoding.py +28 -28
- re_common/baselibrary/utils/baseesdsl.py +86 -86
- re_common/baselibrary/utils/baseexcel.py +264 -264
- re_common/baselibrary/utils/baseexcept.py +109 -109
- re_common/baselibrary/utils/basefile.py +654 -654
- re_common/baselibrary/utils/baseftp.py +214 -214
- re_common/baselibrary/utils/basegzip.py +60 -60
- re_common/baselibrary/utils/basehdfs.py +135 -135
- re_common/baselibrary/utils/basehttpx.py +268 -268
- re_common/baselibrary/utils/baseip.py +87 -87
- re_common/baselibrary/utils/basejson.py +2 -2
- re_common/baselibrary/utils/baselist.py +32 -32
- re_common/baselibrary/utils/basemotor.py +190 -190
- re_common/baselibrary/utils/basemssql.py +98 -98
- re_common/baselibrary/utils/baseodbc.py +113 -113
- re_common/baselibrary/utils/basepandas.py +302 -302
- re_common/baselibrary/utils/basepeewee.py +11 -11
- re_common/baselibrary/utils/basepika.py +180 -180
- re_common/baselibrary/utils/basepydash.py +143 -143
- re_common/baselibrary/utils/basepymongo.py +230 -230
- re_common/baselibrary/utils/basequeue.py +22 -22
- re_common/baselibrary/utils/baserar.py +57 -57
- re_common/baselibrary/utils/baserequest.py +279 -279
- re_common/baselibrary/utils/baseset.py +8 -8
- re_common/baselibrary/utils/basesmb.py +403 -403
- re_common/baselibrary/utils/basestring.py +382 -382
- re_common/baselibrary/utils/basetime.py +320 -320
- re_common/baselibrary/utils/baseurl.py +121 -121
- re_common/baselibrary/utils/basezip.py +57 -57
- re_common/baselibrary/utils/core/__init__.py +7 -7
- re_common/baselibrary/utils/core/bottomutils.py +18 -18
- re_common/baselibrary/utils/core/mdeprecated.py +327 -327
- re_common/baselibrary/utils/core/mlamada.py +16 -16
- re_common/baselibrary/utils/core/msginfo.py +25 -25
- re_common/baselibrary/utils/core/requests_core.py +103 -103
- re_common/baselibrary/utils/fateadm.py +429 -429
- re_common/baselibrary/utils/importfun.py +123 -123
- re_common/baselibrary/utils/mfaker.py +57 -57
- re_common/baselibrary/utils/my_abc/__init__.py +3 -3
- re_common/baselibrary/utils/my_abc/better_abc.py +32 -32
- re_common/baselibrary/utils/mylogger.py +414 -414
- re_common/baselibrary/utils/myredisclient.py +861 -861
- re_common/baselibrary/utils/pipupgrade.py +21 -21
- re_common/baselibrary/utils/ringlist.py +85 -85
- re_common/baselibrary/utils/version_compare.py +36 -36
- re_common/baselibrary/utils/ydmhttp.py +126 -126
- re_common/facade/lazy_import.py +11 -11
- re_common/facade/loggerfacade.py +25 -25
- re_common/facade/mysqlfacade.py +467 -467
- re_common/facade/now.py +31 -31
- re_common/facade/sqlite3facade.py +257 -257
- re_common/facade/use/mq_use_facade.py +83 -83
- re_common/facade/use/proxy_use_facade.py +19 -19
- re_common/libtest/base_dict_test.py +19 -19
- re_common/libtest/baseavro_test.py +13 -13
- re_common/libtest/basefile_test.py +14 -14
- re_common/libtest/basemssql_test.py +77 -77
- re_common/libtest/baseodbc_test.py +7 -7
- re_common/libtest/basepandas_test.py +38 -38
- re_common/libtest/get_attr_test/get_attr_test_settings.py +14 -14
- re_common/libtest/get_attr_test/settings.py +54 -54
- re_common/libtest/idencode_test.py +53 -53
- re_common/libtest/iniconfig_test.py +35 -35
- re_common/libtest/ip_test.py +34 -34
- re_common/libtest/merge_file_test.py +20 -20
- re_common/libtest/mfaker_test.py +8 -8
- re_common/libtest/mm3_test.py +31 -31
- re_common/libtest/mylogger_test.py +88 -88
- re_common/libtest/myparsel_test.py +27 -27
- re_common/libtest/mysql_test.py +151 -151
- re_common/libtest/pymongo_test.py +21 -21
- re_common/libtest/split_test.py +11 -11
- re_common/libtest/sqlite3_merge_test.py +5 -5
- re_common/libtest/sqlite3_test.py +34 -34
- re_common/libtest/tomlconfig_test.py +30 -30
- re_common/libtest/use_tools_test/__init__.py +2 -2
- re_common/libtest/user/__init__.py +4 -4
- re_common/studio/__init__.py +4 -4
- re_common/studio/assignment_expressions.py +36 -36
- re_common/studio/mydash/test1.py +18 -18
- re_common/studio/pydashstudio/first.py +9 -9
- re_common/studio/streamlitstudio/first_app.py +65 -65
- re_common/studio/streamlitstudio/uber_pickups.py +23 -23
- re_common/studio/test.py +18 -18
- re_common/v2/baselibrary/business_utils/BusinessStringUtil.py +195 -0
- re_common/v2/baselibrary/business_utils/__init__.py +0 -0
- re_common/v2/baselibrary/business_utils/rel_tools.py +6 -0
- re_common/v2/baselibrary/decorators/utils.py +59 -59
- re_common/v2/baselibrary/s3object/baseboto3.py +230 -230
- re_common/v2/baselibrary/tools/WeChatRobot.py +95 -79
- re_common/v2/baselibrary/tools/ac_ahocorasick.py +75 -75
- re_common/v2/baselibrary/tools/dict_tools.py +37 -37
- re_common/v2/baselibrary/tools/dolphinscheduler.py +187 -187
- re_common/v2/baselibrary/tools/hdfs_data_processer.py +338 -338
- re_common/v2/baselibrary/tools/list_tools.py +65 -65
- re_common/v2/baselibrary/tools/search_hash_tools.py +54 -54
- re_common/v2/baselibrary/tools/text_matcher.py +326 -326
- re_common/v2/baselibrary/tools/unionfind_tools.py +60 -60
- re_common/v2/baselibrary/utils/BusinessStringUtil.py +196 -196
- re_common/v2/baselibrary/utils/author_smi.py +360 -360
- re_common/v2/baselibrary/utils/base_string_similarity.py +158 -158
- re_common/v2/baselibrary/utils/basedict.py +37 -37
- re_common/v2/baselibrary/utils/basehdfs.py +161 -161
- re_common/v2/baselibrary/utils/basepika.py +180 -180
- re_common/v2/baselibrary/utils/basetime.py +77 -77
- re_common/v2/baselibrary/utils/db.py +38 -38
- re_common/v2/baselibrary/utils/json_cls.py +16 -16
- re_common/v2/baselibrary/utils/mq.py +83 -83
- re_common/v2/baselibrary/utils/n_ary_expression_tree.py +243 -243
- re_common/v2/baselibrary/utils/string_bool.py +186 -149
- re_common/v2/baselibrary/utils/string_clear.py +227 -204
- re_common/v2/baselibrary/utils/string_smi.py +18 -18
- re_common/v2/baselibrary/utils/stringutils.py +213 -213
- re_common/vip/base_step_process.py +11 -11
- re_common/vip/baseencodeid.py +90 -90
- re_common/vip/changetaskname.py +28 -28
- re_common/vip/core_var.py +24 -24
- re_common/vip/mmh3Hash.py +89 -89
- re_common/vip/proxy/allproxys.py +127 -127
- re_common/vip/proxy/allproxys_thread.py +159 -159
- re_common/vip/proxy/cnki_proxy.py +153 -153
- re_common/vip/proxy/kuaidaili.py +87 -87
- re_common/vip/proxy/proxy_all.py +113 -113
- re_common/vip/proxy/update_kuaidaili_0.py +42 -42
- re_common/vip/proxy/wanfang_proxy.py +152 -152
- re_common/vip/proxy/wp_proxy_all.py +181 -181
- re_common/vip/read_rawid_to_txt.py +91 -91
- re_common/vip/title/__init__.py +5 -5
- re_common/vip/title/transform/TransformBookTitleToZt.py +125 -125
- re_common/vip/title/transform/TransformConferenceTitleToZt.py +139 -139
- re_common/vip/title/transform/TransformCstadTitleToZt.py +195 -195
- re_common/vip/title/transform/TransformJournalTitleToZt.py +203 -203
- re_common/vip/title/transform/TransformPatentTitleToZt.py +132 -132
- re_common/vip/title/transform/TransformRegulationTitleToZt.py +114 -114
- re_common/vip/title/transform/TransformStandardTitleToZt.py +135 -135
- re_common/vip/title/transform/TransformThesisTitleToZt.py +135 -135
- re_common/vip/title/transform/__init__.py +10 -10
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/LICENSE +201 -201
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/METADATA +16 -16
- re_common-10.0.24.dist-info/RECORD +230 -0
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/WHEEL +1 -1
- re_common-10.0.22.dist-info/RECORD +0 -227
- {re_common-10.0.22.dist-info → re_common-10.0.24.dist-info}/top_level.txt +0 -0
|
@@ -1,230 +1,230 @@
|
|
|
1
|
-
from boto3.session import Session
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class BaseBoto3(object):
|
|
5
|
-
|
|
6
|
-
def __init__(self, aws_access_key_id="", aws_secret_access_key="", endpoint_url=""):
|
|
7
|
-
self.aws_access_key_id = aws_access_key_id
|
|
8
|
-
self.aws_secret_access_key = aws_secret_access_key
|
|
9
|
-
self.endpoint_url = endpoint_url
|
|
10
|
-
self.session = None
|
|
11
|
-
self.client = None
|
|
12
|
-
if self.aws_access_key_id and self.aws_secret_access_key and self.endpoint_url:
|
|
13
|
-
self.conn_session()
|
|
14
|
-
self.get_client()
|
|
15
|
-
|
|
16
|
-
def set_key(self, aws_access_key_id, aws_secret_access_key, endpoint_url):
|
|
17
|
-
self.aws_access_key_id = aws_access_key_id
|
|
18
|
-
self.aws_secret_access_key = aws_secret_access_key
|
|
19
|
-
self.endpoint_url = endpoint_url
|
|
20
|
-
return self
|
|
21
|
-
|
|
22
|
-
def conn_session(self):
|
|
23
|
-
assert self.aws_access_key_id not in (None, '')
|
|
24
|
-
assert self.aws_secret_access_key not in (None, '')
|
|
25
|
-
self.session = Session(aws_access_key_id=self.aws_access_key_id,
|
|
26
|
-
aws_secret_access_key=self.aws_secret_access_key)
|
|
27
|
-
return self.session
|
|
28
|
-
|
|
29
|
-
def get_client(self):
|
|
30
|
-
assert self.session is not None
|
|
31
|
-
self.client = self.session.client('s3', endpoint_url=self.endpoint_url)
|
|
32
|
-
return self
|
|
33
|
-
|
|
34
|
-
def get_all_buckets(self):
|
|
35
|
-
"""
|
|
36
|
-
获取所有的桶信息
|
|
37
|
-
:return:
|
|
38
|
-
"""
|
|
39
|
-
return self.client.list_buckets()
|
|
40
|
-
|
|
41
|
-
def create_buckets(self, buckets_name):
|
|
42
|
-
"""
|
|
43
|
-
如果get_client 使用 client 返回
|
|
44
|
-
{'ResponseMetadata': {'RequestId': '16BC90EED4A433C4', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'accept-ranges': 'bytes', 'content-length': '0', 'content-security-policy': 'block-all-mixed-content', 'location': '/create1', 'server': 'MinIO', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '16BC90EED4A433C4', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Wed, 01 Dec 2021 07:28:39 GMT'}, 'RetryAttempts': 0}, 'Location': '/create1'}
|
|
45
|
-
"""
|
|
46
|
-
assert buckets_name.find("_") == -1, "新建一个bucket桶(bucket name 中不能有_下划线)"
|
|
47
|
-
# 新建一个bucket桶(bucket name 中不能有_下划线)
|
|
48
|
-
return self.client.create_bucket(Bucket=buckets_name)
|
|
49
|
-
|
|
50
|
-
def delete_buckets(self, bucket_name):
|
|
51
|
-
"""
|
|
52
|
-
删除桶 删除bucket(只能删除空的bucket)
|
|
53
|
-
:return:
|
|
54
|
-
"""
|
|
55
|
-
response = self.client.delete_bucket(Bucket=bucket_name)
|
|
56
|
-
return response
|
|
57
|
-
|
|
58
|
-
def get_bucket(self, bucket_name):
|
|
59
|
-
raise Exception("无实现方法")
|
|
60
|
-
|
|
61
|
-
def get_all_objs(self, bucket_name, prefix=None, continuation_token=None):
|
|
62
|
-
"""
|
|
63
|
-
|
|
64
|
-
continuation_token: 如果超过1000 需要传第一次获取结果中的 continuation_token
|
|
65
|
-
|
|
66
|
-
response 的结构
|
|
67
|
-
{'ResponseMetadata': {'RequestId': '1818F447C1E7BA3B', 'HostId': '', 'HTTPStatusCode': 200,
|
|
68
|
-
'HTTPHeaders': {'accept-ranges': 'bytes', 'content-length': '3182', 'content-security-policy': 'block-all-mixed-content', 'content-type': 'application/xml',
|
|
69
|
-
'server': 'MinIO', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '1818F447C1E7BA3B',
|
|
70
|
-
'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Thu, 09 Jan 2025 07:04:05 GMT'}, 'RetryAttempts': 0},
|
|
71
|
-
'IsTruncated': False, 'Contents':
|
|
72
|
-
[
|
|
73
|
-
{'Key': 'zt_file/zt类型样例数据/11_part-00000.gz', 'LastModified': datetime.datetime(2024, 4, 28, 2, 56, 59, 716000, tzinfo=tzutc()), 'ETag': '"e0d635f171bce6a67ad72265e5f9137d-2"',
|
|
74
|
-
'Size': 18164139, 'StorageClass': 'STANDARD', 'Owner': {'DisplayName': 'minio', 'ID': '02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4'}},
|
|
75
|
-
{'Key': 'zt_file/zt类型样例数据/12_part-00000.gz', 'LastModified': datetime.datetime(2024, 4, 28, 2, 56, 57, 70000, tzinfo=tzutc()), 'ETag': '"f238fe9973a2bc0d3e1562c2938ce897-9"',
|
|
76
|
-
'Size': 93710911, 'StorageClass': 'STANDARD', 'Owner': {'DisplayName': 'minio', 'ID': '02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4'}},
|
|
77
|
-
],
|
|
78
|
-
'Name': 'crawl.dc.cqvip.com', 'Prefix': 'zt_file/zt类型样例数据', 'Delimiter': '',
|
|
79
|
-
'MaxKeys': 1000, 'EncodingType': 'url', 'KeyCount': 7}
|
|
80
|
-
|
|
81
|
-
"""
|
|
82
|
-
if continuation_token:
|
|
83
|
-
# 获取桶中以特定前缀开头的所有对象
|
|
84
|
-
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
85
|
-
Prefix=prefix,
|
|
86
|
-
ContinuationToken=continuation_token)
|
|
87
|
-
else:
|
|
88
|
-
# 获取桶中以特定前缀开头的所有对象
|
|
89
|
-
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
90
|
-
Prefix=prefix)
|
|
91
|
-
object_list = []
|
|
92
|
-
# 检查是否有对象存在
|
|
93
|
-
if 'Contents' in response:
|
|
94
|
-
object_list = [obj['Key'] for obj in response['Contents']]
|
|
95
|
-
|
|
96
|
-
continuation_token = None
|
|
97
|
-
# 检查是否有更多对象
|
|
98
|
-
if response.get('IsTruncated'): # 如果返回结果被截断,说明有更多对象
|
|
99
|
-
continuation_token = response.get('NextContinuationToken')
|
|
100
|
-
|
|
101
|
-
return object_list, continuation_token
|
|
102
|
-
|
|
103
|
-
def list_prefixes(self, bucket_name, prefix=None, Delimiter="/", continuation_token=None):
|
|
104
|
-
"""
|
|
105
|
-
获取目录下一层的目录
|
|
106
|
-
prefix: 注意 这个要以 Delimiter 结尾 比如 Delimiter="/" 那么 prefix="a/"
|
|
107
|
-
continuation_token: 如果超过1000 需要传第一次获取结果中的 continuation_token
|
|
108
|
-
return: ['a/b/', 'a/c/'] 注意 反回的 结果带有prefix 只能返回目录 不能返回文件
|
|
109
|
-
"""
|
|
110
|
-
if continuation_token:
|
|
111
|
-
# 获取桶中以特定前缀开头的所有对象
|
|
112
|
-
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
113
|
-
Prefix=prefix,
|
|
114
|
-
Delimiter=Delimiter, # 使用斜杠分隔符模拟目录结构
|
|
115
|
-
ContinuationToken=continuation_token)
|
|
116
|
-
else:
|
|
117
|
-
# 获取桶中以特定前缀开头的所有对象
|
|
118
|
-
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
119
|
-
Delimiter=Delimiter, # 使用斜杠分隔符模拟目录结构
|
|
120
|
-
Prefix=prefix)
|
|
121
|
-
object_list = []
|
|
122
|
-
# 检查是否有对象存在
|
|
123
|
-
if 'Contents' in response:
|
|
124
|
-
object_list = [obj['Key'] for obj in response['Contents']]
|
|
125
|
-
|
|
126
|
-
Prefix_list = []
|
|
127
|
-
# 检查是否有目录存在
|
|
128
|
-
if 'CommonPrefixes' in response:
|
|
129
|
-
Prefix_list = [obj['Prefix'] for obj in response['CommonPrefixes']]
|
|
130
|
-
|
|
131
|
-
continuation_token = None
|
|
132
|
-
# 检查是否有更多对象
|
|
133
|
-
if response.get('IsTruncated'): # 如果返回结果被截断,说明有更多对象
|
|
134
|
-
continuation_token = response.get('NextContinuationToken')
|
|
135
|
-
|
|
136
|
-
return object_list, Prefix_list, continuation_token
|
|
137
|
-
|
|
138
|
-
def get_object_value(self, bucket_name, file_key, encoding='utf-8'):
|
|
139
|
-
"""
|
|
140
|
-
读取文本数据
|
|
141
|
-
Returns:
|
|
142
|
-
"""
|
|
143
|
-
obj = self.client.get_object(Bucket=bucket_name, Key=file_key)
|
|
144
|
-
body = obj['Body'].read().decode(encoding)
|
|
145
|
-
return body
|
|
146
|
-
|
|
147
|
-
def put_object(self, bucket_name, key, body):
|
|
148
|
-
"""
|
|
149
|
-
直接写内容到文件
|
|
150
|
-
Args:
|
|
151
|
-
bucket_name:
|
|
152
|
-
key:
|
|
153
|
-
body: 需要 编码 .encode('utf-8')
|
|
154
|
-
|
|
155
|
-
Returns:
|
|
156
|
-
"""
|
|
157
|
-
self.client.put_object(Bucket=bucket_name,
|
|
158
|
-
Key=key,
|
|
159
|
-
Body=body)
|
|
160
|
-
|
|
161
|
-
def download_file(self, bucket_name, key, local_file):
|
|
162
|
-
"""
|
|
163
|
-
return: None
|
|
164
|
-
"""
|
|
165
|
-
result = self.client.download_file(bucket_name, key, local_file)
|
|
166
|
-
return result
|
|
167
|
-
|
|
168
|
-
def upload_file(self, bucket_name, key, local_file):
|
|
169
|
-
"""
|
|
170
|
-
# key 桶中的位置 test1/test.pdf
|
|
171
|
-
:param local_file: 本地文件路径
|
|
172
|
-
:param bucket_name: 桶名
|
|
173
|
-
:param key: 远程文件路径
|
|
174
|
-
:return:
|
|
175
|
-
"""
|
|
176
|
-
self.client.upload_file(local_file, bucket_name, key)
|
|
177
|
-
|
|
178
|
-
def download_fileobj(self, bucket_name, key, fileobj):
|
|
179
|
-
"""
|
|
180
|
-
return: None
|
|
181
|
-
"""
|
|
182
|
-
result = self.client.download_fileobj(bucket_name, key, fileobj)
|
|
183
|
-
return result
|
|
184
|
-
|
|
185
|
-
def upload_fileobj(self, bucket_name, key, fileobj):
|
|
186
|
-
# fileobj 字节流
|
|
187
|
-
self.client.upload_fileobj(fileobj, bucket_name, key)
|
|
188
|
-
|
|
189
|
-
def check_exist_or_file_info(self, bucket_name, key):
|
|
190
|
-
"""
|
|
191
|
-
检查文件是否存在且能获取文件info
|
|
192
|
-
{'ResponseMetadata': {'RequestId': '17E6A65A2B299D3B', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders':
|
|
193
|
-
{'accept-ranges': 'bytes', 'content-length': '117', 'content-security-policy': 'block-all-mixed-content', 'content-type': 'binary/octet-stream',
|
|
194
|
-
'etag': '"2237a934f176003e41abf3d733291079"', 'last-modified': 'Thu, 25 Jul 2024 05:49:43 GMT', 'server': 'MinIO',
|
|
195
|
-
'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '17E6A65A2B299D3B',
|
|
196
|
-
'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Mon, 29 Jul 2024 09:53:33 GMT'}, 'RetryAttempts': 0},
|
|
197
|
-
'AcceptRanges': 'bytes', 'LastModified': datetime.datetime(2024, 7, 25, 5, 49, 43, tzinfo=tzutc()), 'ContentLength': 117, 'ETag': '"2237a934f176003e41abf3d733291079"',
|
|
198
|
-
'ContentType': 'binary/octet-stream', 'Metadata': {}}
|
|
199
|
-
"""
|
|
200
|
-
try:
|
|
201
|
-
obj_info = self.client.head_object(
|
|
202
|
-
Bucket=bucket_name,
|
|
203
|
-
Key=key
|
|
204
|
-
)
|
|
205
|
-
return obj_info
|
|
206
|
-
except:
|
|
207
|
-
return None
|
|
208
|
-
|
|
209
|
-
def get_prefix_count(self, bucket_name, obj_count, prefix, continuation_token=None):
|
|
210
|
-
"""
|
|
211
|
-
统计 某个目录的文件数据量,由于需要每个目录获取一次 性能很慢
|
|
212
|
-
"""
|
|
213
|
-
for index in range(10000):
|
|
214
|
-
obj_list, dir_list, token = self.list_prefixes(bucket_name=bucket_name,
|
|
215
|
-
prefix=prefix,
|
|
216
|
-
continuation_token=continuation_token)
|
|
217
|
-
|
|
218
|
-
obj_count = obj_count + len(obj_list)
|
|
219
|
-
for dir_sub in dir_list:
|
|
220
|
-
obj_count = self.get_prefix_count(bucket_name, obj_count, dir_sub)
|
|
221
|
-
|
|
222
|
-
if token:
|
|
223
|
-
continuation_token = token
|
|
224
|
-
else:
|
|
225
|
-
break
|
|
226
|
-
|
|
227
|
-
if index > 10000 - 5:
|
|
228
|
-
raise Exception("循环耗尽,请检查逻辑正确性")
|
|
229
|
-
|
|
230
|
-
return obj_count
|
|
1
|
+
from boto3.session import Session
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BaseBoto3(object):
|
|
5
|
+
|
|
6
|
+
def __init__(self, aws_access_key_id="", aws_secret_access_key="", endpoint_url=""):
|
|
7
|
+
self.aws_access_key_id = aws_access_key_id
|
|
8
|
+
self.aws_secret_access_key = aws_secret_access_key
|
|
9
|
+
self.endpoint_url = endpoint_url
|
|
10
|
+
self.session = None
|
|
11
|
+
self.client = None
|
|
12
|
+
if self.aws_access_key_id and self.aws_secret_access_key and self.endpoint_url:
|
|
13
|
+
self.conn_session()
|
|
14
|
+
self.get_client()
|
|
15
|
+
|
|
16
|
+
def set_key(self, aws_access_key_id, aws_secret_access_key, endpoint_url):
|
|
17
|
+
self.aws_access_key_id = aws_access_key_id
|
|
18
|
+
self.aws_secret_access_key = aws_secret_access_key
|
|
19
|
+
self.endpoint_url = endpoint_url
|
|
20
|
+
return self
|
|
21
|
+
|
|
22
|
+
def conn_session(self):
|
|
23
|
+
assert self.aws_access_key_id not in (None, '')
|
|
24
|
+
assert self.aws_secret_access_key not in (None, '')
|
|
25
|
+
self.session = Session(aws_access_key_id=self.aws_access_key_id,
|
|
26
|
+
aws_secret_access_key=self.aws_secret_access_key)
|
|
27
|
+
return self.session
|
|
28
|
+
|
|
29
|
+
def get_client(self):
|
|
30
|
+
assert self.session is not None
|
|
31
|
+
self.client = self.session.client('s3', endpoint_url=self.endpoint_url)
|
|
32
|
+
return self
|
|
33
|
+
|
|
34
|
+
def get_all_buckets(self):
|
|
35
|
+
"""
|
|
36
|
+
获取所有的桶信息
|
|
37
|
+
:return:
|
|
38
|
+
"""
|
|
39
|
+
return self.client.list_buckets()
|
|
40
|
+
|
|
41
|
+
def create_buckets(self, buckets_name):
|
|
42
|
+
"""
|
|
43
|
+
如果get_client 使用 client 返回
|
|
44
|
+
{'ResponseMetadata': {'RequestId': '16BC90EED4A433C4', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'accept-ranges': 'bytes', 'content-length': '0', 'content-security-policy': 'block-all-mixed-content', 'location': '/create1', 'server': 'MinIO', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '16BC90EED4A433C4', 'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Wed, 01 Dec 2021 07:28:39 GMT'}, 'RetryAttempts': 0}, 'Location': '/create1'}
|
|
45
|
+
"""
|
|
46
|
+
assert buckets_name.find("_") == -1, "新建一个bucket桶(bucket name 中不能有_下划线)"
|
|
47
|
+
# 新建一个bucket桶(bucket name 中不能有_下划线)
|
|
48
|
+
return self.client.create_bucket(Bucket=buckets_name)
|
|
49
|
+
|
|
50
|
+
def delete_buckets(self, bucket_name):
|
|
51
|
+
"""
|
|
52
|
+
删除桶 删除bucket(只能删除空的bucket)
|
|
53
|
+
:return:
|
|
54
|
+
"""
|
|
55
|
+
response = self.client.delete_bucket(Bucket=bucket_name)
|
|
56
|
+
return response
|
|
57
|
+
|
|
58
|
+
def get_bucket(self, bucket_name):
|
|
59
|
+
raise Exception("无实现方法")
|
|
60
|
+
|
|
61
|
+
def get_all_objs(self, bucket_name, prefix=None, continuation_token=None):
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
continuation_token: 如果超过1000 需要传第一次获取结果中的 continuation_token
|
|
65
|
+
|
|
66
|
+
response 的结构
|
|
67
|
+
{'ResponseMetadata': {'RequestId': '1818F447C1E7BA3B', 'HostId': '', 'HTTPStatusCode': 200,
|
|
68
|
+
'HTTPHeaders': {'accept-ranges': 'bytes', 'content-length': '3182', 'content-security-policy': 'block-all-mixed-content', 'content-type': 'application/xml',
|
|
69
|
+
'server': 'MinIO', 'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '1818F447C1E7BA3B',
|
|
70
|
+
'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Thu, 09 Jan 2025 07:04:05 GMT'}, 'RetryAttempts': 0},
|
|
71
|
+
'IsTruncated': False, 'Contents':
|
|
72
|
+
[
|
|
73
|
+
{'Key': 'zt_file/zt类型样例数据/11_part-00000.gz', 'LastModified': datetime.datetime(2024, 4, 28, 2, 56, 59, 716000, tzinfo=tzutc()), 'ETag': '"e0d635f171bce6a67ad72265e5f9137d-2"',
|
|
74
|
+
'Size': 18164139, 'StorageClass': 'STANDARD', 'Owner': {'DisplayName': 'minio', 'ID': '02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4'}},
|
|
75
|
+
{'Key': 'zt_file/zt类型样例数据/12_part-00000.gz', 'LastModified': datetime.datetime(2024, 4, 28, 2, 56, 57, 70000, tzinfo=tzutc()), 'ETag': '"f238fe9973a2bc0d3e1562c2938ce897-9"',
|
|
76
|
+
'Size': 93710911, 'StorageClass': 'STANDARD', 'Owner': {'DisplayName': 'minio', 'ID': '02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4'}},
|
|
77
|
+
],
|
|
78
|
+
'Name': 'crawl.dc.cqvip.com', 'Prefix': 'zt_file/zt类型样例数据', 'Delimiter': '',
|
|
79
|
+
'MaxKeys': 1000, 'EncodingType': 'url', 'KeyCount': 7}
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
if continuation_token:
|
|
83
|
+
# 获取桶中以特定前缀开头的所有对象
|
|
84
|
+
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
85
|
+
Prefix=prefix,
|
|
86
|
+
ContinuationToken=continuation_token)
|
|
87
|
+
else:
|
|
88
|
+
# 获取桶中以特定前缀开头的所有对象
|
|
89
|
+
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
90
|
+
Prefix=prefix)
|
|
91
|
+
object_list = []
|
|
92
|
+
# 检查是否有对象存在
|
|
93
|
+
if 'Contents' in response:
|
|
94
|
+
object_list = [obj['Key'] for obj in response['Contents']]
|
|
95
|
+
|
|
96
|
+
continuation_token = None
|
|
97
|
+
# 检查是否有更多对象
|
|
98
|
+
if response.get('IsTruncated'): # 如果返回结果被截断,说明有更多对象
|
|
99
|
+
continuation_token = response.get('NextContinuationToken')
|
|
100
|
+
|
|
101
|
+
return object_list, continuation_token
|
|
102
|
+
|
|
103
|
+
def list_prefixes(self, bucket_name, prefix=None, Delimiter="/", continuation_token=None):
|
|
104
|
+
"""
|
|
105
|
+
获取目录下一层的目录
|
|
106
|
+
prefix: 注意 这个要以 Delimiter 结尾 比如 Delimiter="/" 那么 prefix="a/"
|
|
107
|
+
continuation_token: 如果超过1000 需要传第一次获取结果中的 continuation_token
|
|
108
|
+
return: ['a/b/', 'a/c/'] 注意 反回的 结果带有prefix 只能返回目录 不能返回文件
|
|
109
|
+
"""
|
|
110
|
+
if continuation_token:
|
|
111
|
+
# 获取桶中以特定前缀开头的所有对象
|
|
112
|
+
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
113
|
+
Prefix=prefix,
|
|
114
|
+
Delimiter=Delimiter, # 使用斜杠分隔符模拟目录结构
|
|
115
|
+
ContinuationToken=continuation_token)
|
|
116
|
+
else:
|
|
117
|
+
# 获取桶中以特定前缀开头的所有对象
|
|
118
|
+
response = self.client.list_objects_v2(Bucket=bucket_name,
|
|
119
|
+
Delimiter=Delimiter, # 使用斜杠分隔符模拟目录结构
|
|
120
|
+
Prefix=prefix)
|
|
121
|
+
object_list = []
|
|
122
|
+
# 检查是否有对象存在
|
|
123
|
+
if 'Contents' in response:
|
|
124
|
+
object_list = [obj['Key'] for obj in response['Contents']]
|
|
125
|
+
|
|
126
|
+
Prefix_list = []
|
|
127
|
+
# 检查是否有目录存在
|
|
128
|
+
if 'CommonPrefixes' in response:
|
|
129
|
+
Prefix_list = [obj['Prefix'] for obj in response['CommonPrefixes']]
|
|
130
|
+
|
|
131
|
+
continuation_token = None
|
|
132
|
+
# 检查是否有更多对象
|
|
133
|
+
if response.get('IsTruncated'): # 如果返回结果被截断,说明有更多对象
|
|
134
|
+
continuation_token = response.get('NextContinuationToken')
|
|
135
|
+
|
|
136
|
+
return object_list, Prefix_list, continuation_token
|
|
137
|
+
|
|
138
|
+
def get_object_value(self, bucket_name, file_key, encoding='utf-8'):
|
|
139
|
+
"""
|
|
140
|
+
读取文本数据
|
|
141
|
+
Returns:
|
|
142
|
+
"""
|
|
143
|
+
obj = self.client.get_object(Bucket=bucket_name, Key=file_key)
|
|
144
|
+
body = obj['Body'].read().decode(encoding)
|
|
145
|
+
return body
|
|
146
|
+
|
|
147
|
+
def put_object(self, bucket_name, key, body):
|
|
148
|
+
"""
|
|
149
|
+
直接写内容到文件
|
|
150
|
+
Args:
|
|
151
|
+
bucket_name:
|
|
152
|
+
key:
|
|
153
|
+
body: 需要 编码 .encode('utf-8')
|
|
154
|
+
|
|
155
|
+
Returns:
|
|
156
|
+
"""
|
|
157
|
+
self.client.put_object(Bucket=bucket_name,
|
|
158
|
+
Key=key,
|
|
159
|
+
Body=body)
|
|
160
|
+
|
|
161
|
+
def download_file(self, bucket_name, key, local_file):
|
|
162
|
+
"""
|
|
163
|
+
return: None
|
|
164
|
+
"""
|
|
165
|
+
result = self.client.download_file(bucket_name, key, local_file)
|
|
166
|
+
return result
|
|
167
|
+
|
|
168
|
+
def upload_file(self, bucket_name, key, local_file):
|
|
169
|
+
"""
|
|
170
|
+
# key 桶中的位置 test1/test.pdf
|
|
171
|
+
:param local_file: 本地文件路径
|
|
172
|
+
:param bucket_name: 桶名
|
|
173
|
+
:param key: 远程文件路径
|
|
174
|
+
:return:
|
|
175
|
+
"""
|
|
176
|
+
self.client.upload_file(local_file, bucket_name, key)
|
|
177
|
+
|
|
178
|
+
def download_fileobj(self, bucket_name, key, fileobj):
|
|
179
|
+
"""
|
|
180
|
+
return: None
|
|
181
|
+
"""
|
|
182
|
+
result = self.client.download_fileobj(bucket_name, key, fileobj)
|
|
183
|
+
return result
|
|
184
|
+
|
|
185
|
+
def upload_fileobj(self, bucket_name, key, fileobj):
|
|
186
|
+
# fileobj 字节流
|
|
187
|
+
self.client.upload_fileobj(fileobj, bucket_name, key)
|
|
188
|
+
|
|
189
|
+
def check_exist_or_file_info(self, bucket_name, key):
|
|
190
|
+
"""
|
|
191
|
+
检查文件是否存在且能获取文件info
|
|
192
|
+
{'ResponseMetadata': {'RequestId': '17E6A65A2B299D3B', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders':
|
|
193
|
+
{'accept-ranges': 'bytes', 'content-length': '117', 'content-security-policy': 'block-all-mixed-content', 'content-type': 'binary/octet-stream',
|
|
194
|
+
'etag': '"2237a934f176003e41abf3d733291079"', 'last-modified': 'Thu, 25 Jul 2024 05:49:43 GMT', 'server': 'MinIO',
|
|
195
|
+
'strict-transport-security': 'max-age=31536000; includeSubDomains', 'vary': 'Origin, Accept-Encoding', 'x-amz-request-id': '17E6A65A2B299D3B',
|
|
196
|
+
'x-content-type-options': 'nosniff', 'x-xss-protection': '1; mode=block', 'date': 'Mon, 29 Jul 2024 09:53:33 GMT'}, 'RetryAttempts': 0},
|
|
197
|
+
'AcceptRanges': 'bytes', 'LastModified': datetime.datetime(2024, 7, 25, 5, 49, 43, tzinfo=tzutc()), 'ContentLength': 117, 'ETag': '"2237a934f176003e41abf3d733291079"',
|
|
198
|
+
'ContentType': 'binary/octet-stream', 'Metadata': {}}
|
|
199
|
+
"""
|
|
200
|
+
try:
|
|
201
|
+
obj_info = self.client.head_object(
|
|
202
|
+
Bucket=bucket_name,
|
|
203
|
+
Key=key
|
|
204
|
+
)
|
|
205
|
+
return obj_info
|
|
206
|
+
except:
|
|
207
|
+
return None
|
|
208
|
+
|
|
209
|
+
def get_prefix_count(self, bucket_name, obj_count, prefix, continuation_token=None):
|
|
210
|
+
"""
|
|
211
|
+
统计 某个目录的文件数据量,由于需要每个目录获取一次 性能很慢
|
|
212
|
+
"""
|
|
213
|
+
for index in range(10000):
|
|
214
|
+
obj_list, dir_list, token = self.list_prefixes(bucket_name=bucket_name,
|
|
215
|
+
prefix=prefix,
|
|
216
|
+
continuation_token=continuation_token)
|
|
217
|
+
|
|
218
|
+
obj_count = obj_count + len(obj_list)
|
|
219
|
+
for dir_sub in dir_list:
|
|
220
|
+
obj_count = self.get_prefix_count(bucket_name, obj_count, dir_sub)
|
|
221
|
+
|
|
222
|
+
if token:
|
|
223
|
+
continuation_token = token
|
|
224
|
+
else:
|
|
225
|
+
break
|
|
226
|
+
|
|
227
|
+
if index > 10000 - 5:
|
|
228
|
+
raise Exception("循环耗尽,请检查逻辑正确性")
|
|
229
|
+
|
|
230
|
+
return obj_count
|
|
@@ -1,79 +1,95 @@
|
|
|
1
|
-
import sqlite3
|
|
2
|
-
import requests
|
|
3
|
-
import pandas as pd
|
|
4
|
-
import os
|
|
5
|
-
import json
|
|
6
|
-
import traceback
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
import sqlite3
|
|
2
|
+
import requests
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import os
|
|
5
|
+
import json
|
|
6
|
+
import traceback
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# c1d3a814-1a02-4bbd-b5c2-f756fef92cb8: b层机器人消息群-非聊天 的 pythonspark
|
|
10
|
+
# 013547da-3d78-4a7f-b4a7-e668b192c293: b层机器人消息群-非聊天 的 数仓B层服务端部署通知
|
|
11
|
+
|
|
12
|
+
# 发送消息到企业微信机器人
|
|
13
|
+
# vx_key: string类型,自己的企业微信机器人的key
|
|
14
|
+
# s:string类型,要发送的消息
|
|
15
|
+
def send_vx(vx_key, s, i=0):
|
|
16
|
+
vx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=' + vx_key
|
|
17
|
+
headers = {"Content-Type": "text/plain"}
|
|
18
|
+
data = {
|
|
19
|
+
"msgtype": "text",
|
|
20
|
+
"text": {
|
|
21
|
+
"content": s,
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if i > 3:
|
|
25
|
+
raise Exception(str(traceback.format_exc()))
|
|
26
|
+
try:
|
|
27
|
+
requests.post(url=vx_url, headers=headers, json=data, timeout=30)
|
|
28
|
+
except:
|
|
29
|
+
i = i + 1
|
|
30
|
+
send_vx(vx_key, str(traceback.format_exc()), i)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# 发送文件到企业微信机器人
|
|
34
|
+
# vx_key: string类型,自己的企业微信机器人的key
|
|
35
|
+
# file_path: string类型,文件地址
|
|
36
|
+
def post_file(vx_key, file_path):
|
|
37
|
+
id_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/upload_media?key=' + vx_key + '&type=file'
|
|
38
|
+
wx_url = 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=' + vx_key
|
|
39
|
+
data = {'file': open(file_path, 'rb')}
|
|
40
|
+
response = requests.post(url=id_url, files=data)
|
|
41
|
+
json_res = response.json()
|
|
42
|
+
media_id = json_res['media_id']
|
|
43
|
+
data = {"msgtype": "file",
|
|
44
|
+
"file": {"media_id": media_id}
|
|
45
|
+
}
|
|
46
|
+
try:
|
|
47
|
+
requests.post(url=wx_url, json=data)
|
|
48
|
+
except:
|
|
49
|
+
send_vx(send_vx, str(traceback.format_exc()))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# data: dataframe|string|dict|list|tuple|array
|
|
53
|
+
# file_name: 带后缀的完整文件名
|
|
54
|
+
# file_type: 文件类型,包括csv、excel、txt、json、sql
|
|
55
|
+
def file_to_vx(vx_key, data, file_name):
|
|
56
|
+
file_type = file_name.split('.')[-1]
|
|
57
|
+
if file_type == "xls" or file_type == "xlsx":
|
|
58
|
+
file_type = "excel"
|
|
59
|
+
current_dir = os.getcwd()
|
|
60
|
+
temp_dir = os.path.join(os.getcwd(), "tmp")
|
|
61
|
+
if os.path.exists(temp_dir):
|
|
62
|
+
pass
|
|
63
|
+
else:
|
|
64
|
+
os.makedirs(temp_dir)
|
|
65
|
+
file_path = current_dir + "/" + file_name
|
|
66
|
+
try:
|
|
67
|
+
if isinstance(data, pd.DataFrame) and file_type != "txt":
|
|
68
|
+
if file_type == "db3":
|
|
69
|
+
conn = sqlite3.connect(file_path)
|
|
70
|
+
data.to_sql('base_table', conn, if_exists='replace', index=False)
|
|
71
|
+
post_file(vx_key, file_path)
|
|
72
|
+
else:
|
|
73
|
+
code_str = "data.to_" + file_type + "(file_path,index=False)"
|
|
74
|
+
eval(code_str)
|
|
75
|
+
post_file(vx_key, file_path)
|
|
76
|
+
os.system('rm ' + file_path + '')
|
|
77
|
+
else:
|
|
78
|
+
if isinstance(data, dict):
|
|
79
|
+
data_str = json.dumps(data, ensure_ascii=False)
|
|
80
|
+
elif isinstance(data, list):
|
|
81
|
+
data_str = ""
|
|
82
|
+
for i in data:
|
|
83
|
+
if isinstance(i, dict):
|
|
84
|
+
data_str = data_str + json.dumps(i, ensure_ascii=False) + "\n"
|
|
85
|
+
else:
|
|
86
|
+
data_str = data_str + str(i) + "\n"
|
|
87
|
+
else:
|
|
88
|
+
data_str = str(data)
|
|
89
|
+
print(data_str[:100])
|
|
90
|
+
with open(file_path, 'w', encoding='utf-8') as f:
|
|
91
|
+
f.write(data_str)
|
|
92
|
+
post_file(vx_key, file_path)
|
|
93
|
+
except:
|
|
94
|
+
send_vx(vx_key, str(traceback.format_exc()))
|
|
95
|
+
os.system('rm -r' + temp_dir + '')
|