pixelarraylib 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.
@@ -0,0 +1,390 @@
1
+ import asyncio
2
+ import json
3
+ import re
4
+ import subprocess
5
+ import traceback
6
+ from typing import Union, List, Generator
7
+ from cryptography.fernet import Fernet
8
+ import base64
9
+ from arraylib.monitor.feishu import Feishu
10
+ import os
11
+ import paramiko
12
+
13
+ feishu_alert = Feishu("devtoolkit服务报警")
14
+
15
+
16
+ async def execute_batch_async_tasks(tasks, semaphore_count=None):
17
+ if semaphore_count is None:
18
+ return await asyncio.gather(*tasks)
19
+
20
+ semaphore = asyncio.Semaphore(semaphore_count)
21
+
22
+ async def sem_task(task):
23
+ async with semaphore:
24
+ return await task
25
+
26
+ return await asyncio.gather(*(sem_task(task) for task in tasks))
27
+
28
+
29
+ def encode_chinese_string(text: str) -> str:
30
+ """
31
+ description:
32
+ 将中文转换为UTF-8编码的字符串
33
+ parameters:
34
+ text(str): 需要转换的字符串
35
+ return:
36
+ converted_text(str): 转换后的字符串(URL安全的base64格式)
37
+ """
38
+ # 使用URL安全的base64编码方法
39
+ return base64.urlsafe_b64encode(text.encode("utf-8")).decode("ascii").rstrip("=")
40
+
41
+
42
+ def decode_chinese_string(encoded_text: str) -> str:
43
+ """
44
+ description:
45
+ 将UTF-8编码的字符串转换为中文
46
+ parameters:
47
+ encoded_text(str): 编码后的字符串(URL安全的base64格式)
48
+ return:
49
+ text(str): 原始中文字符串
50
+ """
51
+ # 添加回可能被移除的填充字符'='
52
+ padding = 4 - (len(encoded_text) % 4)
53
+ encoded_text += "=" * padding
54
+ # 使用URL安全的base64解码方法
55
+ return base64.urlsafe_b64decode(encoded_text.encode("ascii")).decode("utf-8")
56
+
57
+
58
+ def generate_fernet_key() -> bytes:
59
+ """
60
+ description:
61
+ 生成Fernet加密密钥
62
+ return:
63
+ key(str): 加密密钥
64
+ """
65
+ return Fernet.generate_key().decode()
66
+
67
+
68
+ def encrypt_string(text: str, key: str) -> tuple[str, bytes]:
69
+ """
70
+ description:
71
+ 使用Fernet对称加密算法加密字符串
72
+ parameters:
73
+ text(str): 需要加密的字符串
74
+ key(str): 加密密钥
75
+ return:
76
+ str: 加密后的字符串
77
+ """
78
+ f = Fernet(key.encode())
79
+ encrypted_data = f.encrypt(text.encode())
80
+ return encrypted_data.decode()
81
+
82
+
83
+ def decrypt_string(encrypted_text: str, key: str) -> str:
84
+ """
85
+ description:
86
+ 解密使用Fernet加密的字符串
87
+ parameters:
88
+ encrypted_text(str): 加密后的字符串
89
+ key(str): 加密密钥
90
+ return:
91
+ str: 解密后的原始字符串
92
+ """
93
+ f = Fernet(key.encode())
94
+ decrypted_data = f.decrypt(encrypted_text.encode())
95
+ return decrypted_data.decode()
96
+
97
+
98
+ def decimal(num: float, precision=2):
99
+ """
100
+ 保留小数点后precision位
101
+ parameters:
102
+ num: float, 需要保留小数点的数字
103
+ precision: int, 保留小数点的位数
104
+ return:
105
+ num(float): 保留小数点后的数字
106
+ """
107
+ num_s = f"{num:.{precision}f}"
108
+ return float(num_s)
109
+
110
+
111
+ def percentage(current, target):
112
+ """
113
+ 计算当前值占总值的百分比
114
+ parameters:
115
+ current: float, 当前值
116
+ target: float, 总值
117
+ return:
118
+ percentage_str(str): 百分比字符串
119
+ """
120
+ percentage = decimal((current / target) * 100)
121
+ percentage_str = f"{percentage}%"
122
+ return percentage_str
123
+
124
+
125
+ def size_unit_convert(size, input_unit="B", output_unit="MB", precision=2):
126
+ """
127
+ 单位转换
128
+ parameters:
129
+ size: float, 需要转换的文件大小
130
+ input_unit: str, 输入的单位,默认B
131
+ output_unit: str, 输出的单位,默认MB
132
+ precision: int, 保留小数点的位数,默认2
133
+ return:
134
+ size(float): 转换后的文件大小
135
+ """
136
+ size_unit_list = ["B", "KB", "MB", "GB", "TB"]
137
+ if input_unit not in size_unit_list or output_unit not in size_unit_list:
138
+ return size
139
+ pos_input_unit = size_unit_list.index(input_unit)
140
+ pos_output_unit = size_unit_list.index(output_unit)
141
+ if pos_input_unit == pos_output_unit:
142
+ return size
143
+
144
+ mult_num = (
145
+ 1 / (1024 ** (pos_output_unit - pos_input_unit))
146
+ if pos_input_unit < pos_output_unit
147
+ else 1024 ** (pos_input_unit - pos_output_unit)
148
+ )
149
+ return decimal(size * mult_num, precision)
150
+
151
+
152
+ def split_content_into_sentences(
153
+ content: str, remove_punctuation: bool = True
154
+ ) -> tuple[list[str], bool]:
155
+ """
156
+ description:
157
+ 将内容按逗号和顿号分割成句子
158
+ parameters:
159
+ content(str): 需要分割的内容
160
+ return:
161
+ sentences(list[str]): 分割后的句子列表
162
+ flag(bool): 是否分割成功
163
+ """
164
+ try:
165
+ split_pattern = r"[。!?;,、:]"
166
+ content = content.strip()
167
+ sentences = re.split(split_pattern, content)
168
+ sentences = [s.strip() for s in sentences if s.strip()]
169
+
170
+ # 对每一句话循环去除所有的空格
171
+ sentences = [
172
+ sentence.replace(" ", "")
173
+ for sentence in sentences
174
+ if sentence and sentence.strip() and sentence.strip() != ""
175
+ ]
176
+
177
+ if remove_punctuation:
178
+ sentences = [re.sub(r"[^\w\s]", "", s) for s in sentences]
179
+ return sentences, True
180
+ except Exception as e:
181
+ feishu_alert.send(f"分割内容时发生错误: {traceback.format_exc()}")
182
+ return [], False
183
+
184
+
185
+ def remove_all_punctuation(text: str) -> tuple[str, bool]:
186
+ """
187
+ description:
188
+ 去除字符串中的所有标点符号
189
+ parameters:
190
+ text(str): 需要处理的字符串
191
+ return:
192
+ text(str): 处理后的字符串
193
+ flag(bool): 是否处理成功
194
+ """
195
+ try:
196
+ # 使用正则表达式去除所有标点符号
197
+ return re.sub(r"[^\w\s]", "", text), True
198
+ except Exception as e:
199
+ feishu_alert.send(f"去除标点符号时发生错误: {traceback.format_exc()}")
200
+ return text, False
201
+
202
+
203
+ def file_to_base64(file_path: str) -> str:
204
+ """
205
+ description:
206
+ 将文件转换为base64
207
+ parameters:
208
+ file_path(str): 文件路径
209
+ return:
210
+ base64_str(str): base64字符串
211
+ """
212
+ with open(file_path, "rb") as file:
213
+ return base64.b64encode(file.read()).decode("utf-8")
214
+
215
+
216
+ def execute_command(command: Union[str, List[str]]) -> str:
217
+ """
218
+ description:
219
+ 执行命令
220
+ parameters:
221
+ cmd(list[str]): 需要执行的命令
222
+ return:
223
+ result(str): 命令执行结果
224
+ """
225
+ try:
226
+ if isinstance(command, str):
227
+ command = command.split()
228
+ print(command)
229
+ result = subprocess.run(
230
+ command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
231
+ )
232
+ return result.stdout.decode(), True
233
+ except subprocess.CalledProcessError as e:
234
+ feishu_alert.send(
235
+ f"执行命令失败,命令: {command},错误信息: {e.stderr.decode() if e.stderr else str(e)}"
236
+ )
237
+ return None, False
238
+
239
+
240
+ async def execute_command_async(command: Union[str, List[str]]) -> str:
241
+ """
242
+ description:
243
+ 异步执行命令
244
+ parameters:
245
+ command(list[str]): 需要执行的命令
246
+ return:
247
+ result(str): 命令执行结果
248
+ """
249
+ try:
250
+ if isinstance(command, str):
251
+ command = command.split()
252
+ print(command)
253
+ result = await asyncio.create_subprocess_exec(
254
+ *command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
255
+ )
256
+ stdout, stderr = await result.communicate()
257
+ return stdout.decode(), True
258
+ except subprocess.CalledProcessError as e:
259
+ feishu_alert.send(
260
+ f"异步执行命令失败,命令: {command},错误信息: {e.stderr.decode() if e.stderr else str(e)}"
261
+ )
262
+ return None, False
263
+
264
+
265
+ def get_variable_type(variable: object) -> str:
266
+ """
267
+ description:
268
+ 获取变量类型
269
+ parameters:
270
+ variable(object): 需要获取类型的变量
271
+ return:
272
+ variable_type(str): 变量类型
273
+ """
274
+ return type(variable).__name__
275
+
276
+
277
+ def extract_json_from_markdown(content: str) -> dict:
278
+ """
279
+ description:
280
+ 从Markdown文本中提取JSON内容
281
+ parameters:
282
+ content(str): Markdown文本
283
+ return:
284
+ json_content(dict): JSON内容
285
+ """
286
+ # 首先尝试匹配 ```json 格式
287
+ json_match = re.search(r"```json\n(.*?)\n```", content, re.DOTALL)
288
+ if json_match:
289
+ return json.loads(json_match.group(1))
290
+
291
+ # 如果没有找到 ```json 格式,尝试直接匹配 JSON 对象
292
+ json_match = re.search(r"({[\s\S]*})", content)
293
+ if json_match:
294
+ return json.loads(json_match.group(1))
295
+
296
+ # 如果还是没有找到,尝试直接解析整个内容
297
+ try:
298
+ return json.loads(content)
299
+ except:
300
+ return {}
301
+
302
+
303
+ def get_ssh_config():
304
+ """
305
+ descrption:
306
+ 获取~/.ssh/config中的配置信息
307
+ return:
308
+ configs(list): 配置信息 [{"host": "", "hostname": "", "user": "", "identityfile": ""}, ...]
309
+ """
310
+ ssh_config_file = os.path.expanduser("~/.ssh/config")
311
+ configs = []
312
+ current_config = {}
313
+
314
+ with open(ssh_config_file, "r") as f:
315
+ for line in f.readlines():
316
+ line = line.strip()
317
+ if not line:
318
+ continue
319
+
320
+ if line.startswith("Host "):
321
+ if current_config:
322
+ configs.append(current_config)
323
+ current_config = {}
324
+ current_config["host"] = line.split()[1]
325
+ elif line.startswith("HostName "):
326
+ current_config["hostname"] = line.split()[1]
327
+ elif line.startswith("User "):
328
+ current_config["user"] = line.split()[1]
329
+ elif line.startswith("IdentityFile "):
330
+ current_config["identityfile"] = os.path.expanduser(line.split()[1])
331
+
332
+ if current_config:
333
+ configs.append(current_config)
334
+
335
+ return configs
336
+
337
+
338
+ def execute_command_through_ssh_stream(
339
+ hostname: str, command: str
340
+ ) -> Generator[str, None, None]:
341
+ """
342
+ descrption:
343
+ SSH到线上机器并执行命令
344
+ parameters:
345
+ hostname(str): 线上机器的IP地址
346
+ command(str): 要执行的命令
347
+ return:
348
+ output(generator): 命令的输出生成器
349
+ """
350
+ ssh_config = next(
351
+ (config for config in get_ssh_config() if config.get("hostname") == hostname),
352
+ None,
353
+ )
354
+ if not ssh_config:
355
+ raise Exception("SSH 配置获取失败")
356
+
357
+ ssh = paramiko.SSHClient()
358
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
359
+ ssh.connect(
360
+ ssh_config["hostname"],
361
+ username=ssh_config["user"],
362
+ key_filename=ssh_config["identityfile"],
363
+ )
364
+ try:
365
+ stdin, stdout, stderr = ssh.exec_command(command, get_pty=True)
366
+ stdout.channel.settimeout(None)
367
+
368
+ while line := stdout.readline():
369
+ yield line.strip() + "\n"
370
+
371
+ if stderr.readline():
372
+ raise Exception(f"在host: {hostname}上执行命令{command}失败")
373
+ finally:
374
+ ssh.close()
375
+
376
+
377
+ def execute_command_through_ssh(hostname: str, command: str) -> str:
378
+ """
379
+ descrption:
380
+ SSH到线上机器并执行命令
381
+ parameters:
382
+ hostname(str): 线上机器的IP地址
383
+ command(str): 要执行的命令
384
+ return:
385
+ output(str): 命令的输出
386
+ """
387
+ result = ""
388
+ for line in execute_command_through_ssh_stream(hostname, command):
389
+ result += line
390
+ return result
@@ -0,0 +1,141 @@
1
+ Metadata-Version: 2.4
2
+ Name: pixelarraylib
3
+ Version: 1.0.0
4
+ Summary: PixelArray Python开发工具库 - 包含阿里云服务、数据库工具、装饰器、监控等功能
5
+ Author-email: Lu qi <qi.lu@pixelarrayai.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://gitlab.com/pixelarrayai/general_pythondevutils_lib
8
+ Project-URL: Bug Reports, https://gitlab.com/pixelarrayai/general_pythondevutils_lib/-/issues
9
+ Project-URL: Source, https://gitlab.com/pixelarrayai/general_pythondevutils_lib
10
+ Keywords: python,utils,aliyun,database,tools,pixelarray
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Topic :: Utilities
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: alibabacloud_tea_util
25
+ Requires-Dist: alibabacloud_cms20190101
26
+ Requires-Dist: alibabacloud_green20220302
27
+ Requires-Dist: alibabacloud_dm20151123
28
+ Requires-Dist: alibabacloud_fc20230330
29
+ Requires-Dist: alibabacloud_darabonba_stream
30
+ Requires-Dist: alibabacloud_dysmsapi20170525
31
+ Requires-Dist: alibabacloud_sts20150401
32
+ Requires-Dist: alibabacloud_alidns20150109
33
+ Requires-Dist: alibabacloud_eci20180808
34
+ Requires-Dist: alibabacloud_bssopenapi20171214
35
+ Requires-Dist: oss2
36
+ Requires-Dist: pymysql
37
+ Requires-Dist: aiomysql
38
+ Requires-Dist: redis
39
+ Requires-Dist: redis[async]
40
+ Requires-Dist: requests
41
+ Requires-Dist: aiohttp
42
+ Requires-Dist: asyncio
43
+ Requires-Dist: setuptools
44
+ Requires-Dist: cffi
45
+ Requires-Dist: cryptography
46
+ Requires-Dist: pandas
47
+ Requires-Dist: paramiko
48
+ Dynamic: license-file
49
+
50
+ # PixelArrayLib - PixelArray Python开发工具库
51
+
52
+ PixelArrayLib是一个功能丰富的Python开发工具库,包含阿里云服务、数据库工具、装饰器、监控等功能,同时提供便捷的命令行工具。
53
+
54
+ ## 安装
55
+
56
+ ```bash
57
+ pip install pixelarraylib
58
+ ```
59
+
60
+ ## 使用方法
61
+
62
+ ### 1. Python程序中使用
63
+
64
+ ```python
65
+ # 导入pixelarraylib模块
66
+ import arraylib
67
+
68
+ # 使用各种功能模块
69
+ from arraylib.aliyun import some_service
70
+ from arraylib.db_utils import database_tools
71
+ from arraylib.decorators import useful_decorators
72
+ ```
73
+
74
+ ### 2. 命令行工具使用
75
+
76
+ 安装后,你可以在命令行中直接使用 `pixelarraylib` 命令:
77
+
78
+ #### 创建测试用例文件
79
+ ```bash
80
+ # 一键创建所有测试用例文件
81
+ pixelarraylib create_test_case_files
82
+ ```
83
+
84
+ #### 代码提交统计
85
+ ```bash
86
+ # 统计最近30天的代码提交
87
+ pixelarraylib summary_code_count
88
+
89
+ # 统计指定日期范围的提交
90
+ pixelarraylib summary_code_count --since="2025-05-09"
91
+
92
+ # 统计特定作者的提交
93
+ pixelarraylib summary_code_count --author="张三"
94
+
95
+ # 输出到CSV文件
96
+ pixelarraylib summary_code_count --output=stats.csv
97
+
98
+ # 只统计特定文件类型
99
+ pixelarraylib summary_code_count --file-types="py,js,vue"
100
+
101
+ # 查看帮助信息
102
+ pixelarraylib summary_code_count --help
103
+ ```
104
+
105
+ ## 功能特性
106
+
107
+ - **阿里云服务集成**: 包含CMS、Green、DM、FC、SMS、STS等服务
108
+ - **数据库工具**: MySQL、Redis等数据库操作工具
109
+ - **Web框架**: FastAPI集成
110
+ - **实用工具**: 二维码生成、加密解密、XML处理等
111
+ - **命令行工具**: 测试用例生成、代码统计等实用脚本
112
+
113
+ ## 开发
114
+
115
+ ### 本地开发安装
116
+
117
+ ```bash
118
+ # 克隆仓库
119
+ git clone https://gitlab.com/pixelarrayai/general_pythondevutils_lib.git
120
+ cd general_pythondevutils_lib
121
+
122
+ # 安装开发依赖
123
+ pip install -e .
124
+
125
+ # 测试命令行工具
126
+ pixelarraylib --help
127
+ ```
128
+
129
+ ### 添加新的命令行工具
130
+
131
+ 1. 在 `arraylib/scripts/` 目录下创建新的脚本文件
132
+ 2. 在 `arraylib/__main__.py` 中添加新的命令选项
133
+ 3. 更新 `arraylib/scripts/__init__.py` 导出新功能
134
+
135
+ ## 许可证
136
+
137
+ MIT License
138
+
139
+ ## 作者
140
+
141
+ Lu qi (qi.lu@pixelarrayai.com)
@@ -0,0 +1,37 @@
1
+ arraylib/__init__.py,sha256=SH1Y-v6CQYC8kLfivhghAUstP4tM880SeZVxh7SBZkQ,847
2
+ arraylib/__main__.py,sha256=FF3vdP_eCfw-jDpJFWvzLXTitv4Gn96x-yEtpwiB0vw,5000
3
+ arraylib/aliyun/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ arraylib/aliyun/aliyun_email.py,sha256=8lnkPryVlTLV8DOkcmi6bE100hFe-vu2Navxlpul_u8,4949
5
+ arraylib/aliyun/billing.py,sha256=v46OBzmqDubHLxvkHwMPjX-ZFdk2Z6ze-lfxzb0uJgE,21509
6
+ arraylib/aliyun/content_scanner.py,sha256=q7MXlKeDgf6jHJKyQwF4SCdMYcznL76ZVb0Kw9clwEc,9370
7
+ arraylib/aliyun/domain.py,sha256=pspT2f5hdT_wbyqiHmYJeXsKioO9gR7DGcVQ8oWEkEc,13815
8
+ arraylib/aliyun/eci.py,sha256=jJrc3sBt0R_YbwoyIt-oUOKfk4Txxa8rYzMYqa8vXEQ,1538
9
+ arraylib/aliyun/ecs.py,sha256=jaj_IEGJMlDHeKOtGh4jRmiCbYlbqXdUmCzJ30KxZXc,2874
10
+ arraylib/aliyun/fc.py,sha256=FKP80G1D_RJDua1Y12_MHaiLhrLgi92naK7dmx-kjBo,5946
11
+ arraylib/aliyun/oss.py,sha256=x48u5586oP6UiWNiKdTBraiTek2kfIxaV2ejzya9zLc,22257
12
+ arraylib/aliyun/sms.py,sha256=JrB-JS6RC29jJpv6ar3Inmd1AAg2lcFXRBjoqDzJdRQ,2225
13
+ arraylib/aliyun/sts.py,sha256=vjAxQs2kNU6aMgAbp6TpWz-PekB0IYxtNFSMQOlphC4,4517
14
+ arraylib/db_utils/mysql.py,sha256=5VUY07O3EC4CNeQJOr3eH9whxi5roSjNY_Wsn1V7tOU,17889
15
+ arraylib/db_utils/redis.py,sha256=LKbsa9JmyGVjA99xCx90zTLnMcm4JxXsiZhlJ610ynQ,11118
16
+ arraylib/decorators/__init__.py,sha256=9H_w5GkRg38zF1nGJ904Kh6AIACU3yZbBW7cporOMjo,236
17
+ arraylib/decorators/decorators.py,sha256=vzvwn-1YEiyYo6aS05yva5VQvCLEGnCBQcmMClZwDpc,6551
18
+ arraylib/gitlab/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ arraylib/gitlab/code_analyzer.py,sha256=sRwe43ozGPqwfXhjl_5fQxXuf6e_63NPF5pEZNo1PmY,12431
20
+ arraylib/gitlab/pypi_package_manager.py,sha256=c-fRS-Nz6z9XtmjpNizDbp8ZygRRbNfWVZav_j0RHo8,2377
21
+ arraylib/monitor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ arraylib/monitor/feishu.py,sha256=BKOfqRO_pPwXx6NFBboqAs1N3mPd3KsPSBVfS1FcJ2c,4851
23
+ arraylib/net/request.py,sha256=NT-tl-2cEFF6hO5fejbTphl3P7P7JWxsXLt-GMYjgaU,4034
24
+ arraylib/scripts/__init__.py,sha256=O_Y8hCOrS5Y-c0zKN9pijtLDOyMW6tLqaK884eocJZI,689
25
+ arraylib/scripts/collect_code_to_txt.py,sha256=sMGh5Ccp-Gu9g8SbaUWqWmd2EF3_drUcKtcbn3fLVxI,12149
26
+ arraylib/scripts/create_test_case_files.py,sha256=HpOM2-OePXkU7TEQfK64K7CPnOtkWjTmIYykkIzp3DA,2807
27
+ arraylib/scripts/nginx_proxy_to_ecs.py,sha256=Ao6-gI4YTndclX2RAje1FOmKBvCu6-cLkwWHgzdozkY,3708
28
+ arraylib/scripts/remove_empty_lines.py,sha256=PyVt-6ZPWWPpZ3Cmjv90UgTWZhIxRbcLVC3i5EaiqIE,3519
29
+ arraylib/scripts/summary_code_count.py,sha256=cWstdJveYSNQed8cvvIxS4cO-wnlfgPxNgQ5jyiCUZA,15345
30
+ arraylib/system/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
+ arraylib/system/common.py,sha256=fZSfdiZhK1aAxLxVhGPlkryiqZvG1lE7-Gca4XO3FAg,11414
32
+ pixelarraylib-1.0.0.dist-info/licenses/LICENSE,sha256=O-g1dUr0U50rSIvmWE9toiVkSgFpVt72_MHITbWvAqA,1067
33
+ pixelarraylib-1.0.0.dist-info/METADATA,sha256=sbRq3-UOmCDox85b4S1R26defSp8JM4zH-E7gf3iCJ0,4042
34
+ pixelarraylib-1.0.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
35
+ pixelarraylib-1.0.0.dist-info/entry_points.txt,sha256=GMCuPtjh_ngMrwkmltYvQL8nzpp4HXXe7HEYvp03WVc,57
36
+ pixelarraylib-1.0.0.dist-info/top_level.txt,sha256=DCfj9KgMHJXrggUf8kdR2JJOS1RzEIbKt4_JaccrZ58,9
37
+ pixelarraylib-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.9.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ pixelarraylib = arraylib.__main__:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 PixelArray
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ arraylib