Compare commits
10 Commits
36a99c0f5a
...
d1881c5ff7
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d1881c5ff7 | ||
![]() |
5a552f02ea | ||
![]() |
edd6ea8dc7 | ||
![]() |
a8854edd92 | ||
![]() |
6f004e73fd | ||
![]() |
3deb269adc | ||
![]() |
7ac1560c15 | ||
![]() |
42430ea111 | ||
![]() |
d8334b26ec | ||
![]() |
d29f80dc2e |
Binary file not shown.
0
nc_http/core/file/__init__.py
Normal file
0
nc_http/core/file/__init__.py
Normal file
47
nc_http/core/file/func.py
Normal file
47
nc_http/core/file/func.py
Normal 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
|
@@ -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)
|
|
0
nc_http/core/request/__init__.py
Normal file
0
nc_http/core/request/__init__.py
Normal file
138
nc_http/core/request/func.py
Normal file
138
nc_http/core/request/func.py
Normal 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
|
32
nc_http/core/response/func.py
Normal file
32
nc_http/core/response/func.py
Normal 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
|
||||||
|
)
|
0
nc_http/core/search/__init__.py
Normal file
0
nc_http/core/search/__init__.py
Normal file
0
nc_http/core/search/es/__init__.py
Normal file
0
nc_http/core/search/es/__init__.py
Normal file
31
nc_http/core/search/es/elastic_base.py
Normal file
31
nc_http/core/search/es/elastic_base.py
Normal 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
|
25
nc_http/core/search/es/func.py
Normal file
25
nc_http/core/search/es/func.py
Normal 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)
|
9
nc_http/tools/helpers/dict.py
Normal file
9
nc_http/tools/helpers/dict.py
Normal 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()}
|
0
nc_http/tools/helpers/file.py
Normal file
0
nc_http/tools/helpers/file.py
Normal file
23
nc_http/tools/helpers/params.py
Normal file
23
nc_http/tools/helpers/params.py
Normal 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
|
21
nc_http/tools/helpers/timestamp.py
Normal file
21
nc_http/tools/helpers/timestamp.py
Normal 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
4
upload.bat
Normal 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/*
|
Reference in New Issue
Block a user