Compare commits

..

10 Commits

Author SHA1 Message Date
han0
d1881c5ff7 feat(core.document): 更新api文档模版 2023-04-26 08:22:28 +08:00
han0
5a552f02ea fix: 修复无法正确获取文件后缀名的问题 2023-03-22 10:15:29 +08:00
han0
edd6ea8dc7 feat(core.file): 新增 move_file 2023-03-22 10:01:07 +08:00
han0
a8854edd92 feat(core.file): 新增 save_file 函数 2023-03-22 09:13:22 +08:00
han0
6f004e73fd feat: 新增 core.search.es 2023-03-17 15:06:17 +08:00
han0
3deb269adc feat: 新增 search 2023-02-23 16:19:53 +08:00
han0
7ac1560c15 feat: 新增 file/params 2023-02-23 15:26:38 +08:00
han0
42430ea111 feat: 新增 get_time/get_file 2023-02-23 15:25:13 +08:00
han0
d8334b26ec feat: 新增 dict/timestamp 2023-02-23 15:10:54 +08:00
han0
d29f80dc2e fix: 修改 core.func 结构 2023-02-23 15:08:07 +08:00
16 changed files with 330 additions and 150 deletions

View File

47
nc_http/core/file/func.py Normal file
View File

@@ -0,0 +1,47 @@
import os
import shutil
import time
import requests
from werkzeug.datastructures import FileStorage
def download_file(url: str, path: str) -> str:
r = requests.get(url)
with open(path, 'wb') as f:
f.write(r.content)
return path
def save_file(f: FileStorage, path: str, namespace: str = None, filename: str = None) -> str:
if namespace:
save_path = os.path.join(path, namespace.replace('.', os.path.sep))
else:
save_path = path
if not os.path.exists(save_path):
os.makedirs(save_path)
filename = filename or '{}{}'.format(str(int(time.time() * 1000)), os.path.splitext(f.filename)[-1])
file_path = os.path.join(save_path, filename)
with open(file_path, 'wb+') as tmp_f:
tmp_f.write(f.read())
return os.path.join(save_path, filename)
def move_file(file_path: str, path: str, namespace: str = None, filename: str = None) -> str:
if namespace:
save_path = os.path.join(path, namespace.replace('.', os.path.sep))
else:
save_path = path
if not os.path.exists(save_path):
os.makedirs(save_path)
filename = filename or '{}{}'.format(str(int(time.time() * 1000)), os.path.splitext(file_path)[-1])
target_file_path = os.path.join(save_path, filename)
shutil.move(file_path, target_file_path)
return target_file_path

View File

@@ -1,150 +0,0 @@
import json
import zlib
from flask import request, g, send_file
from six import string_types
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
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 get_request_json(is_uncamelize=False):
"""
获取 json 传递参数
:param is_uncamelize: 是否进行驼峰->小写下划线转换
:return:
"""
if 'request_data' not in g:
if request.method.lower() == 'get':
data = request.args.to_dict()
else:
if request.content_encoding and 'gzip' in request.content_encoding:
json_data = zlib.decompress(request.get_data())
data = json.loads(json_data)
else:
data = request.get_json(force=True, silent=True) or {}
if is_uncamelize:
data = {uncamelize(k): v for k, v in data.items()}
g.request_data = strip_value(data)
return g.request_data
def get_paging(limit=10):
"""
获取分页参数
:param limit:
:return:
"""
data = get_request_json()
return {
'page': int(data.get('page') or 1),
'size': int(data.get('size') or limit),
'offset': int(data.get('offset') or 0),
'limit': int(data.get('limit') or limit)
}
def get_sorting():
"""
获取排序参数
:return:
"""
data = get_request_json()
if not data.get('order_field'):
return None
return {
'order': data.get('order') or 'asc',
'order_field': uncamelize(data.get('order_field')),
}
def send_excel(file_handler, file_name, suffix='xlsx'):
"""
发送 excel 文件
:param file_handler:
:param file_name:
:param suffix:
:return:
"""
return send_file(
file_handler,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
attachment_filename='{}.{}'.format(file_name, suffix),
as_attachment=True
)
def send_png(img_handler, name='image'):
"""
发送图片文件(可用于验证码)
:param img_handler:
:param name:
:return:
"""
return send_file(
img_handler,
mimetype='image/png',
attachment_filename='{}.png'.format(name),
as_attachment=True
)
def get_client_ip(request):
"""
获取客户端 ip
:param request: flask.Request
:return:
"""
x_forwarded_for = request.headers.get('X-Forwarded-For')
if x_forwarded_for:
ips = x_forwarded_for.split(',')
return ips[0].strip()
return request.headers.get('X-Real-Ip', request.remote_addr)

View File

View File

