cloudoll 2.2.7__tar.gz → 2.2.9__tar.gz
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.
- {cloudoll-2.2.7 → cloudoll-2.2.9}/PKG-INFO +1 -1
- cloudoll-2.2.9/cloudoll/__init__.py +1 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/logging/__init__.py +20 -6
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/__init__.py +12 -8
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/field.py +1 -1
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/model.py +19 -15
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/utils/watch.py +0 -1
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/__init__.py +17 -7
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/PKG-INFO +1 -1
- cloudoll-2.2.7/cloudoll/__init__.py +0 -1
- {cloudoll-2.2.7 → cloudoll-2.2.9}/LICENSE +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/README.md +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/__main__.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/cli.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/error/__init__.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/error/errors.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/mail/smtp.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/base.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/err.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/mysql.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/parse.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/orm/postgres.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/robot/__init__.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/robot/dingtalk.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/robot/feishu.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/robot/slack.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/utils/common.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/utils/m2d.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/utils/patch_loop.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/exception.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/html.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/http.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/jwt.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll/web/settings.py +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/SOURCES.txt +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/requires.txt +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/setup.cfg +0 -0
- {cloudoll-2.2.7 → cloudoll-2.2.9}/setup.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.9"
|
|
@@ -19,6 +19,7 @@ __ALL__ = (
|
|
|
19
19
|
"critical",
|
|
20
20
|
"print_info",
|
|
21
21
|
"print_error",
|
|
22
|
+
"print_warn",
|
|
22
23
|
)
|
|
23
24
|
_COLORS = {
|
|
24
25
|
# 终端输出日志颜色配置
|
|
@@ -40,9 +41,11 @@ class ColorAnsi:
|
|
|
40
41
|
|
|
41
42
|
_FORMATS = {
|
|
42
43
|
# 终端输出格式
|
|
43
|
-
"console_format": "%(log_color)s[%(levelname)s]-%(asctime)s-%(pathname)s-%(module)s-%(funcName)s-[line:%(lineno)d]: %(message)s",
|
|
44
|
+
# "console_format": "%(log_color)s[%(levelname)s]-%(asctime)s-%(pathname)s-%(module)s-%(funcName)s-[line:%(lineno)d]: %(message)s",
|
|
45
|
+
"console_format": "%(log_color)s%(asctime)s %(levelname)s %(funcName)s %(message)s",
|
|
44
46
|
# 日志输出格式
|
|
45
|
-
"log_format": "[%(levelname)s]-%(asctime)s-%(pathname)s-%(module)s-%(funcName)s-[line:%(lineno)d]: %(message)s",
|
|
47
|
+
# "log_format": "[%(levelname)s]-%(asctime)s-%(pathname)s-%(module)s-%(funcName)s-[line:%(lineno)d]: %(message)s",
|
|
48
|
+
"log_format": "%(asctime)s %(levelname)s %(funcName)s %(message)s",
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
_LOG_SIZE = 1024 * 1024 * 1 # 1MB 日志最大1MB
|
|
@@ -138,12 +141,23 @@ class HandleLog:
|
|
|
138
141
|
_handler = None
|
|
139
142
|
|
|
140
143
|
|
|
141
|
-
def
|
|
142
|
-
|
|
144
|
+
def print_format(color_ansi, type, *args):
|
|
145
|
+
ft = color_ansi + "{}" + ColorAnsi.END
|
|
146
|
+
timestamp = ft.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S") + " " + type)
|
|
147
|
+
text = " ".join(ft.format(str(arg)) for arg in args)
|
|
148
|
+
print(timestamp, text)
|
|
143
149
|
|
|
144
150
|
|
|
145
|
-
def
|
|
146
|
-
|
|
151
|
+
def print_info(*args):
|
|
152
|
+
print_format(ColorAnsi.GREEN, "INFO", *args)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def print_error(*args):
|
|
156
|
+
print_format(ColorAnsi.RED, "ERROR", *args)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def print_warn(*args):
|
|
160
|
+
print_format(ColorAnsi.YELLOW, "WARN", *args)
|
|
147
161
|
|
|
148
162
|
|
|
149
163
|
def _get_handle():
|
|
@@ -3,7 +3,7 @@ from .parse import parse_coon
|
|
|
3
3
|
import aiopg, aiomysql
|
|
4
4
|
from .base import MeteBase, QueryTypes
|
|
5
5
|
from typing import Any
|
|
6
|
-
from ..logging import
|
|
6
|
+
from ..logging import print_info, print_error
|
|
7
7
|
import traceback
|
|
8
8
|
|
|
9
9
|
|
|
@@ -35,7 +35,7 @@ async def create_engine(**kw):
|
|
|
35
35
|
url = f"{driver}://{configs['username']}:{configs['password']}@{configs['host']}:{configs['port']}/{configs['db']}"
|
|
36
36
|
return await aioredis.from_url(url, **query)
|
|
37
37
|
else:
|
|
38
|
-
|
|
38
|
+
print_error("Not suport this database type.")
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class Postgres(MeteBase):
|
|
@@ -104,11 +104,13 @@ class Postgres(MeteBase):
|
|
|
104
104
|
maxsize=kw.get("maxsize", 10),
|
|
105
105
|
minsize=kw.get("pool_size", 5),
|
|
106
106
|
)
|
|
107
|
-
|
|
107
|
+
print_info(f"Database connection successfuly for postgres/{kw.get('db')}")
|
|
108
108
|
except Exception as e:
|
|
109
|
-
error(e)
|
|
109
|
+
# error(e)
|
|
110
110
|
# print(traceback.format_exc())
|
|
111
|
-
|
|
111
|
+
print_error(
|
|
112
|
+
f"Database connection failed,the instance : postgres/{kw.get('db')}"
|
|
113
|
+
)
|
|
112
114
|
|
|
113
115
|
return self
|
|
114
116
|
|
|
@@ -191,9 +193,11 @@ class Mysql(MeteBase):
|
|
|
191
193
|
cursorclass=AttrDictCursor,
|
|
192
194
|
loop=loop,
|
|
193
195
|
)
|
|
194
|
-
|
|
196
|
+
print_info(f"Database connection successfuly for mysql/{kw.get('db')}.")
|
|
195
197
|
except Exception as e:
|
|
196
|
-
print(e)
|
|
198
|
+
# print(e)
|
|
197
199
|
# print(traceback.format_exc())
|
|
198
|
-
|
|
200
|
+
print_error(
|
|
201
|
+
f"Database connection failed,the instance : mysql/{kw.get('db')}"
|
|
202
|
+
)
|
|
199
203
|
return self
|
|
@@ -21,10 +21,12 @@ class ModelMetaclass(type):
|
|
|
21
21
|
table_name = attrs.get("__table__", None) or name
|
|
22
22
|
primary_key = None
|
|
23
23
|
fields = []
|
|
24
|
+
# mappings = dict()
|
|
24
25
|
for k, v in attrs.items():
|
|
25
26
|
if isinstance(v, Field):
|
|
26
27
|
v.name = k
|
|
27
28
|
v.full_name = f"`{table_name}`.{k}"
|
|
29
|
+
# mappings[k] = v
|
|
28
30
|
if v.primary_key:
|
|
29
31
|
if primary_key:
|
|
30
32
|
warning(f"Duplicate primary key for {table_name}")
|
|
@@ -55,7 +57,6 @@ class ModelMetaclass(type):
|
|
|
55
57
|
attrs["__offset__"] = None
|
|
56
58
|
|
|
57
59
|
model = type.__new__(mcs, name, bases, attrs)
|
|
58
|
-
# sa.__MODELS__.append(model)
|
|
59
60
|
return model
|
|
60
61
|
|
|
61
62
|
def __repr__(self):
|
|
@@ -71,14 +72,7 @@ class Model(metaclass=ModelMetaclass):
|
|
|
71
72
|
f = getattr(self, k, None)
|
|
72
73
|
f.value = None
|
|
73
74
|
for k, v in kw.items():
|
|
74
|
-
|
|
75
|
-
f = getattr(self, k, None)
|
|
76
|
-
if isinstance(f, Field):
|
|
77
|
-
if v is None:
|
|
78
|
-
v = f.default
|
|
79
|
-
f.value = v
|
|
80
|
-
else:
|
|
81
|
-
setattr(self, k, v)
|
|
75
|
+
self[k] = v
|
|
82
76
|
|
|
83
77
|
# super().__init__(self, **kw)
|
|
84
78
|
|
|
@@ -114,7 +108,9 @@ class Model(metaclass=ModelMetaclass):
|
|
|
114
108
|
if hasattr(self, name):
|
|
115
109
|
f = getattr(self, name)
|
|
116
110
|
if isinstance(f, Field):
|
|
117
|
-
|
|
111
|
+
s = copy.copy(f)
|
|
112
|
+
s.value = value
|
|
113
|
+
super().__setattr__(name, s)
|
|
118
114
|
else:
|
|
119
115
|
super().__setattr__(name, value)
|
|
120
116
|
else:
|
|
@@ -314,15 +310,23 @@ class Model(metaclass=ModelMetaclass):
|
|
|
314
310
|
|
|
315
311
|
sql = f"update `{table}` set {keys}"
|
|
316
312
|
|
|
317
|
-
pk, pkv = self._get_primary()
|
|
318
313
|
if where is not None:
|
|
319
314
|
sql += f' where {" and ".join(f for f in where)}'
|
|
320
315
|
params += self.__params__
|
|
321
|
-
elif pkv is not None:
|
|
322
|
-
sql += f" where `{pk}`=?"
|
|
323
|
-
params.append(pkv)
|
|
324
316
|
else:
|
|
325
|
-
|
|
317
|
+
pk, pkv = self._get_primary()
|
|
318
|
+
if pkv is None:
|
|
319
|
+
for arg in args:
|
|
320
|
+
if isinstance(arg, dict) and pk in arg:
|
|
321
|
+
pkv = arg[pk]
|
|
322
|
+
elif isinstance(arg, Model):
|
|
323
|
+
pkv = arg.get(pk)
|
|
324
|
+
|
|
325
|
+
if pkv is not None:
|
|
326
|
+
sql += f" where `{pk}`=?"
|
|
327
|
+
params.append(pkv)
|
|
328
|
+
else:
|
|
329
|
+
raise "Need where or primary key"
|
|
326
330
|
|
|
327
331
|
return await self.__pool__.update(sql, params)
|
|
328
332
|
|
|
@@ -51,6 +51,7 @@ __ALL__ = (
|
|
|
51
51
|
"put",
|
|
52
52
|
"delete",
|
|
53
53
|
"render_json",
|
|
54
|
+
"render_error",
|
|
54
55
|
"middleware",
|
|
55
56
|
"render_view",
|
|
56
57
|
"redirect",
|
|
@@ -64,29 +65,29 @@ class _Handler(object):
|
|
|
64
65
|
self.fn = fn
|
|
65
66
|
|
|
66
67
|
async def __call__(self, request):
|
|
67
|
-
|
|
68
|
+
content_type = request.content_type
|
|
68
69
|
# 获取函数参数的名称和默认值
|
|
69
70
|
props = inspect.getfullargspec(self.fn)
|
|
70
|
-
if len(props.args) == 2 and
|
|
71
|
+
if len(props.args) == 2 and content_type == "multipart/form-data":
|
|
71
72
|
await _set_session_route(request)
|
|
72
73
|
multipart = await request.multipart()
|
|
73
74
|
field = await multipart.next()
|
|
74
75
|
result = await self.fn(request, field)
|
|
75
76
|
elif len(props.args) == 1:
|
|
76
77
|
await _set_session_route(request)
|
|
77
|
-
if
|
|
78
|
+
if content_type == "multipart/form-data":
|
|
78
79
|
data = await request.post()
|
|
79
|
-
elif
|
|
80
|
+
elif content_type == "application/json":
|
|
80
81
|
data = await request.json()
|
|
81
82
|
else:
|
|
82
83
|
data = await request.post()
|
|
83
|
-
|
|
84
|
+
query_string = request.query_string
|
|
84
85
|
body = {}
|
|
85
86
|
for k in data:
|
|
86
87
|
body[k] = data[k]
|
|
87
88
|
qs = {}
|
|
88
|
-
if
|
|
89
|
-
for k, v in parse.parse_qs(
|
|
89
|
+
if query_string:
|
|
90
|
+
for k, v in parse.parse_qs(query_string, True).items():
|
|
90
91
|
qs[k] = v[0]
|
|
91
92
|
request.qs = Object(qs)
|
|
92
93
|
request.body = Object(body)
|
|
@@ -536,6 +537,10 @@ def all(path: str):
|
|
|
536
537
|
return app.route_table.view(path)
|
|
537
538
|
|
|
538
539
|
|
|
540
|
+
def render_error(msg, status=500) -> Response:
|
|
541
|
+
return render_json({"message": msg, "code": status}, status=status)
|
|
542
|
+
|
|
543
|
+
|
|
539
544
|
def render_json(data, **kw) -> Response:
|
|
540
545
|
res = {}
|
|
541
546
|
if isinstance(data, list):
|
|
@@ -547,6 +552,11 @@ def render_json(data, **kw) -> Response:
|
|
|
547
552
|
res.update(data)
|
|
548
553
|
else:
|
|
549
554
|
res["data"] = data
|
|
555
|
+
status = kw.get("status", 200)
|
|
556
|
+
if status == 200:
|
|
557
|
+
res["message"] = "OK"
|
|
558
|
+
res["code"] = 200
|
|
559
|
+
|
|
550
560
|
res["timestamp"] = int(datetime.now().timestamp() * 1000)
|
|
551
561
|
text = json.dumps(res, ensure_ascii=False, cls=JsonEncoder)
|
|
552
562
|
return web.json_response(text=text, **kw)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.7"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|