ezKit 1.0.0__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.
ezKit/weixin.py ADDED
@@ -0,0 +1,148 @@
1
+ import json
2
+ import time
3
+
4
+ import requests
5
+
6
+
7
+ class WeiXin(object):
8
+
9
+ '''
10
+ 企业微信开发者中心
11
+
12
+ https://developer.work.weixin.qq.com/
13
+ https://developer.work.weixin.qq.com/document/path/90313 (全局错误码)
14
+
15
+ 参考文档:
16
+
17
+ https://www.gaoyuanqi.cn/python-yingyong-qiyewx/
18
+ https://www.jianshu.com/p/020709b130d3
19
+ '''
20
+
21
+ _work_id, _agent_id, _agent_secret, _access_token = None, None, None, None
22
+
23
+ def __init__(self, work_id, agent_id, agent_secret):
24
+ ''' Initiation '''
25
+ self._work_id = work_id
26
+ self._agent_id = agent_id
27
+ self._agent_secret = agent_secret
28
+
29
+ ''' 获取 Token '''
30
+ self.get_access_token()
31
+
32
+ def get_access_token(self):
33
+ _response = requests.get(f'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={self._work_id}&corpsecret={self._agent_secret}')
34
+ if _response.status_code == 200:
35
+ _result = _response.json()
36
+ self._access_token = _result.get('access_token')
37
+ else:
38
+ self._access_token = None
39
+
40
+ def get_agent_list(self):
41
+
42
+ self.get_access_token() if self._access_token == None else next
43
+
44
+ _response = requests.get(f'https://qyapi.weixin.qq.com/cgi-bin/agent/list?access_token={self._access_token}')
45
+
46
+ if _response.status_code == 200:
47
+ _response_data = _response.json()
48
+ if _response_data.get('errcode') == 42001:
49
+ self.get_access_token()
50
+ time.sleep(1)
51
+ self.get_agent_list()
52
+ return _response_data
53
+ return {'response': _response.text}
54
+
55
+ def get_department_list(self, id):
56
+
57
+ self.get_access_token() if self._access_token == None else next
58
+
59
+ _response = requests.get(f'https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={self._access_token}&id={id}')
60
+
61
+ if _response.status_code == 200:
62
+ _response_data = _response.json()
63
+ if _response_data.get('errcode') == 42001:
64
+ self.get_access_token()
65
+ time.sleep(1)
66
+ self.get_department_list(id)
67
+ return _response_data
68
+ return {'response': _response.text}
69
+
70
+ def get_user_list(self, id):
71
+
72
+ self.get_access_token() if self._access_token == None else next
73
+
74
+ _response = requests.get(f'https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={self._access_token}&department_id={id}')
75
+
76
+ if _response.status_code == 200:
77
+ _response_data = _response.json()
78
+ if _response_data.get('errcode') == 42001:
79
+ self.get_access_token()
80
+ time.sleep(1)
81
+ self.get_user_list(id)
82
+ return _response_data
83
+ return {'response': _response.text}
84
+
85
+ def get_user_id_by_mobile(self, mobile):
86
+
87
+ self.get_access_token() if self._access_token == None else next
88
+
89
+ _json_dict = {'mobile': mobile}
90
+
91
+ _json_string = json.dumps(_json_dict)
92
+
93
+ _response = requests.post(f'https://qyapi.weixin.qq.com/cgi-bin/user/getuserid?access_token={self._access_token}', data=_json_string)
94
+
95
+ if _response.status_code == 200:
96
+ _response_data = _response.json()
97
+ if _response_data.get('errcode') == 42001:
98
+ self.get_access_token()
99
+ time.sleep(1)
100
+ self.get_user_id_by_mobile(id)
101
+ return _response_data
102
+ return {'response': _response.text}
103
+
104
+ def get_user_info(self, id):
105
+
106
+ self.get_access_token() if self._access_token == None else next
107
+
108
+ _response = requests.get(f'https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={self._access_token}&userid={id}')
109
+
110
+ if _response.status_code == 200:
111
+ _response_data = _response.json()
112
+ if _response_data.get('errcode') == 42001:
113
+ self.get_access_token()
114
+ time.sleep(1)
115
+ self.get_user_info(id)
116
+ return _response_data
117
+ return {'response': _response.text}
118
+
119
+ def send_text(self, users, message):
120
+ '''
121
+ https://developer.work.weixin.qq.com/document/path/90235
122
+ '''
123
+
124
+ self.get_access_token() if self._access_token == None else next
125
+
126
+ _json_dict = {
127
+ 'touser': users,
128
+ 'msgtype': 'text',
129
+ 'agentid': self._agent_id,
130
+ 'text': {'content': message},
131
+ 'safe': 0,
132
+ 'enable_id_trans': 0,
133
+ 'enable_duplicate_check': 0,
134
+ 'duplicate_check_interval': 1800
135
+ }
136
+
137
+ _json_string = json.dumps(_json_dict)
138
+
139
+ _response = requests.post(f'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token={self._access_token}', data=_json_string)
140
+
141
+ if _response.status_code == 200:
142
+ _response_data = _response.json()
143
+ if _response_data.get('errcode') == 42001:
144
+ self.get_access_token()
145
+ time.sleep(1)
146
+ self.send_text(users, message)
147
+ return _response_data
148
+ return {'response': _response.text}
ezKit/xftp.py ADDED
@@ -0,0 +1,194 @@
1
+ '''
2
+ ftplib: https://docs.python.org/3.10/library/ftplib.html
3
+ '''
4
+ import os
5
+ from ftplib import FTP
6
+ from pathlib import Path
7
+
8
+
9
+ class XFTP:
10
+
11
+ def __init__(self, host='127.0.0.1', port=21, username='anonymous', password='', encoding='UTF-8', debuglevel=0):
12
+ ''' Initiation '''
13
+ self.ftp = FTP()
14
+ self.ftp.set_debuglevel(debuglevel)
15
+ self.host = host
16
+ self.port = port
17
+ self.username = username
18
+ self.password = password
19
+ self.encoding = encoding
20
+ self.retry = 1
21
+
22
+ def connect(self):
23
+ ''' FTP connect '''
24
+ try:
25
+ self.ftp.connect(host=self.host, port=self.port, timeout=10)
26
+ self.ftp.encoding = self.encoding
27
+ self.ftp.login(user=self.username, passwd=self.password)
28
+ print('FTP connect success')
29
+ print('-' * 80)
30
+ return True
31
+ except Exception as e:
32
+ print(f'FTP connect error: {e}, retry...')
33
+ if self.retry >= 3:
34
+ print('FTP connect faild')
35
+ return False
36
+ self.retry += 1
37
+ self.connect()
38
+
39
+ def close(self, info=None):
40
+ ''' FTP close '''
41
+ print(info) if info else None
42
+ try:
43
+ self.ftp.quit()
44
+ except:
45
+ self.ftp.close()
46
+ print('-' * 80)
47
+ print('FTP connect closed')
48
+
49
+ def get_file_list(self, dir='/'):
50
+ ''' Get file list '''
51
+ self.chdir_to_remote(dir)
52
+ return self.ftp.nlst()
53
+
54
+ def get_file_size(self, dir='/', file=None):
55
+ ''' Get file size '''
56
+ self.chdir_to_remote(dir)
57
+ return self.ftp.size(file)
58
+
59
+ def mkdir(self, dir_string='/'):
60
+ ''' 创建目录 (从 / 目录依次递增创建子目录. 如果目录存在, 创建目录时会报错, 所以这里忽略所有错误.) '''
61
+ try:
62
+ dir_list = dir_string.split("/")
63
+ for i, _ in enumerate(dir_list):
64
+ dir = '/'.join(dir_list[:i + 1])
65
+ try:
66
+ self.ftp.mkd(dir)
67
+ except:
68
+ pass
69
+ return True
70
+ except:
71
+ return False
72
+
73
+ def chdir_to_remote(self, dir='/'):
74
+ ''' change to remote directory'''
75
+ try:
76
+ self.ftp.cwd(dir)
77
+ except:
78
+ self.close(f'Remote directory error: {dir}')
79
+
80
+ def x_exit(self, info=None):
81
+ ''' Exit '''
82
+ print(info) if info else None
83
+ # 注意: exit() 并不会退出脚本, 配合 try 使用
84
+ exit()
85
+
86
+ def x_exec(self, local_dir='.', local_file='', remote_dir='/', remote_file='', upload=False):
87
+ ''' Download or Upload '''
88
+
89
+ bufsize = 1024
90
+ local_path = local_dir + '/' + local_file
91
+ remote_path = remote_dir + '/' + remote_file
92
+ info = 'Upload' if upload else 'Download'
93
+
94
+ # 检查参数
95
+ if upload:
96
+ if local_file == '':
97
+ self.close('Argument Miss: local file')
98
+ # 如果没有设置 远程文件 名称, 则使用 本地文件 名称
99
+ if remote_file == '':
100
+ remote_file = local_file
101
+ remote_path = remote_dir + '/' + remote_file
102
+ else:
103
+ if remote_file == '':
104
+ self.close('Argument Miss: remote file')
105
+ # 如果没有设置 本地文件 名称, 则使用 远程文件 名称
106
+ if local_file == '':
107
+ local_file = remote_file
108
+ local_path = local_dir + '/' + local_file
109
+
110
+ # 进入本地目录
111
+ try:
112
+ if upload:
113
+ # 检查本地目录
114
+ stat = Path(local_dir)
115
+ self.close(f'Local directory error: {local_dir}') if stat.exists() == False else None
116
+ else:
117
+ # 创建本地目录
118
+ Path(local_dir).mkdir(parents=True, exist_ok=True)
119
+ # 进入本地目录
120
+ os.chdir(local_dir)
121
+ except:
122
+ # 第一层 try 使用 self.x_exit() 无效, 直接使用 self.close()
123
+ self.close(f'Local directory error: {local_dir}')
124
+
125
+ # 上传或下载
126
+ try:
127
+
128
+ if upload:
129
+
130
+ ''' 上传 '''
131
+
132
+ # 创建远程目录
133
+ if remote_dir != '/':
134
+ self.mkdir(remote_dir)
135
+
136
+ # 进入远程目录
137
+ self.chdir_to_remote(remote_dir)
138
+
139
+ # 上传文件
140
+ stat = Path(local_file)
141
+ if stat.exists() and stat.is_file():
142
+ with open(local_file, 'rb') as fid:
143
+ self.ftp.storbinary(f'STOR {remote_file}', fid, bufsize)
144
+ print('{} success: {} -> {}'.format(info, local_path.replace('//', '/'), remote_path.replace('//', '/')))
145
+ return True
146
+ else:
147
+ self.x_exit('{} error: {} is not exist'.format(info, local_path.replace('//', '/')))
148
+
149
+ else:
150
+
151
+ ''' 下载 '''
152
+
153
+ # 进入远程目录
154
+ self.chdir_to_remote(remote_dir)
155
+
156
+ # 下载文件
157
+ if remote_file in self.ftp.nlst():
158
+ with open(local_file, 'wb') as fid:
159
+ self.ftp.retrbinary(f'RETR {remote_file}', fid.write, bufsize)
160
+ print('{} success: {} -> {}'.format(info, remote_path.replace('//', '/'), local_path.replace('//', '/')))
161
+ return True
162
+ else:
163
+ self.x_exit('{} error: {} is not exist'.format(info, remote_path.replace('//', '/')))
164
+
165
+ except Exception as e:
166
+ # 第一层 try 使用 self.x_exit() 无效, 直接使用 self.close()
167
+ # self.close('{} faild! Please check {} or {}'.format(info, local_path, remote_path))
168
+ self.close(f'{info} error: {e}')
169
+ return False
170
+
171
+ def handle_all(self, local_dir='.', remote_dir='/', upload=False):
172
+ ''' Handle All '''
173
+ if upload:
174
+ # 检查本地目录
175
+ stat = Path(local_dir)
176
+ self.close(f'Local directory error: {local_dir}') if stat.exists() == False else None
177
+ # 获取文件列表
178
+ local_files = [f for f in os.listdir(local_dir) if os.path.isfile(os.path.join(local_dir, f))]
179
+ for i in local_files:
180
+ self.x_exec(local_dir=local_dir, remote_dir=remote_dir, local_file=i, upload=True)
181
+ else:
182
+ remote_files = self.get_file_list(remote_dir)
183
+ for i in remote_files:
184
+ self.x_exec(local_dir=local_dir, remote_dir=remote_dir, remote_file=i)
185
+
186
+ def retrlines(self, remote_dir='/', cmd='LIST'):
187
+ ''' Retrlines '''
188
+ try:
189
+ self.chdir_to_remote(remote_dir)
190
+ print(self.ftp.retrlines(cmd))
191
+ self.close()
192
+ except Exception as e:
193
+ # 第一层 try 使用 self.x_exit() 无效, 直接使用 self.close()
194
+ self.close(e)