From 36a99c0f5a222ecb58588c8f06cf8a6f89e1c7cb Mon Sep 17 00:00:00 2001 From: han0 Date: Thu, 23 Feb 2023 14:59:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20tools.helpers=20?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- nc_http/tools/helpers.py | 174 ------------------------------ nc_http/tools/helpers/__init__.py | 7 ++ nc_http/tools/helpers/string.py | 134 +++++++++++++++++++++++ nc_http/tools/helpers/tree.py | 33 ++++++ nc_http/tools/helpers/url.py | 50 +++++++++ 5 files changed, 224 insertions(+), 174 deletions(-) delete mode 100644 nc_http/tools/helpers.py create mode 100644 nc_http/tools/helpers/__init__.py create mode 100644 nc_http/tools/helpers/string.py create mode 100644 nc_http/tools/helpers/tree.py create mode 100644 nc_http/tools/helpers/url.py diff --git a/nc_http/tools/helpers.py b/nc_http/tools/helpers.py deleted file mode 100644 index d16d511..0000000 --- a/nc_http/tools/helpers.py +++ /dev/null @@ -1,174 +0,0 @@ -import random -import re -import string - -from six.moves.urllib import parse as urlparse - -""" -工具函数集 -""" - - -def valid_email(email): - """ - 验证字符串是否为合法电子邮件 - :param email: - :return: - """ - email = str(email) - if len(email) > 7: - pattern = ( - r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@" - r"(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" - ) - if re.match(pattern, email) is not None: - return True - return False - - -LETTERS = 0b001 -DIGITS = 0b010 -PUNCTUATION = 0b100 - - -def random_ascii_string(length, mask=None): - """ - 生成随机 ascii 字符串 - :param length: - :param mask: - :return: - """ - - if mask is None: - mask = LETTERS | DIGITS - - unicode_ascii_characters = '' - if mask & LETTERS: - unicode_ascii_characters += string.ascii_letters - if mask & DIGITS: - unicode_ascii_characters += string.digits - if mask & PUNCTUATION: - unicode_ascii_characters += string.punctuation - - if not unicode_ascii_characters: - return '' - - rnd = random.SystemRandom() - return ''.join([rnd.choice(unicode_ascii_characters) for _ in range(length)]) - - -def url_parse_query(url): - """ - 从 url 提取 query string 字典 - :param url: - :return: - """ - return dict(urlparse.parse_qsl(urlparse.urlparse(url).query, True)) - - -def url_without_query(url): - """ - 移除 url 中 query string - """ - url = urlparse.urlparse(url) - return urlparse.urlunparse((url.scheme, url.netloc, url.path, url.params, '', url.fragment)) - - -def build_url(base, additional_params=None): - """ - url 中增加 query string 参数 - :param base: - :param additional_params: - :return: - """ - url = urlparse.urlparse(base) - query_params = {} - query_params.update(urlparse.parse_qsl(url.query, True)) - if additional_params is not None: - query_params.update(additional_params) - for k, v in additional_params.items(): - if v is None: - query_params.pop(k) - - return urlparse.urlunparse( - (url.scheme, url.netloc, url.path, url.params, urlparse.urlencode(query_params), url.fragment) - ) - - -COUNTRY_ZONE = ('86',) - - -def parse_mobile(mobile_str): - """ - 解析手机号码 - :param mobile_str: - :return: - """ - match = re.findall(r'^(\+({0}))?(\d+)$'.format('|'.join(COUNTRY_ZONE)), mobile_str) - if match: - zone, mobile = match[0][-2:] - if '+' in mobile_str and not zone: - return None - - if not zone: - zone = '86' - - if zone == '86' and re.match(r'^1\d{10}$', mobile) is not None: - return zone, mobile - - return None - - -def list_to_tree(rows, id_key='id', parent_id_key='parent_id', i=0): - """ - list转tree的函数 - :param rows: - :param id_key: - :param parent_id_key: - :param i: - :return: - """ - data = [] - for row in rows: - if row[parent_id_key] == i: - row['children'] = list_to_tree(rows, id_key=id_key, parent_id_key=parent_id_key, i=row[id_key]) - data.append(row) - return data - - -def cut_tree(trees, nodes, id_key='id', parent_id_key='parent_id'): - """ - 根据叶结点整理出包含所有叶节点的最小树结构 - :param trees: - :param nodes: 叶结点 - :param id_key: - :param parent_id_key: - :return: - """ - data = [] - for row in trees: - children = cut_tree(row['children'], nodes, id_key=id_key, parent_id_key=parent_id_key) - if children or row['id'] in nodes: - row['children'] = children - data.append(row) - return data - - -if __name__ == '__main__': - s = valid_email('wslstest@sample.com') - print(s) - - s = random_ascii_string(40) - print(s) - - s = url_parse_query('http://api_w.qiange.so/hz/shorturl_tongji?short_url=BkPMeb') - print(s) - - s = url_without_query('http://api_w.qiange.so/hz/shorturl_tongji?short_url=BkPMeb') - print(s) - - s = build_url('http://www.baidu.com', {'a': 1, 'b': 2}) - print(s) - - s = parse_mobile('+8615888888888') - print(s) diff --git a/nc_http/tools/helpers/__init__.py b/nc_http/tools/helpers/__init__.py new file mode 100644 index 0000000..1f1155e --- /dev/null +++ b/nc_http/tools/helpers/__init__.py @@ -0,0 +1,7 @@ +""" +工具函数集 +""" + +from .string import * +from .tree import * +from .url import * diff --git a/nc_http/tools/helpers/string.py b/nc_http/tools/helpers/string.py new file mode 100644 index 0000000..8a70d70 --- /dev/null +++ b/nc_http/tools/helpers/string.py @@ -0,0 +1,134 @@ +import random +import re +import string + +from six import string_types + +LETTERS = 0b001 +DIGITS = 0b010 +PUNCTUATION = 0b100 + + +def random_ascii_string(length, mask=None): + """ + 生成随机 ascii 字符串 + :param length: + :param mask: + :return: + """ + + if mask is None: + mask = LETTERS | DIGITS + + unicode_ascii_characters = '' + if mask & LETTERS: + unicode_ascii_characters += string.ascii_letters + if mask & DIGITS: + unicode_ascii_characters += string.digits + if mask & PUNCTUATION: + unicode_ascii_characters += string.punctuation + + if not unicode_ascii_characters: + return '' + + rnd = random.SystemRandom() + return ''.join([rnd.choice(unicode_ascii_characters) for _ in range(length)]) + + +def valid_email(email): + """ + 验证字符串是否为合法电子邮件 + :param email: + :return: + """ + email = str(email) + if len(email) > 7: + pattern = ( + r"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@" + r"(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?" + ) + if re.match(pattern, email) is not None: + return True + return False + + +COUNTRY_ZONE = ('86',) + + +def parse_mobile(mobile_str): + """ + 解析手机号码 + :param mobile_str: + :return: + """ + match = re.findall(r'^(\+({0}))?(\d+)$'.format('|'.join(COUNTRY_ZONE)), mobile_str) + if match: + zone, mobile = match[0][-2:] + if '+' in mobile_str and not zone: + return None + + if not zone: + zone = '86' + + if zone == '86' and re.match(r'^1\d{10}$', mobile) is not None: + return zone, mobile + + return None + + +def camelize(uncamelized_str): + """ + 小写下划线转驼峰 + :param uncamelized_str: + :return: + """ + if not uncamelized_str: + return uncamelized_str + result = ''.join(i.capitalize() for i in uncamelized_str.split('_')) + result = ''.join((result[0].lower(), result[1:])) + return result + + +def uncamelize(camelized_str): + """ + 驼峰转小写下划线 + :param camelized_str: + :return: + """ + if not camelized_str: + return camelized_str + lst = [] + for index, char in enumerate(camelized_str): + if char.isupper() and index != 0: + lst.append("_") + lst.append(char) + + return ''.join(lst).lower() + + +def strip_value(data): + """ + 递归处理字符占位符 + :param data: + :return: + """ + if isinstance(data, dict): + for key, value in data.items(): + data[key] = strip_value(value) + elif isinstance(data, list): + for key, value in enumerate(data): + data[key] = strip_value(value) + elif isinstance(data, string_types): + data = data.strip() + + return data + + +if __name__ == '__main__': + s = valid_email('wslstest@sample.com') + print(s) + + s = random_ascii_string(40) + print(s) + s = parse_mobile('+8615888888888') + print(s) diff --git a/nc_http/tools/helpers/tree.py b/nc_http/tools/helpers/tree.py new file mode 100644 index 0000000..139b0e5 --- /dev/null +++ b/nc_http/tools/helpers/tree.py @@ -0,0 +1,33 @@ +def list_to_tree(rows, id_key='id', parent_id_key='parent_id', i=0): + """ + list转tree的函数 + :param rows: + :param id_key: + :param parent_id_key: + :param i: + :return: + """ + data = [] + for row in rows: + if row[parent_id_key] == i: + row['children'] = list_to_tree(rows, id_key=id_key, parent_id_key=parent_id_key, i=row[id_key]) + data.append(row) + return data + + +def cut_tree(trees, nodes, id_key='id', parent_id_key='parent_id'): + """ + 根据叶结点整理出包含所有叶节点的最小树结构 + :param trees: + :param nodes: 叶结点 + :param id_key: + :param parent_id_key: + :return: + """ + data = [] + for row in trees: + children = cut_tree(row['children'], nodes, id_key=id_key, parent_id_key=parent_id_key) + if children or row['id'] in nodes: + row['children'] = children + data.append(row) + return data diff --git a/nc_http/tools/helpers/url.py b/nc_http/tools/helpers/url.py new file mode 100644 index 0000000..b087e54 --- /dev/null +++ b/nc_http/tools/helpers/url.py @@ -0,0 +1,50 @@ +from six.moves.urllib import parse as urlparse + + +def url_parse_query(url): + """ + 从 url 提取 query string 字典 + :param url: + :return: + """ + return dict(urlparse.parse_qsl(urlparse.urlparse(url).query, True)) + + +def url_without_query(url): + """ + 移除 url 中 query string + """ + url = urlparse.urlparse(url) + return urlparse.urlunparse((url.scheme, url.netloc, url.path, url.params, '', url.fragment)) + + +def build_url(base, additional_params=None): + """ + url 中增加 query string 参数 + :param base: + :param additional_params: + :return: + """ + url = urlparse.urlparse(base) + query_params = {} + query_params.update(urlparse.parse_qsl(url.query, True)) + if additional_params is not None: + query_params.update(additional_params) + for k, v in additional_params.items(): + if v is None: + query_params.pop(k) + + return urlparse.urlunparse( + (url.scheme, url.netloc, url.path, url.params, urlparse.urlencode(query_params), url.fragment) + ) + + +if __name__ == '__main__': + s = url_parse_query('http://api_w.qiange.so/hz/shorturl_tongji?short_url=BkPMeb') + print(s) + + s = url_without_query('http://api_w.qiange.so/hz/shorturl_tongji?short_url=BkPMeb') + print(s) + + s = build_url('http://www.baidu.com', {'a': 1, 'b': 2}) + print(s)