@@ -0,0 +1,138 @@
import json
import zlib
from datetime import datetime
from time import mktime
from flask import request, g
from nc_http.tools.helpers import uncamelize, strip_value
def get_request_json(is_uncamelize=False):
"""
获取 json 传递参数
:param is_uncamelize: 是否进行驼峰->小写下划线转换
:return:
"""
if 'request_data' not in g:
if request.method.lower() == 'get':
data = request.args.to_dict()
else:
if request.content_encoding and 'gzip' in request.content_encoding:
json_data = zlib.decompress(request.get_data())
data = json.loads(json_data)
else:
data = request.get_json(force=True, silent=True) or {}
if is_uncamelize:
data = {uncamelize(k): v for k, v in data.items()}
g.request_data = strip_value(data)
return g.request_data
def get_paging(limit=10):
"""
获取分页参数
:param limit:
:return:
"""
data = get_request_json()
return {
'page': int(data.get('page') or 1),
'size': int(data.get('size') or limit),
'offset': int(data.get('offset') or 0),
'limit': int(data.get('limit') or limit)
}
def get_sorting():
"""
获取排序参数
:return:
"""
data = get_request_json()
if not data.get('order_field'):
return None
return {
'order': data.get('order') or 'asc',
'order_field': uncamelize(data.get('order_field')),
}
def get_client_ip(request):
"""
获取客户端 ip
:param request: flask.Request
:return:
"""
x_forwarded_for = request.headers.get('X-Forwarded-For')
if x_forwarded_for:
ips = x_forwarded_for.split(',')
return ips[0].strip()
return request.headers.get('X-Real-Ip', request.remote_addr)
def get_time(data, is_datetime=False):
if data:
if isinstance(data, int):
return data
if isinstance(data, datetime):
return int(mktime(data.timetuple()))
_data = None
if data.isdigit():
_data = int(data)
if is_datetime:
_data = datetime.fromtimestamp(_data)
else:
if data.count('-') == 2:
date_format = '%Y-%m-%d'
elif data.count('-') == 1:
date_format = '%Y-%m'
elif data.count('/') == 2:
date_format = '%Y/%m/%d'
else:
date_format = ''
if data.count(':') == 2:
time_format = '%H:%M:%S'
elif data.count(':') == 1:
time_format = '%H:%M'
else:
time_format = ''
if date_format or time_format:
if ' ' in data:
datetime_format = '{} {}'.format(date_format, time_format)
else:
datetime_format = '{}{}'.format(date_format, time_format)
_data = datetime.strptime(data, datetime_format)
if is_datetime is False:
_data = int(mktime(_data.timetuple()))
else:
if is_datetime:
return None
return 0
else:
if is_datetime:
return None
return 0
return _data
def get_file():
file_handler = None
for key in request.files:
f = request.files[key]
file_handler = f
break
if not file_handler:
return None
return file_handler

View File

@@ -0,0 +1,32 @@
from flask import send_file
def send_excel(file_handler, file_name, suffix='xlsx'):
"""
发送 excel 文件
:param file_handler:
:param file_name:
:param suffix:
:return:
"""
return send_file(
file_handler,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
attachment_filename='{}.{}'.format(file_name, suffix),
as_attachment=True
)
def send_png(img_handler, name='image'):
"""
发送图片文件(可用于验证码)
:param img_handler:
:param name:
:return:
"""
return send_file(
img_handler,
mimetype='image/png',
attachment_filename='{}.png'.format(name),
as_attachment=True
)

View File

View File

View File

@@ -0,0 +1,31 @@
class ElasticBase:
index = None # 索引名称
query = {} # dsl 查询参数
es = None # es 实例
@classmethod
def search(cls, query=None, **params):
query = query or cls.query.copy()
for param in params:
print(param) # 根据参数构建查询 dsl
return query
@classmethod
def get_list(cls, query, paging=None):
params = {}
if paging:
params['size'] = paging['limit']
params['from'] = (paging['page'] - 1) * paging['limit']
result = cls.es.search(index=cls.index, body=query, params=params)
data = []
for row in result['hits']['hits']:
source = row['_source']
source['_score'] = row['_score']
source['_sort'] = row.get('sort')
data.append(source)
paging['total'] = result['hits']['total']['value']
return data, paging

View File

@@ -0,0 +1,25 @@
import json
import requests
from elasticsearch_dsl import connections
def clean_es(host, index_name, type_=None):
"""
清空 es
:param host:
:param index_name:
:param type_:
:return:
"""
connections.create_connection(hosts=[host])
headers = {'Content-Type': 'application/json'}
# 删除 index
url = '{}/{}/_delete_by_query'.format(host, index_name)
if not type_:
data = {"query": {"match_all": {}}}
else:
data = {"query": {"term": {"type": {"value": type_}}}}
result = requests.post(url, json.dumps(data), headers=headers)
r = json.loads(result.content)
print(r)

View File

@@ -0,0 +1,9 @@
from nc_http.tools.helpers import uncamelize, camelize
def uncamelize_dict(d):
return {uncamelize(k): v for k, v in d.items()}
def camelize_dict(d):
return {camelize(k): v for k, v in d.items()}

View File

View File

@@ -0,0 +1,23 @@
def filter_fields(data, valid_fields):
"""
过滤字段
:param data:
:param valid_fields: 格式['field1', 'field2', 'field3', {'field4': ['sub_field1', 'sub_field2']}]
:return:
"""
if isinstance(data, list):
tmp = []
for item in data:
tmp.append(filter_fields(item, valid_fields))
format_data = tmp
else:
format_data = {}
for field in valid_fields:
if isinstance(field, dict):
for key, sub_valid_fields in field.items():
if isinstance(sub_valid_fields, list) and key in data:
format_data[key] = filter_fields(data[key], sub_valid_fields)
else:
if field in data:
format_data[field] = data[field]
return format_data

View File

@@ -0,0 +1,21 @@
def get_day_list(start_time, end_time, day_limits=365):
"""
:param start_time:
:param end_time:
:param day_limits:
:return:
"""
mod = start_time % (24 * 60 * 60)
if mod > 0:
day = start_time - mod + (24 * 60 * 60)
else:
day = start_time
day_list = []
for _ in range(day_limits):
if day <= end_time:
day_list.append(day)
day += (24 * 60 * 60)
else:
break
return day_list

4
upload.bat Normal file
View File

@@ -0,0 +1,4 @@
python36 -m pip install --upgrade setuptools wheel twine -i https://pypi.douban.com/simple
python36 setup.py sdist bdist_wheel
twine check dist/*
twine upload --repository-url http://192.168.12.2:8082/repository/pypi-hosted/ dist/*