cloudoll 2.2.9__tar.gz → 2.2.11__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.9 → cloudoll-2.2.11}/PKG-INFO +1 -1
- cloudoll-2.2.11/cloudoll/__init__.py +1 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/cli.py +22 -15
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/mail/smtp.py +5 -5
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/__init__.py +12 -6
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/base.py +1 -1
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/model.py +3 -3
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/mysql.py +2 -2
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/parse.py +2 -2
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/postgres.py +3 -3
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/robot/dingtalk.py +9 -9
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/robot/feishu.py +7 -6
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/utils/m2d.py +4 -4
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/utils/watch.py +13 -10
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/__init__.py +17 -16
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/http.py +12 -11
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/jwt.py +2 -2
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/settings.py +2 -2
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/PKG-INFO +1 -1
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/requires.txt +1 -1
- {cloudoll-2.2.9 → cloudoll-2.2.11}/setup.py +2 -1
- cloudoll-2.2.9/cloudoll/__init__.py +0 -1
- {cloudoll-2.2.9 → cloudoll-2.2.11}/LICENSE +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/README.md +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/__main__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/error/__init__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/error/errors.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/logging/__init__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/mail/__init__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/err.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/orm/field.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/robot/__init__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/robot/slack.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/utils/__init__.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/utils/common.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/utils/patch_loop.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/exception.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll/web/html.py +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/SOURCES.txt +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/dependency_links.txt +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/entry_points.txt +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/cloudoll.egg-info/top_level.txt +0 -0
- {cloudoll-2.2.9 → cloudoll-2.2.11}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.2.11"
|
|
@@ -6,11 +6,10 @@ from .utils.m2d import create_models, create_tables
|
|
|
6
6
|
import asyncio
|
|
7
7
|
import os
|
|
8
8
|
import sys
|
|
9
|
-
from .logging import
|
|
9
|
+
from .logging import print_error, print_info
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from . import __version__
|
|
12
12
|
import traceback
|
|
13
|
-
import logging
|
|
14
13
|
from .utils.watch import AppTask
|
|
15
14
|
from aiohttp import web
|
|
16
15
|
from .utils.common import chainMap
|
|
@@ -54,7 +53,6 @@ def gen(path, create, table, environment, database) -> None:
|
|
|
54
53
|
if sa.pool is None:
|
|
55
54
|
return
|
|
56
55
|
model_path = os.path.join(os.path.abspath("."), path)
|
|
57
|
-
# print(model_path)
|
|
58
56
|
tables = None
|
|
59
57
|
if table != "ALL":
|
|
60
58
|
tables = table.split(",")
|
|
@@ -68,8 +66,7 @@ def gen(path, create, table, environment, database) -> None:
|
|
|
68
66
|
await create_tables(sa, model_path, tables=tables)
|
|
69
67
|
|
|
70
68
|
except Exception as e:
|
|
71
|
-
|
|
72
|
-
print(traceback.print_exc())
|
|
69
|
+
print_error(traceback.print_exc())
|
|
73
70
|
click.echo("input `cloudoll --help` for more helps.")
|
|
74
71
|
finally:
|
|
75
72
|
await sa.close()
|
|
@@ -79,23 +76,31 @@ def gen(path, create, table, environment, database) -> None:
|
|
|
79
76
|
|
|
80
77
|
@cli.command()
|
|
81
78
|
@click.option("-env", "--environment", help="Environment, local / test / prod", default="local")
|
|
82
|
-
@click.option("-p", "--port", help="Server's port", default=
|
|
83
|
-
@click.option("-h", "--host", help="Server's host", default=
|
|
79
|
+
@click.option("-p", "--port", help="Server's port", default=9001)
|
|
80
|
+
@click.option("-h", "--host", help="Server's host", default='0.0.0.0')
|
|
81
|
+
@click.option("-m", "--mode", help="development or production mode", default='development')
|
|
84
82
|
@click.option("-path", "--path",help="Unix file system path to serve on. Specifying a path will cause hostname and port arguments to be ignored.",)
|
|
85
|
-
@click.option("-
|
|
86
|
-
def start(environment, host, port, path,
|
|
83
|
+
@click.option("-e", "--entry", help="Entry point model name. delfault name app", default="app")
|
|
84
|
+
def start(environment, host, port, mode, path, entry) -> None:
|
|
87
85
|
"""Start a services."""
|
|
88
86
|
try:
|
|
87
|
+
print_info("Current mode: " ,mode)
|
|
88
|
+
config = get_config(environment)
|
|
89
|
+
# print(environment, host, port, mode, path, entry)
|
|
90
|
+
# return
|
|
91
|
+
if mode == 'production':
|
|
92
|
+
App = app.create(config=config)
|
|
93
|
+
App.run()
|
|
94
|
+
return
|
|
89
95
|
aux_app = web.Application(
|
|
90
96
|
logger=None,
|
|
91
97
|
)
|
|
92
|
-
config = get_config(environment)
|
|
93
98
|
server = config.get("server", {})
|
|
94
99
|
server = chainMap(server, {"host": host, "port": port, "path": path})
|
|
95
100
|
config["server"] = server
|
|
96
101
|
|
|
97
102
|
aux_port = int(server.port) + 1
|
|
98
|
-
task = AppTask(Path(".").resolve(), config, entry=
|
|
103
|
+
task = AppTask(Path(".").resolve(), config, entry=entry)
|
|
99
104
|
aux_app.cleanup_ctx.append(task.cleanup_ctx)
|
|
100
105
|
web.run_app(
|
|
101
106
|
aux_app,
|
|
@@ -105,10 +110,12 @@ def start(environment, host, port, path, model) -> None:
|
|
|
105
110
|
print=None,
|
|
106
111
|
shutdown_timeout=0.1,
|
|
107
112
|
)
|
|
113
|
+
except KeyboardInterrupt:
|
|
114
|
+
sys.exit(0)
|
|
108
115
|
except Exception as e:
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
sys.exit(
|
|
116
|
+
# print_error(e)
|
|
117
|
+
print_error(traceback.format_exc())
|
|
118
|
+
sys.exit(0)
|
|
112
119
|
|
|
113
120
|
|
|
114
121
|
_project_existing = click.Path(dir_okay=True)
|
|
@@ -120,7 +127,7 @@ def create(project_name) -> None:
|
|
|
120
127
|
full_path = os.path.join(os.path.abspath("."), project_name)
|
|
121
128
|
# log = logging.getLogger('cloudoll.create')
|
|
122
129
|
if os.path.exists(full_path):
|
|
123
|
-
|
|
130
|
+
print_error(f"Project name `{project_name}` already exist.")
|
|
124
131
|
# return None
|
|
125
132
|
|
|
126
133
|
|
|
@@ -46,7 +46,7 @@ from email.mime.multipart import MIMEMultipart
|
|
|
46
46
|
|
|
47
47
|
from email.utils import parseaddr, formataddr
|
|
48
48
|
import mimetypes
|
|
49
|
-
from ..logging import
|
|
49
|
+
from ..logging import print_info, print_error
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
def _format_addr(s):
|
|
@@ -78,10 +78,10 @@ class Client(object):
|
|
|
78
78
|
password = self._password
|
|
79
79
|
if account is None or password is None:
|
|
80
80
|
raise KeyError("请设置账号密码")
|
|
81
|
-
|
|
81
|
+
print_info("登录中...")
|
|
82
82
|
self._server.login(account, password)
|
|
83
83
|
except BaseException as e:
|
|
84
|
-
|
|
84
|
+
print_error(e)
|
|
85
85
|
raise
|
|
86
86
|
|
|
87
87
|
def send(self):
|
|
@@ -107,7 +107,7 @@ class Client(object):
|
|
|
107
107
|
self._server.sendmail(self._account, to_addr, msg.as_string())
|
|
108
108
|
self._server.quit()
|
|
109
109
|
except BaseException as er:
|
|
110
|
-
|
|
110
|
+
print_error(er)
|
|
111
111
|
|
|
112
112
|
def add_to_addr(self, nick, addr):
|
|
113
113
|
"""
|
|
@@ -139,7 +139,7 @@ class Client(object):
|
|
|
139
139
|
if len(mime_types) > 0:
|
|
140
140
|
mime_type = mime_types[0]
|
|
141
141
|
else:
|
|
142
|
-
|
|
142
|
+
print_error("无法匹配附件类型,可以尝试安装httpd服务")
|
|
143
143
|
## 这里如果拿不到type 需要安装httpd ,dnf install httpd
|
|
144
144
|
[t, n] = mime_type.split("/")
|
|
145
145
|
filename = os.path.basename(filepath) # 'a.txt'
|
|
@@ -5,6 +5,8 @@ from .base import MeteBase, QueryTypes
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
from ..logging import print_info, print_error
|
|
7
7
|
import traceback
|
|
8
|
+
from aiomysql import Pool as MYPool
|
|
9
|
+
from aiopg.pool import Pool as PGPool
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
async def create_engine(**kw):
|
|
@@ -20,7 +22,7 @@ async def create_engine(**kw):
|
|
|
20
22
|
driver = kw.get("type")
|
|
21
23
|
configs = kw
|
|
22
24
|
|
|
23
|
-
print_info("DB Config:", configs, query)
|
|
25
|
+
# print_info("DB Config:", configs, query)
|
|
24
26
|
|
|
25
27
|
if driver == "mysql":
|
|
26
28
|
return await Mysql().create_engine(**configs, **query)
|
|
@@ -40,7 +42,7 @@ async def create_engine(**kw):
|
|
|
40
42
|
|
|
41
43
|
class Postgres(MeteBase):
|
|
42
44
|
def __init__(self, pool=None):
|
|
43
|
-
self.pool = pool
|
|
45
|
+
self.pool: PGPool = pool
|
|
44
46
|
self.driver = "postgres"
|
|
45
47
|
|
|
46
48
|
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
@@ -48,9 +50,11 @@ class Postgres(MeteBase):
|
|
|
48
50
|
|
|
49
51
|
async def query(self, sql, params=None, query_type: QueryTypes = 2, size: int = 10):
|
|
50
52
|
sql = sql.replace("?", "%s").replace("`", "")
|
|
51
|
-
|
|
53
|
+
print_info("sql", sql, params)
|
|
52
54
|
if not self.pool:
|
|
53
55
|
raise ValueError("must be create_engine first.")
|
|
56
|
+
if self.pool._closing or self.pool._closed:
|
|
57
|
+
return None
|
|
54
58
|
async with self.pool.acquire() as conn:
|
|
55
59
|
async with conn.cursor() as cursor:
|
|
56
60
|
# current_cursor = getattr(cursor, 'lastrowid', None)
|
|
@@ -106,7 +110,7 @@ class Postgres(MeteBase):
|
|
|
106
110
|
)
|
|
107
111
|
print_info(f"Database connection successfuly for postgres/{kw.get('db')}")
|
|
108
112
|
except Exception as e:
|
|
109
|
-
#
|
|
113
|
+
# print_error(e)
|
|
110
114
|
# print(traceback.format_exc())
|
|
111
115
|
print_error(
|
|
112
116
|
f"Database connection failed,the instance : postgres/{kw.get('db')}"
|
|
@@ -131,7 +135,7 @@ class AttrDictCursor(aiomysql.DictCursor):
|
|
|
131
135
|
|
|
132
136
|
class Mysql(MeteBase):
|
|
133
137
|
def __init__(self, pool=None):
|
|
134
|
-
self.pool = pool
|
|
138
|
+
self.pool: MYPool = pool
|
|
135
139
|
self.driver = "mysql"
|
|
136
140
|
|
|
137
141
|
def __call__(self, *args: Any, **kwds: Any) -> Any:
|
|
@@ -140,9 +144,11 @@ class Mysql(MeteBase):
|
|
|
140
144
|
|
|
141
145
|
async def query(self, sql, params=None, query_type: QueryTypes = 2, size: int = 10):
|
|
142
146
|
sql = sql.replace("?", "%s")
|
|
143
|
-
|
|
147
|
+
print_info("sql", sql, params)
|
|
144
148
|
if not self.pool:
|
|
145
149
|
raise ValueError("must be create_engine first.")
|
|
150
|
+
if self.pool._closing or self.pool._closed:
|
|
151
|
+
return None
|
|
146
152
|
async with self.pool.acquire() as conn:
|
|
147
153
|
async with conn.cursor() as cursor:
|
|
148
154
|
# current_cursor = getattr(cursor, 'lastrowid', None)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from .field import Field, Function, Expression
|
|
2
|
-
from ..logging import
|
|
2
|
+
from ..logging import print_warn
|
|
3
3
|
from functools import reduce
|
|
4
4
|
import operator
|
|
5
5
|
import copy, datetime
|
|
@@ -29,13 +29,13 @@ class ModelMetaclass(type):
|
|
|
29
29
|
# mappings[k] = v
|
|
30
30
|
if v.primary_key:
|
|
31
31
|
if primary_key:
|
|
32
|
-
|
|
32
|
+
print_warn(f"Duplicate primary key for {table_name}")
|
|
33
33
|
primary_key = k
|
|
34
34
|
else:
|
|
35
35
|
fields.append(k)
|
|
36
36
|
|
|
37
37
|
if not primary_key:
|
|
38
|
-
|
|
38
|
+
print_warn(f"{table_name} Missing primary key")
|
|
39
39
|
|
|
40
40
|
# for k in mappings.keys():
|
|
41
41
|
# attrs.pop(k)
|
|
@@ -30,7 +30,7 @@ from aiomysql.pool import Pool
|
|
|
30
30
|
|
|
31
31
|
# from aiomysql.cursors import Cursor
|
|
32
32
|
# from aiomysql.connection import Connection
|
|
33
|
-
from cloudoll.logging import
|
|
33
|
+
from cloudoll.logging import print_error
|
|
34
34
|
|
|
35
35
|
# from inspect import isclass, isfunction
|
|
36
36
|
from .base import MeteBase
|
|
@@ -79,5 +79,5 @@ class Mysql(MeteBase):
|
|
|
79
79
|
loop=loop,
|
|
80
80
|
)
|
|
81
81
|
except Exception as e:
|
|
82
|
-
|
|
82
|
+
print_error(f"Database connection failed,the instance : {kw.get('db')}")
|
|
83
83
|
return self
|
|
@@ -49,7 +49,7 @@ def parse_coon(url: str):
|
|
|
49
49
|
query = {}
|
|
50
50
|
if configs["query"] is not None:
|
|
51
51
|
|
|
52
|
-
for key, value in
|
|
52
|
+
for key, value in parse_sql(configs["query"]):
|
|
53
53
|
if key in query:
|
|
54
54
|
query[key] = to_list(query[key])
|
|
55
55
|
cast("List[str]", query[key]).append(value)
|
|
@@ -72,7 +72,7 @@ def to_list(x: Any, default: Optional[List[Any]] = None) -> List[Any]:
|
|
|
72
72
|
return list(x)
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
def
|
|
75
|
+
def parse_sql(
|
|
76
76
|
qs,
|
|
77
77
|
keep_blank_values=False,
|
|
78
78
|
strict_parsing=False,
|
|
@@ -26,7 +26,7 @@ result = await pool.query("sql")
|
|
|
26
26
|
__author__ = "chuchur/chuchur.com"
|
|
27
27
|
|
|
28
28
|
from aiopg import create_pool, Pool, Cursor, Connection
|
|
29
|
-
from ..logging import
|
|
29
|
+
from ..logging import print_error
|
|
30
30
|
from .base import MeteBase
|
|
31
31
|
from typing import Any
|
|
32
32
|
|
|
@@ -59,7 +59,7 @@ class Postgres(MeteBase):
|
|
|
59
59
|
minsize=kw.get("pool_size", 5),
|
|
60
60
|
)
|
|
61
61
|
except Exception as e:
|
|
62
|
-
#
|
|
63
|
-
|
|
62
|
+
# print_error(e)
|
|
63
|
+
print_error(f"Database connection failed,the instance : {kw.get('db')}")
|
|
64
64
|
|
|
65
65
|
return self
|
|
@@ -7,8 +7,8 @@ __author__ = "chuchur/chuchur.com"
|
|
|
7
7
|
import base64
|
|
8
8
|
import hashlib
|
|
9
9
|
import hmac
|
|
10
|
-
import
|
|
11
|
-
import requests as http
|
|
10
|
+
from ..logging import print_error
|
|
11
|
+
from curl_cffi import requests as http
|
|
12
12
|
import time
|
|
13
13
|
from urllib import parse
|
|
14
14
|
|
|
@@ -22,7 +22,7 @@ class Client(object):
|
|
|
22
22
|
def _get_sign(self):
|
|
23
23
|
secret = self._secret
|
|
24
24
|
if not secret:
|
|
25
|
-
|
|
25
|
+
print_error("缺少secret")
|
|
26
26
|
return None, None
|
|
27
27
|
|
|
28
28
|
# 拼接timestamp和secret
|
|
@@ -48,7 +48,7 @@ class Client(object):
|
|
|
48
48
|
"""
|
|
49
49
|
access_token = self._access_token
|
|
50
50
|
if not access_token:
|
|
51
|
-
|
|
51
|
+
print_error("请配置access_token")
|
|
52
52
|
return False
|
|
53
53
|
url = "https://oapi.dingtalk.com/media/upload?access_token=%s" % access_token
|
|
54
54
|
with open(filepath, "rb") as f:
|
|
@@ -58,7 +58,7 @@ class Client(object):
|
|
|
58
58
|
if res["errcode"] == 0:
|
|
59
59
|
return res
|
|
60
60
|
else:
|
|
61
|
-
|
|
61
|
+
print_error(res["errmsg"])
|
|
62
62
|
|
|
63
63
|
def send(self, data: dict):
|
|
64
64
|
"""
|
|
@@ -67,7 +67,7 @@ class Client(object):
|
|
|
67
67
|
"""
|
|
68
68
|
webhook = self._webhook
|
|
69
69
|
if not webhook:
|
|
70
|
-
|
|
70
|
+
print_error("缺少webhook")
|
|
71
71
|
return False
|
|
72
72
|
timestamp, sign = self._get_sign()
|
|
73
73
|
if not timestamp or not sign:
|
|
@@ -82,11 +82,11 @@ class Client(object):
|
|
|
82
82
|
if result:
|
|
83
83
|
res = result.json()
|
|
84
84
|
if res["errcode"] == 0:
|
|
85
|
-
|
|
85
|
+
print_error("发送成功!")
|
|
86
86
|
return True
|
|
87
87
|
else:
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
print_error("发送失败")
|
|
89
|
+
print_error(res["errmsg"])
|
|
90
90
|
return False
|
|
91
91
|
|
|
92
92
|
def send_text(self, text: str):
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
|
|
4
4
|
__author__ = "chuchur/chuchur.com"
|
|
5
5
|
|
|
6
|
-
import hashlib, hmac, time, base64
|
|
7
|
-
|
|
6
|
+
import hashlib, hmac, time, base64
|
|
7
|
+
from curl_cffi import requests as http
|
|
8
|
+
from ..logging import print_error,print_info
|
|
8
9
|
|
|
9
10
|
class Client(object):
|
|
10
11
|
def __init__(self, **kw):
|
|
@@ -14,7 +15,7 @@ class Client(object):
|
|
|
14
15
|
def _get_sign(self):
|
|
15
16
|
secret = self._secret
|
|
16
17
|
if not secret:
|
|
17
|
-
|
|
18
|
+
print_error("缺少secret")
|
|
18
19
|
return None, None
|
|
19
20
|
# 拼接timestamp和secret
|
|
20
21
|
timestamp = int(time.time())
|
|
@@ -35,7 +36,7 @@ class Client(object):
|
|
|
35
36
|
"""
|
|
36
37
|
webhook = self._webhook
|
|
37
38
|
if not webhook:
|
|
38
|
-
|
|
39
|
+
print_error("缺少webhook")
|
|
39
40
|
return False
|
|
40
41
|
timestamp, sign = self._get_sign()
|
|
41
42
|
if not timestamp or not sign:
|
|
@@ -47,10 +48,10 @@ class Client(object):
|
|
|
47
48
|
if result:
|
|
48
49
|
res = result.json()
|
|
49
50
|
if res["StatusCode"] == 0:
|
|
50
|
-
|
|
51
|
+
print_info("发送成功")
|
|
51
52
|
return False
|
|
52
53
|
else:
|
|
53
|
-
|
|
54
|
+
print_error("发送失败!")
|
|
54
55
|
return True
|
|
55
56
|
|
|
56
57
|
def send_text(self, text: str):
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import enum
|
|
2
2
|
import os
|
|
3
3
|
import re
|
|
4
|
-
from ..logging import print_info,
|
|
4
|
+
from ..logging import print_info, print_warn
|
|
5
5
|
import importlib
|
|
6
6
|
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ async def create_model(pool, table_name) -> str:
|
|
|
19
19
|
Create table
|
|
20
20
|
:params table name
|
|
21
21
|
"""
|
|
22
|
-
|
|
22
|
+
print_info(f"create model from {table_name}")
|
|
23
23
|
# rows = await pool.all(f"show full COLUMNS from `{table_name}`", None)
|
|
24
24
|
rows = await get_table_cols(pool, table_name)
|
|
25
25
|
# print(rows)
|
|
@@ -133,7 +133,7 @@ async def create_table(pool, models: list, tables: list = None):
|
|
|
133
133
|
continue
|
|
134
134
|
|
|
135
135
|
if tb.startswith("v_"):
|
|
136
|
-
|
|
136
|
+
print_warn(f"{tb} look like a view so skip.")
|
|
137
137
|
continue
|
|
138
138
|
|
|
139
139
|
# sql = f"DROP TABLE IF EXISTS `{tb}`;\n"
|
|
@@ -246,7 +246,7 @@ def get_col_sql(field):
|
|
|
246
246
|
)
|
|
247
247
|
# else:
|
|
248
248
|
# sql += " DEFAULT NULL"
|
|
249
|
-
print(field.name, field.update_generated)
|
|
249
|
+
# print(field.name, field.update_generated)
|
|
250
250
|
if field.update_generated:
|
|
251
251
|
sql += " ON UPDATE " + (
|
|
252
252
|
field.default if "(" in field.default else f"'{field.default}'"
|
|
@@ -8,7 +8,7 @@ import sys
|
|
|
8
8
|
from contextlib import suppress
|
|
9
9
|
from multiprocessing import Process
|
|
10
10
|
from watchfiles import awatch, DefaultFilter
|
|
11
|
-
from ..logging import
|
|
11
|
+
from ..logging import print_info, print_warn
|
|
12
12
|
import contextlib
|
|
13
13
|
from typing import Any, Iterator, Optional, NoReturn
|
|
14
14
|
from typing import TYPE_CHECKING, Optional, Sequence, Union
|
|
@@ -83,7 +83,7 @@ def mian_app(tty_path, config, entry):
|
|
|
83
83
|
except KeyboardInterrupt:
|
|
84
84
|
pass
|
|
85
85
|
finally:
|
|
86
|
-
with
|
|
86
|
+
with suppress(asyncio.TimeoutError, KeyboardInterrupt):
|
|
87
87
|
runner.run(app_runner.cleanup())
|
|
88
88
|
else:
|
|
89
89
|
loop = asyncio.new_event_loop()
|
|
@@ -96,7 +96,7 @@ def mian_app(tty_path, config, entry):
|
|
|
96
96
|
except KeyboardInterrupt:
|
|
97
97
|
pass
|
|
98
98
|
finally:
|
|
99
|
-
with
|
|
99
|
+
with suppress(asyncio.TimeoutError, KeyboardInterrupt):
|
|
100
100
|
loop.run_until_complete(runner.cleanup())
|
|
101
101
|
|
|
102
102
|
|
|
@@ -128,7 +128,7 @@ class AppTask(WatchTask):
|
|
|
128
128
|
async for changes in self._awatch:
|
|
129
129
|
self._reloads += 1
|
|
130
130
|
if any(f.endswith(".py") for _, f in changes):
|
|
131
|
-
|
|
131
|
+
print_info(f"{len(changes)} changes, restarting server")
|
|
132
132
|
await self._stop_dev_server()
|
|
133
133
|
self._start_dev_server()
|
|
134
134
|
await asyncio.sleep(1)
|
|
@@ -138,7 +138,10 @@ class AppTask(WatchTask):
|
|
|
138
138
|
|
|
139
139
|
def _start_dev_server(self) -> None:
|
|
140
140
|
act = "Start" if self._reloads == 0 else "Restart"
|
|
141
|
-
|
|
141
|
+
print_info(f"{act}ing dev server")
|
|
142
|
+
print_info(
|
|
143
|
+
f"Server Running on http://{self._config['server']['host']}:{self._config['server']['port']}"
|
|
144
|
+
)
|
|
142
145
|
|
|
143
146
|
try:
|
|
144
147
|
tty_path = os.ttyname(sys.stdin.fileno())
|
|
@@ -156,19 +159,19 @@ class AppTask(WatchTask):
|
|
|
156
159
|
|
|
157
160
|
async def _stop_dev_server(self) -> None:
|
|
158
161
|
if self._process.is_alive():
|
|
159
|
-
|
|
162
|
+
print_info("stopping server process...")
|
|
160
163
|
if self._process.pid:
|
|
161
|
-
|
|
164
|
+
print_info("sending SIGINT")
|
|
162
165
|
os.kill(self._process.pid, signal.SIGINT)
|
|
163
166
|
self._process.join(5)
|
|
164
167
|
if self._process.exitcode is None:
|
|
165
|
-
|
|
168
|
+
print_warn("process has not terminated, sending SIGKILL")
|
|
166
169
|
self._process.kill()
|
|
167
170
|
self._process.join(1)
|
|
168
171
|
else:
|
|
169
|
-
|
|
172
|
+
print_info("process stopped")
|
|
170
173
|
else:
|
|
171
|
-
|
|
174
|
+
print_warn(
|
|
172
175
|
"server process already dead, exit code: %s", self._process.exitcode
|
|
173
176
|
)
|
|
174
177
|
|
|
@@ -30,7 +30,7 @@ from setuptools import find_packages
|
|
|
30
30
|
from .settings import get_config
|
|
31
31
|
import aiomcache
|
|
32
32
|
from redis import asyncio as aioredis
|
|
33
|
-
from ..logging import
|
|
33
|
+
from ..logging import print_warn, print_info
|
|
34
34
|
from ..orm.model import Model
|
|
35
35
|
from . import jwt
|
|
36
36
|
from decimal import Decimal
|
|
@@ -125,7 +125,7 @@ def _get_modules(fd):
|
|
|
125
125
|
modules = set()
|
|
126
126
|
temp = os.path.join(os.path.abspath("."), fd)
|
|
127
127
|
if not os.path.exists(temp):
|
|
128
|
-
|
|
128
|
+
print_info("Routers not detected")
|
|
129
129
|
return modules
|
|
130
130
|
s = find_packages(temp)
|
|
131
131
|
for pkg in s:
|
|
@@ -156,7 +156,7 @@ async def check_port_open(port: int, delay: float = 1) -> None:
|
|
|
156
156
|
except OSError as e:
|
|
157
157
|
if e.errno != EADDRINUSE:
|
|
158
158
|
raise
|
|
159
|
-
|
|
159
|
+
print_warn("port %d is already in use, waiting %d...", port, i)
|
|
160
160
|
await asyncio.sleep(delay)
|
|
161
161
|
else:
|
|
162
162
|
server.close()
|
|
@@ -170,7 +170,7 @@ def _reg_middleware():
|
|
|
170
170
|
mid_dir = os.path.join(os.path.abspath("."), root)
|
|
171
171
|
# print(mid_dir)
|
|
172
172
|
if not os.path.exists(mid_dir):
|
|
173
|
-
|
|
173
|
+
print_info("Middlewares not detected")
|
|
174
174
|
return
|
|
175
175
|
for f in os.listdir(mid_dir):
|
|
176
176
|
if not f.startswith("__"):
|
|
@@ -191,6 +191,7 @@ class Application(object):
|
|
|
191
191
|
self._route_table = web.RouteTableDef()
|
|
192
192
|
self._middleware = []
|
|
193
193
|
self.config = {}
|
|
194
|
+
self.clean_up = False
|
|
194
195
|
# self.args = Object()
|
|
195
196
|
|
|
196
197
|
def _load_life_cycle(self, entry_model=None):
|
|
@@ -205,7 +206,7 @@ class Application(object):
|
|
|
205
206
|
cy = getattr(self, cycle)
|
|
206
207
|
cy.append(getattr(entry, cycle))
|
|
207
208
|
except ImportError:
|
|
208
|
-
|
|
209
|
+
print_warn(f"Entry model:{entry_model} can not find.")
|
|
209
210
|
|
|
210
211
|
def init_parse(self):
|
|
211
212
|
try:
|
|
@@ -267,7 +268,7 @@ class Application(object):
|
|
|
267
268
|
if conf_st:
|
|
268
269
|
temp = os.path.join(os.path.abspath("."), "static")
|
|
269
270
|
self.app.router.add_static(**conf_st, path=temp)
|
|
270
|
-
|
|
271
|
+
print_warn("Suggest using nginx or others instead.")
|
|
271
272
|
|
|
272
273
|
temp = os.path.join(os.path.abspath("."), "templates")
|
|
273
274
|
if os.path.exists(temp):
|
|
@@ -289,15 +290,15 @@ class Application(object):
|
|
|
289
290
|
self.clean_up = True
|
|
290
291
|
|
|
291
292
|
for db in apps.db:
|
|
292
|
-
|
|
293
|
+
print_info(f"release database {db}.")
|
|
293
294
|
await apps.db[db].close()
|
|
294
295
|
|
|
295
296
|
# close for session
|
|
296
297
|
if "redis" in apps:
|
|
297
|
-
|
|
298
|
+
print_info(f"release redis session.")
|
|
298
299
|
await apps.redis.close()
|
|
299
300
|
if "memcached" in apps:
|
|
300
|
-
|
|
301
|
+
print_info(f"release memcached session")
|
|
301
302
|
apps.memcached.close()
|
|
302
303
|
|
|
303
304
|
async def _init_database(self, apps):
|
|
@@ -336,7 +337,7 @@ class Application(object):
|
|
|
336
337
|
secure=secure,
|
|
337
338
|
)
|
|
338
339
|
setup(apps, storage)
|
|
339
|
-
|
|
340
|
+
print_info("start redis session.")
|
|
340
341
|
elif mcache_conf:
|
|
341
342
|
host = mcache_conf.get("host")
|
|
342
343
|
port = mcache_conf.get("port", 11211)
|
|
@@ -351,7 +352,7 @@ class Application(object):
|
|
|
351
352
|
secure=secure,
|
|
352
353
|
)
|
|
353
354
|
setup(apps, storage)
|
|
354
|
-
|
|
355
|
+
print_info("start memcached session.")
|
|
355
356
|
else:
|
|
356
357
|
dig = hashlib.sha256(cookie_name.encode()).digest()
|
|
357
358
|
fernet_key = base64.urlsafe_b64encode(dig)
|
|
@@ -367,7 +368,7 @@ class Application(object):
|
|
|
367
368
|
httponly=httponly,
|
|
368
369
|
)
|
|
369
370
|
setup(apps, storage)
|
|
370
|
-
|
|
371
|
+
print_info("start local cookie.")
|
|
371
372
|
|
|
372
373
|
def _reg_router(self):
|
|
373
374
|
fd = "controllers"
|
|
@@ -386,15 +387,15 @@ class Application(object):
|
|
|
386
387
|
:params prot default 9001
|
|
387
388
|
:params host default 127.0.0.1
|
|
388
389
|
"""
|
|
389
|
-
defaults = {"host": "
|
|
390
|
+
defaults = {"host": "0.0.0.0", "port": 9001, "path": None}
|
|
390
391
|
conf = self.config.get("server", {})
|
|
391
392
|
# args_conf = {"host": self.args.host, "port": self.args.port}
|
|
392
393
|
# print(conf)
|
|
393
394
|
conf = chainMap(defaults, conf, kw)
|
|
394
395
|
# print(conf)
|
|
395
396
|
# check_port_open(conf["host"], conf["port"])
|
|
396
|
-
|
|
397
|
-
|
|
397
|
+
print_info(f"Server running on http://{conf['host']}:{conf['port']}")
|
|
398
|
+
print_info("(Press CTRL+C to quit)")
|
|
398
399
|
web.run_app(
|
|
399
400
|
self.app,
|
|
400
401
|
loop=self._loop,
|
|
@@ -408,7 +409,7 @@ class Application(object):
|
|
|
408
409
|
# if self.loop is None:
|
|
409
410
|
# return web.run_app(self.app, host=host, port=port, **kw)
|
|
410
411
|
# else:
|
|
411
|
-
#
|
|
412
|
+
# print_info(f"Server run at http://{host}:{port}")
|
|
412
413
|
# return self.loop.create_server(
|
|
413
414
|
# self.app.make_handler(), host=host, port=port, **kw
|
|
414
415
|
# )
|
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
__author__ = "chuchur/chuchur.com"
|
|
5
5
|
|
|
6
|
-
import requests
|
|
6
|
+
from curl_cffi import requests
|
|
7
7
|
import time
|
|
8
|
-
|
|
9
|
-
from
|
|
8
|
+
|
|
9
|
+
# from requests import Response
|
|
10
|
+
from ..logging import print_error, print_info
|
|
10
11
|
|
|
11
12
|
PROXIES = {
|
|
12
13
|
"http": "http://127.0.0.1:7890",
|
|
@@ -53,7 +54,7 @@ class Client(object):
|
|
|
53
54
|
while try_times > 0:
|
|
54
55
|
try:
|
|
55
56
|
fun = getattr(self.session, method, None)
|
|
56
|
-
result: Response = fun(url, **kw)
|
|
57
|
+
result: requests.Response = fun(url, **kw)
|
|
57
58
|
head = result.headers
|
|
58
59
|
ctype = head["Content-Type"]
|
|
59
60
|
if result.status_code == 200:
|
|
@@ -64,15 +65,15 @@ class Client(object):
|
|
|
64
65
|
return result.text
|
|
65
66
|
return result
|
|
66
67
|
else:
|
|
67
|
-
|
|
68
|
-
|
|
68
|
+
print_info(result.json())
|
|
69
|
+
print_error(f"Error : code ->{result.status_code},try gain....")
|
|
69
70
|
try_times -= 1
|
|
70
71
|
time.sleep(2)
|
|
71
72
|
except BaseException as e:
|
|
72
|
-
|
|
73
|
+
print_error(e)
|
|
73
74
|
try_times -= 1
|
|
74
75
|
time.sleep(2)
|
|
75
|
-
#
|
|
76
|
+
# print_info(e)
|
|
76
77
|
return result
|
|
77
78
|
|
|
78
79
|
|
|
@@ -125,14 +126,14 @@ def download(url, savepath=None, **kw):
|
|
|
125
126
|
if not savepath:
|
|
126
127
|
return rb.content
|
|
127
128
|
if not rb:
|
|
128
|
-
|
|
129
|
+
print_error("下载出错")
|
|
129
130
|
return False
|
|
130
131
|
else:
|
|
131
132
|
try:
|
|
132
133
|
with open(savepath, "wb") as f:
|
|
133
134
|
f.write(rb.content)
|
|
134
|
-
|
|
135
|
+
print_info("下载完成!")
|
|
135
136
|
except BaseException as e:
|
|
136
|
-
|
|
137
|
+
print_error(e)
|
|
137
138
|
return False
|
|
138
139
|
return True
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
__author__ = "chuchur/chuchur.com"
|
|
5
5
|
|
|
6
6
|
import jwt, datetime
|
|
7
|
-
from ..logging import
|
|
7
|
+
from ..logging import print_error
|
|
8
8
|
from typing import Union
|
|
9
9
|
|
|
10
10
|
def encode(payload, key, exp: Union[int, str] = 3600)->str:
|
|
@@ -36,5 +36,5 @@ def decode(token, key):
|
|
|
36
36
|
return None
|
|
37
37
|
return payload # 返回自定义内容
|
|
38
38
|
except Exception as e:
|
|
39
|
-
|
|
39
|
+
print_error(e)
|
|
40
40
|
return None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import yaml
|
|
2
2
|
import os
|
|
3
|
-
from ..logging import
|
|
3
|
+
from ..logging import print_error, print_info
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
def get_config(env):
|
|
@@ -9,7 +9,7 @@ def get_config(env):
|
|
|
9
9
|
conf_path = os.path.join(os.path.abspath("."), "config", f"conf.{env}.yaml")
|
|
10
10
|
print_info(f"loading config {conf_path}")
|
|
11
11
|
if not os.path.exists(conf_path):
|
|
12
|
-
|
|
12
|
+
print_error(f"Configuration file does not exist: {conf_path}")
|
|
13
13
|
return {}
|
|
14
14
|
with open(conf_path) as f:
|
|
15
15
|
config = yaml.safe_load(f)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.2.9"
|
|
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
|