diff --git a/.gitignore b/.gitignore
index 2e9777372bd4eead102db1a21306fffb2e3ee2dd..07a441fbe19e202cfca1f885e327f3fbf936275f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,7 @@
-#以下文件不允许提交到git
-__pycache__
-.settings
-.buildpath
-.project
-*.log
-*.pyc
-*log/
/.idea
/.vscode
+*.log
+.env
/dist
/kcweb.egg-info
-/file
-/utill/Queues
-/utill/db/sqlitedata/kcwlicuxweb
\ No newline at end of file
+/build
\ No newline at end of file
diff --git a/README.md b/README.md
index a926debd3e5c4705b93fdf3c95226a8ff08b14ae..558298cb7e9ffd279f5ed402ada366c9da209c51 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,11 @@
+python -m build
+twine upload dist/*
-
kcweb==4.13.26框架简要说明
+ kcweb框架简要说明
kcweb作为web开发而设计的高性能框架,采用全新的架构思想,注重易用性。遵循MIT开源许可协议发布,意味着个人和企业可以免费使用kcweb,甚至允许把你基于kcweb开发的应用开源或商业产品发布或销售。
-[官方完整文档](https://intapp.kwebapp.cn/intapp/doc/index/finddoc/1/49/1 "官方文档")
+[官方完整文档](https://intapp.kwebapp.cn/intapp/doc/index/finddoc/1/50/1 "官方文档")
------------
diff --git a/Events.py b/kcweb/Events.py
similarity index 48%
rename from Events.py
rename to kcweb/Events.py
index 1cba5fb57344ce80b8afe64190b1c19d94b8d682..a5420a0d51e707c73e8b226a661f50ccea58663d 100644
--- a/Events.py
+++ b/kcweb/Events.py
@@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
-import os, sys, time, subprocess,signal
+import os, time, subprocess,psutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
-eventgtimexz=0
class MyFileSystemEventHander(FileSystemEventHandler):
+ __eventgtimexz=0
def __init__(self, fn):
super(MyFileSystemEventHander, self).__init__()
self.restart = fn
@@ -11,40 +11,54 @@ class MyFileSystemEventHander(FileSystemEventHandler):
def on_any_event(self, event):
if '.py' in event.src_path and event.src_path.endswith('.py'):
global eventgtimexz
- if time.time()-eventgtimexz > 3:
- eventgtimexz=time.time()
- # print('* 更新文件:%s' % event.src_path)
- # time.sleep(10)
- time.sleep(0.2)
- self.restart()
+ if time.time()-self.__eventgtimexz > 0.5:
+ self.__eventgtimexz=time.time()
+ # print('* 更新文件:%s' % event.src_path,event.event_type)
+ if event.event_type=='modified':
+ if 'controller\__init__.py' in event.src_path or 'app\__init__.py' in event.src_path:
+ time.sleep(10)
+ pass
+ else:
+ self.restart()
class Events:
command = ['echo', 'ok']
process = None
def __init__(self,argv):
- if '--server' not in argv and 'python' not in argv[0] or 'kcw.py' in argv:
- argv.insert(0, 'python')
+ # print('event1',argv)
+ # if ('--server' not in argv and 'python' not in argv[0]) or 'kcw.py' in argv:
+ # print('event2',argv)
+ # argv.insert(0, 'python')
self.command = argv
paths = os.path.abspath('.')
- self.start_watch(paths, None)
-
+ # print(paths)
+ self.start_watch(paths)
+
def kill_process(self):
"关闭"
if self.process:
- self.process.kill()
- self.process.wait()
+ if 'kcweb'==self.command[0] or 'kcwebplus'==self.command[0]:
+ try:
+ process = psutil.Process(self.process.pid)
+ except:pass
+ else:
+ for proc in process.children(recursive=True):
+ proc.kill()
+ proc.kill()
+ else:
+ self.process.kill()
+ self.process.wait()
self.process = None
-
def start_process(self):
"启动"
- self.process = subprocess.Popen(self.command, stdin=sys.stdin, stdout=sys.stdout, stderr=sys.stderr)
-
+ self.process = subprocess.Popen(self.command)
def restart_process(self):
"重启"
+
self.kill_process()
time.sleep(0.1)
self.start_process()
- def start_watch(self,path, callback):
+ def start_watch(self,path):
"执行"
observer = Observer()
observer.schedule(MyFileSystemEventHander(self.restart_process), path, recursive=True)
@@ -53,7 +67,7 @@ class Events:
try:
while True:
time.sleep(0.1)
- except KeyboardInterrupt:
+ except KeyboardInterrupt as e:
self.kill_process()
# observer.stop()
# observer.join()
diff --git a/kcweb/LICENSE b/kcweb/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..e57e69a5be5508ee28532f589e3e30fb5eb69066
--- /dev/null
+++ b/kcweb/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 冯树坤
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/__init__.py b/kcweb/__init__.py
similarity index 100%
rename from __init__.py
rename to kcweb/__init__.py
diff --git a/kcweb/__pycache__/Events.cpython-36.pyc b/kcweb/__pycache__/Events.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ccc76ffab75d8ed83f5660b71f32a0d596ebeb72
Binary files /dev/null and b/kcweb/__pycache__/Events.cpython-36.pyc differ
diff --git a/kcweb/__pycache__/__init__.cpython-36.pyc b/kcweb/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..47ed36b08747158cc0dcbe41e105bf80f7f8f897
Binary files /dev/null and b/kcweb/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/__pycache__/app.cpython-36.pyc b/kcweb/__pycache__/app.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0572d1852d8ccaca74f76f09d5847047854758af
Binary files /dev/null and b/kcweb/__pycache__/app.cpython-36.pyc differ
diff --git a/kcweb/__pycache__/kcweb.cpython-36.pyc b/kcweb/__pycache__/kcweb.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3cfcc3fd5c2a20f26f206a27679fb0f4304e320a
Binary files /dev/null and b/kcweb/__pycache__/kcweb.cpython-36.pyc differ
diff --git a/app.py b/kcweb/app.py
similarity index 63%
rename from app.py
rename to kcweb/app.py
index 3649151109d040b66de3215fef110e445206bd82..ce9d36d598420dfb569a96cff8413812648ab9bc 100644
--- a/app.py
+++ b/kcweb/app.py
@@ -1,24 +1,28 @@
# -*- coding: utf-8 -*-
-import socket,time,re,os,sys,traceback,threading,urllib,cgi
-from . Events import Events
+import re,os,sys,traceback,threading,urllib,cgi
+from wsgiref.simple_server import make_server
from . common import *
from . import config
from mako.template import Template
from datetime import datetime
-from threading import local
from .utill import filetype
-from kcweb.utill.cache import cache as kcwcache
-from wsgiref.simple_server import make_server
-from kcweb.utill.db import mysql as kcwmysql
-from kcweb.utill.db import sqlite as kcwsqlite
+# import socket,time
+# from threading import local
+# from kcweb.utill.cache import cache as kcwcache
+# from utill.db import mysql as kcwmysql
+# from kcweb.utill.db import sqlite as kcwsqlite
class web:
__name=None
__appname=None
__config=config
+ __httpd=None
def __new__(self,name,appname=None):
self.__name=name
self.__appname=appname
- if self.__name != '__main__':
+ if self.__name == '__main__' or self.__name=='kcweb.kcweb' or self.__name=='kcwebplus.kcwebplus':
+ # print("web__new__",self.__name)
+ return super().__new__(self)
+ else:
def apps(env, start_response):
p=(config.app['staticpath']+env['RAW_URI'].replace(' ',''))
status='200 ok'
@@ -86,8 +90,9 @@ class web:
start_response(status,resheader)
return [body]
return apps
- else:
- return super().__new__(self)
+ __host=''
+ __port=''
+ __filename=''
def run(self,host="127.0.0.1",port="39001",name=None):
"""运行开发环境
@@ -95,78 +100,107 @@ class web:
port: 端口
- name: python命令行解释机名字
+ name: python命令行解释机名字 (该参数即将废弃)
"""
- if 'eventlog' in sys.argv or len(sys.argv)==1:
- filename=sys.argv[0][:-3]
+ self.__host=host
+ self.__port=port
+
+ cmd=sys.argv
+ config.app['cli']=False
+ if 'eventlog' in cmd or len(cmd)==1 or (len(cmd)>=2 and cmd[len(cmd)-1]=='server'):
+ # config.app['cli']=False
+ if 'kcwebplus' in cmd[0]: #基于新版本4.13.32之后 kcwebplus server运行
+ cmd[0]='kcwebplus'
+ filename=cmd[0]
+ elif 'kcweb' in cmd[0]: #基于新版本4.13.32之后 kcweb server运行
+ cmd[0]='kcweb'
+ filename=cmd[0]
+ else: #基于老版本4.13.32之前 python server.py运行
+ filename=cmd[0][:-3]
+ self.__filename=filename
if self.__config.app['app_debug']:
- arg=sys.argv
- if 'eventlog' in arg:
+ if 'eventlog' in cmd:
self.__impl(host=host,port=port,filename=filename)
else:
if name:
- arg.insert(0,name)
- arg.append('eventlog')
- Events(arg)
+ cmd.insert(0,name)
+ cmd.append('eventlog')
+ from . Events import Events
+ Events(cmd)
else:
- self.__impl(
- host=host,
- port=port,
- filename=filename
- )
+ self.__impl(host=host,port=port,filename=filename)
elif len(sys.argv)==3 and sys.argv[2]=='--cli':
try:
RAW_URI=sys.argv[1]
except:pass
else:
- PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
- if PATH_INFO[0]=='/':
- PATH_INFO=PATH_INFO[1:]
- QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
- reqheader={
- 'REQUEST_METHOD':'GET',
- 'RAW_URI':RAW_URI,
- 'PATH_INFO':PATH_INFO,
- 'QUERY_STRING':QUERY_STRING,
- 'SERVER_PROTOCOL':'',
- 'HTTP_HOST':'',
- 'HTTP_COOKIE':'',
- 'REMOTE_ADDR':'',
- 'HTTP_X_REAL_IP':'',
- 'HTTP_USER_AGENT':'',
- 'BODY_DATA':''
- }
- status,resheader,body=self.__routes(reqheader)
- if 'body' not in body and 'html' not in body and '<' not in body and '>' not in body:
- print(body)
- exit()
+ self.cli(RAW_URI)
+ def cli(self,RAW_URI):
+ config.app['cli']=True
+ if RAW_URI:
+ PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
+ if PATH_INFO[0]=='/':
+ PATH_INFO=PATH_INFO[1:]
+ else:
+ PATH_INFO=RAW_URI
+ clipidpath=get_folder()+"/pid/"+md5(RAW_URI)+"_cli_pid"
+ pid=''
+ if(config.app['save_cli_pid']):
+ kill_route_cli(RAW_URI)
+ save_route_cli_pid(RAW_URI)
+ QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
+ reqheader={
+ 'REQUEST_METHOD':'GET',
+ 'RAW_URI':RAW_URI,
+ 'PATH_INFO':PATH_INFO,
+ 'QUERY_STRING':QUERY_STRING,
+ 'SERVER_PROTOCOL':'',
+ 'HTTP_HOST':'',
+ 'HTTP_COOKIE':'',
+ 'REMOTE_ADDR':'',
+ 'HTTP_X_REAL_IP':'',
+ 'HTTP_USER_AGENT':'',
+ 'BODY_DATA':''
+ }
+ status,resheader,body=self.__routes(reqheader)
+ print(body)
+ if(config.app['save_cli_pid']) and pid:
+
+ try:
+ os.remove(clipidpath)
+ except:pass
def __impl(self,host,port,filename):
"运行测试服务器"
try:
- if config.app['http_server']=='wsgiref':
- self.__http_wsgi(
- host=host,
- port=port,
- filename=filename
- )
- elif config.app['http_server']=='kcweb':
- self.__http_sever(
- host=host,
- port=port,
- filename=filename
- )
- elif config.app['http_server']=='kcweb_server':
- self.__http_server(
- host=host,
- port=port,
- filename=filename
- )
- else:
- self.__http_wsgi(
- host=host,
- port=port,
- filename=filename
- )
+ # if config.app['http_server']=='wsgiref':
+ # self.__http_wsgi(
+ # host=host,
+ # port=port,
+ # filename=filename
+ # )
+ # elif config.app['http_server']=='kcweb':
+ # self.__http_sever(
+ # host=host,
+ # port=port,
+ # filename=filename
+ # )
+ # elif config.app['http_server']=='kcweb_server':
+ # self.__http_server(
+ # host=host,
+ # port=port,
+ # filename=filename
+ # )
+ # else:
+ # self.__http_wsgi(
+ # host=host,
+ # port=port,
+ # filename=filename
+ # )
+ self.__http_wsgi(
+ host=host,
+ port=port,
+ filename=filename
+ )
except KeyboardInterrupt:
pass
@@ -391,9 +425,9 @@ class web:
except:
globals.HEADER.HTTP_USER_AGENT=None
def __del_globals():
- globals.VAR = local()
- globals.HEADER = local()
- globals.G = local()
+ globals.VAR = threading.local()
+ globals.HEADER = threading.local()
+ globals.G = threading.local()
def __routes(self,header):
body="这是一个http测试服务器"
status="200 ok"
@@ -529,7 +563,12 @@ class web:
data=errms,e=e
)
if not data:
- data=getattr(obj,funct)(*param)
+ try:
+ objclass=getattr(obj,files) #新增
+ except:
+ data=getattr(obj,funct)(*param) #兼容性之前的控制器
+ else:
+ data=getattr(objclass,funct)(*param)
body,status,resheader=web.__tran(
self,data,
status,
@@ -739,249 +778,254 @@ class web:
body=bytes(body, encoding='utf-8')
start_response(status,resheader)
return [body]
+
def __http_wsgi(self,host,port,filename):
"http——wsgi测试服务"
print("* \033[1;31;40m! 警告:\033[0m这是一个wsgiref开发服务器。不要在生产环境中部署使用它")
- print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
- if self.__config.app['app_debug']:
- print('* 调试器:开启')
+ # print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
+ if host=='0.0.0.0':
+ print("\033[32m* (CTRL+单击打开)http://127.0.0.1:"+str(port)+"(按CTRL+C退出)")
else:
- print('* 调试器:已关闭')
- print("* 运行在http://"+host+":"+str(port)+"/ (按CTRL+C退出)")
- httpd = make_server(host, int(port), self.__application)
- httpd.serve_forever()
- def __http_server(self,host,port,filename):
- "http测试服务"
- tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- try:
- tcp_socket.bind((host,int(port)))
- except OSError:
- print("通常每个套接字地址(协议/网络地址/端口)只允许使用一次(按CTRL+C退出)")
+ print("\033[32m* 运行在http://"+host+":"+str(port)+"(按CTRL+C退出)")
+ if self.__config.app['app_debug']:
+ print('\033[37m* 调试器:开启')
else:
- tcp_socket.listen(1024)
- print('! \033[1;31;40m警告:\033[0m这是一个kcweb_server开发服务器。不要在生产环境中部署使用它')
- print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
- if self.__config.app['app_debug']:
- print('* 调试器:开启')
- else:
- print('* 调试器:已关闭')
- print("* 运行在http://"+host+":"+str(port)+"/ (按CTRL+C退出)")
- while True:
- new_tcp_socket,client_info=tcp_socket.accept()
- t=threading.Thread(target=self.__server_client,args=(new_tcp_socket,))
- t.daemon=True
- t.start()
- tcp_socket.close()
- def __server_client(self,new_socket):
- # 处理http的的请求
- data=new_socket.recv(1047576).decode()
- if data:
- datas=data.split("\r\n")
- data1=datas[0]
- #reqsest
- REQUEST_METHOD=data1.split("/")[0].replace(' ','') ##GET
- RAW_URI=re.findall(REQUEST_METHOD+"(.+?) HTTP", data1) #/aa/bb/cc?a=1&b=1
- if RAW_URI:
- RAW_URI=RAW_URI[0]
- else:
- RAW_URI=''
- PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
- QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
- SERVER_PROTOCOL=data1.split(" ")[-1] #HTTP/1.1
- HTTP_HOST=re.findall("Host: (.+?)\r\n", data)#212.129.149.238:39010
- if HTTP_HOST:
- HTTP_HOST=HTTP_HOST[0]
- else:
- HTTP_HOST=''
- HTTP_COOKIE=re.findall("Cookie: (.+?)\r\n", data)#cookie
- if HTTP_COOKIE:
- HTTP_COOKIE=HTTP_COOKIE[0]
- else:
- HTTP_COOKIE=''
- REMOTE_ADDR=''
- HTTP_USER_AGENT=re.findall("User-Agent: (.+?)\r\n", data) #Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
- if HTTP_USER_AGENT:
- HTTP_USER_AGENT=HTTP_USER_AGENT[0]
- else:
- HTTP_USER_AGENT=''
- BODY_DATA=datas[len(datas)-1]
- # print(data)
- #reqsest
- reqheader={
- 'REQUEST_METHOD':REQUEST_METHOD,
- 'RAW_URI':RAW_URI,
- 'PATH_INFO':PATH_INFO,
- 'QUERY_STRING':QUERY_STRING,
- 'SERVER_PROTOCOL':SERVER_PROTOCOL,
- 'HTTP_HOST':HTTP_HOST,
- 'HTTP_COOKIE':HTTP_COOKIE,
- 'REMOTE_ADDR':REMOTE_ADDR,
- 'HTTP_X_REAL_IP':'',
- 'HTTP_USER_AGENT':HTTP_USER_AGENT,
- 'BODY_DATA':BODY_DATA
- }
- p=(config.app['staticpath']+RAW_URI.replace(' ',''))
- # print("目录",p)
- status='200 ok'
- if os.path.isfile(p):
- # print('静态文件',p)
- kind = filetype.guess(p)
- if kind is None:
+ print('\033[37m* 调试器:已关闭')
+ self.__httpd = make_server(host, int(port), self.__application)
+ self.__httpd.serve_forever()
+ # def __server_client(self,new_socket):
+ # # 处理http的的请求
+ # data=new_socket.recv(1047576).decode()
+ # if data:
+ # datas=data.split("\r\n")
+ # data1=datas[0]
+ # #reqsest
+ # REQUEST_METHOD=data1.split("/")[0].replace(' ','') ##GET
+ # RAW_URI=re.findall(REQUEST_METHOD+"(.+?) HTTP", data1) #/aa/bb/cc?a=1&b=1
+ # if RAW_URI:
+ # RAW_URI=RAW_URI[0]
+ # else:
+ # RAW_URI=''
+ # PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
+ # QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
+ # SERVER_PROTOCOL=data1.split(" ")[-1] #HTTP/1.1
+ # HTTP_HOST=re.findall("Host: (.+?)\r\n", data)#212.129.149.238:39010
+ # if HTTP_HOST:
+ # HTTP_HOST=HTTP_HOST[0]
+ # else:
+ # HTTP_HOST=''
+ # HTTP_COOKIE=re.findall("Cookie: (.+?)\r\n", data)#cookie
+ # if HTTP_COOKIE:
+ # HTTP_COOKIE=HTTP_COOKIE[0]
+ # else:
+ # HTTP_COOKIE=''
+ # REMOTE_ADDR=''
+ # HTTP_USER_AGENT=re.findall("User-Agent: (.+?)\r\n", data) #Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
+ # if HTTP_USER_AGENT:
+ # HTTP_USER_AGENT=HTTP_USER_AGENT[0]
+ # else:
+ # HTTP_USER_AGENT=''
+ # BODY_DATA=datas[len(datas)-1]
+ # # print(data)
+ # #reqsest
+ # reqheader={
+ # 'REQUEST_METHOD':REQUEST_METHOD,
+ # 'RAW_URI':RAW_URI,
+ # 'PATH_INFO':PATH_INFO,
+ # 'QUERY_STRING':QUERY_STRING,
+ # 'SERVER_PROTOCOL':SERVER_PROTOCOL,
+ # 'HTTP_HOST':HTTP_HOST,
+ # 'HTTP_COOKIE':HTTP_COOKIE,
+ # 'REMOTE_ADDR':REMOTE_ADDR,
+ # 'HTTP_X_REAL_IP':'',
+ # 'HTTP_USER_AGENT':HTTP_USER_AGENT,
+ # 'BODY_DATA':BODY_DATA
+ # }
+ # p=(config.app['staticpath']+RAW_URI.replace(' ',''))
+ # # print("目录",p)
+ # status='200 ok'
+ # if os.path.isfile(p):
+ # # print('静态文件',p)
+ # kind = filetype.guess(p)
+ # if kind is None:
- f=open(p,"rb")
- body=f.read()
- f.close()
- resheader=[("Cache-Control","public, max-age=43200"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
+ # f=open(p,"rb")
+ # body=f.read()
+ # f.close()
+ # resheader=[("Cache-Control","public, max-age=43200"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
- else:
- f=open(p,"rb")
- body=f.read()
- f.close()
- resheader=[("Content-Type",kind.mime),("Cache-Control","public, max-age=43200"),("Accept-Ranges","bytes"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
- else:
- status,resheader,body=self.__routes(reqheader)
- if type(body) is bytes:
- pass
- else:
- body=body.encode()
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
+ # else:
+ # f=open(p,"rb")
+ # body=f.read()
+ # f.close()
+ # resheader=[("Content-Type",kind.mime),("Cache-Control","public, max-age=43200"),("Accept-Ranges","bytes"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
+ # else:
+ # status,resheader,body=self.__routes(reqheader)
+ # if type(body) is bytes:
+ # pass
+ # else:
+ # body=body.encode()
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
- print(HTTP_HOST+' -- ['+str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))+'] "'+REQUEST_METHOD+" "+RAW_URI +" "+SERVER_PROTOCOL + '" '+status+"-")
- t=time.time()
- header+="Server:kcweb"+str(config.kcweb['version'])+"\n"
- header+="Date:%s\n" % datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
- for t in resheader:
- header+="%s:%s\n" % (t[0],t[1])
- header+="\n"
- try:
- new_socket.send(header.encode())
- new_socket.send(body)
- except Exception as e:
- pass
- new_socket.close()
- def __http_sever(self,host,port,filename):
- #http测试服务器
- print('\033[1;31;40m! 警告:\033[0m这是一个kcweb开发服务器。不要在生产环境中部署使用它')
- print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
- if self.__config.app['app_debug']:
- print('* 调试器:开启')
- else:
- print('* 调试器:已关闭')
- print("* 运行在http://"+host+":"+str(port)+"/ (按CTRL+C退出)")
- tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
- tcp_socket.bind((host,int(port)))
- tcp_socket.listen(1024)
- pack_length=1024
- tcp_socket.setblocking(False)
- tcp_socket_list=list()
- while True:
- try:
- new_tcp_socket,client_info=tcp_socket.accept()
- except:
- pass
- else:
- new_tcp_socket.setblocking(False)
- tcp_socket_list.append(new_tcp_socket)
- for cli_soc in tcp_socket_list:
- try:
- data=cli_soc.recv(pack_length).decode()
- except Exception as e:
- pass
- else:
- if data:
- datas=data.split("\r\n")
- data1=datas[0]
- #reqsest
- REQUEST_METHOD=data1.split("/")[0].replace(' ','') ##GET
- RAW_URI=re.findall(REQUEST_METHOD+"(.+?) HTTP", data1) #/aa/bb/cc?a=1&b=1
- if RAW_URI:
- RAW_URI=RAW_URI[0]
- else:
- RAW_URI=''
- PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
- QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
- SERVER_PROTOCOL=data1.split(" ")[-1] #HTTP/1.1
- HTTP_HOST=re.findall("Host: (.+?)\r\n", data)#212.129.149.238:39010
- if HTTP_HOST:
- HTTP_HOST=HTTP_HOST[0]
- else:
- HTTP_HOST=''
- HTTP_COOKIE=re.findall("Cookie: (.+?)\r\n", data)#cookie
- if HTTP_COOKIE:
- HTTP_COOKIE=HTTP_COOKIE[0]
- else:
- HTTP_COOKIE=''
- REMOTE_ADDR=''
- HTTP_USER_AGENT=re.findall("User-Agent: (.+?)\r\n", data) #Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
- if HTTP_USER_AGENT:
- HTTP_USER_AGENT=HTTP_USER_AGENT[0]
- else:
- HTTP_USER_AGENT=''
- BODY_DATA=datas[len(datas)-1]
- # print(data)
- #reqsest
- reqheader={
- 'REQUEST_METHOD':REQUEST_METHOD,
- 'RAW_URI':RAW_URI,
- 'PATH_INFO':PATH_INFO,
- 'QUERY_STRING':QUERY_STRING,
- 'SERVER_PROTOCOL':SERVER_PROTOCOL,
- 'HTTP_HOST':HTTP_HOST,
- 'HTTP_COOKIE':HTTP_COOKIE,
- 'REMOTE_ADDR':REMOTE_ADDR,
- 'HTTP_X_REAL_IP':'',
- 'HTTP_USER_AGENT':HTTP_USER_AGENT,
- 'BODY_DATA':BODY_DATA
- }
- p=(config.app['staticpath']+RAW_URI.replace(' ',''))
- # print("目录",p)
- status='200 ok'
- if os.path.isfile(p):
- # print('静态文件',p)
- kind = filetype.guess(p)
- if kind is None:
+ # print(HTTP_HOST+' -- ['+str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))+'] "'+REQUEST_METHOD+" "+RAW_URI +" "+SERVER_PROTOCOL + '" '+status+"-")
+ # t=time.time()
+ # header+="Server:kcweb"+str(config.kcweb['version'])+"\n"
+ # header+="Date:%s\n" % datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
+ # for t in resheader:
+ # header+="%s:%s\n" % (t[0],t[1])
+ # header+="\n"
+ # try:
+ # new_socket.send(header.encode())
+ # new_socket.send(body)
+ # except Exception as e:
+ # pass
+ # new_socket.close()
+ # def __http_server(self,host,port,filename):
+ # "http测试服务"
+ # tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+ # try:
+ # tcp_socket.bind((host,int(port)))
+ # except OSError:
+ # print("通常每个套接字地址(协议/网络地址/端口)只允许使用一次(按CTRL+C退出)")
+ # else:
+ # tcp_socket.listen(1024)
+ # print('! \033[1;31;40m警告:\033[0m这是一个kcweb_server开发服务器。不要在生产环境中部署使用它')
+ # print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
+ # if self.__config.app['app_debug']:
+ # print('* 调试器:开启')
+ # else:
+ # print('* 调试器:已关闭')
+ # print("* 运行在http://"+host+":"+str(port)+"/ (按CTRL+C退出)")
+ # while True:
+ # new_tcp_socket,client_info=tcp_socket.accept()
+ # t=threading.Thread(target=self.__server_client,args=(new_tcp_socket,))
+ # t.daemon=True
+ # t.start()
+ # tcp_socket.close()
+
+ # def __http_sever(self,host,port,filename):
+ # #http测试服务器
+ # print('\033[1;31;40m! 警告:\033[0m这是一个kcweb开发服务器。不要在生产环境中部署使用它')
+ # print('* 生产环境中建议使用gunicorn,gunicorn运行命令如:gunicorn -b '+host+':'+str(port)+' '+str(filename)+':app')
+ # if self.__config.app['app_debug']:
+ # print('* 调试器:开启')
+ # else:
+ # print('* 调试器:已关闭')
+ # print("* 运行在http://"+host+":"+str(port)+"/ (按CTRL+C退出)")
+ # tcp_socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+ # tcp_socket.bind((host,int(port)))
+ # tcp_socket.listen(1024)
+ # pack_length=1024
+ # tcp_socket.setblocking(False)
+ # tcp_socket_list=list()
+ # while True:
+ # try:
+ # new_tcp_socket,client_info=tcp_socket.accept()
+ # except:
+ # pass
+ # else:
+ # new_tcp_socket.setblocking(False)
+ # tcp_socket_list.append(new_tcp_socket)
+ # for cli_soc in tcp_socket_list:
+ # try:
+ # data=cli_soc.recv(pack_length).decode()
+ # except Exception as e:
+ # pass
+ # else:
+ # if data:
+ # datas=data.split("\r\n")
+ # data1=datas[0]
+ # #reqsest
+ # REQUEST_METHOD=data1.split("/")[0].replace(' ','') ##GET
+ # RAW_URI=re.findall(REQUEST_METHOD+"(.+?) HTTP", data1) #/aa/bb/cc?a=1&b=1
+ # if RAW_URI:
+ # RAW_URI=RAW_URI[0]
+ # else:
+ # RAW_URI=''
+ # PATH_INFO=RAW_URI.split("?")[0] #/aa/bb/cc
+ # QUERY_STRING=RAW_URI.replace(str(PATH_INFO),'').replace('?','') #a=1&b=1
+ # SERVER_PROTOCOL=data1.split(" ")[-1] #HTTP/1.1
+ # HTTP_HOST=re.findall("Host: (.+?)\r\n", data)#212.129.149.238:39010
+ # if HTTP_HOST:
+ # HTTP_HOST=HTTP_HOST[0]
+ # else:
+ # HTTP_HOST=''
+ # HTTP_COOKIE=re.findall("Cookie: (.+?)\r\n", data)#cookie
+ # if HTTP_COOKIE:
+ # HTTP_COOKIE=HTTP_COOKIE[0]
+ # else:
+ # HTTP_COOKIE=''
+ # REMOTE_ADDR=''
+ # HTTP_USER_AGENT=re.findall("User-Agent: (.+?)\r\n", data) #Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
+ # if HTTP_USER_AGENT:
+ # HTTP_USER_AGENT=HTTP_USER_AGENT[0]
+ # else:
+ # HTTP_USER_AGENT=''
+ # BODY_DATA=datas[len(datas)-1]
+ # # print(data)
+ # #reqsest
+ # reqheader={
+ # 'REQUEST_METHOD':REQUEST_METHOD,
+ # 'RAW_URI':RAW_URI,
+ # 'PATH_INFO':PATH_INFO,
+ # 'QUERY_STRING':QUERY_STRING,
+ # 'SERVER_PROTOCOL':SERVER_PROTOCOL,
+ # 'HTTP_HOST':HTTP_HOST,
+ # 'HTTP_COOKIE':HTTP_COOKIE,
+ # 'REMOTE_ADDR':REMOTE_ADDR,
+ # 'HTTP_X_REAL_IP':'',
+ # 'HTTP_USER_AGENT':HTTP_USER_AGENT,
+ # 'BODY_DATA':BODY_DATA
+ # }
+ # p=(config.app['staticpath']+RAW_URI.replace(' ',''))
+ # # print("目录",p)
+ # status='200 ok'
+ # if os.path.isfile(p):
+ # # print('静态文件',p)
+ # kind = filetype.guess(p)
+ # if kind is None:
- f=open(p,"rb")
- body=f.read()
- f.close()
- resheader=[("Cache-Control","public, max-age=43200"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
+ # f=open(p,"rb")
+ # body=f.read()
+ # f.close()
+ # resheader=[("Cache-Control","public, max-age=43200"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
- else:
- f=open(p,"rb")
- body=f.read()
- f.close()
- resheader=[("Content-Type",kind.mime),("Cache-Control","public, max-age=43200"),("Accept-Ranges","bytes"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
- else:
- status,resheader,body=self.__routes(reqheader)
- if type(body) is bytes:
- pass
- else:
- body=body.encode()
- header="HTTP/1.1 %s \n" % status
- header+="Content-Length:%d\n" % len(body)
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
+ # else:
+ # f=open(p,"rb")
+ # body=f.read()
+ # f.close()
+ # resheader=[("Content-Type",kind.mime),("Cache-Control","public, max-age=43200"),("Accept-Ranges","bytes"),("Expires","Thu, 07 Nov 2019 02:59:02 GMT")]
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
+ # else:
+ # status,resheader,body=self.__routes(reqheader)
+ # if type(body) is bytes:
+ # pass
+ # else:
+ # body=body.encode()
+ # header="HTTP/1.1 %s \n" % status
+ # header+="Content-Length:%d\n" % len(body)
- print(HTTP_HOST+' -- ['+str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))+'] "'+REQUEST_METHOD+" "+RAW_URI +" "+SERVER_PROTOCOL + '" '+status+"-")
- t=time.time()
- header+="Server:kcweb"+str(config.kcweb['version'])+"\n"
- header+="Date:%s\n" % datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
- for t in resheader:
- header+="%s:%s\n" % (t[0],t[1])
- header+="\n"
- try:
- cli_soc.send(header.encode())
- cli_soc.send(body)
- except Exception as e:
- cli_soc.close()
- else:
- cli_soc.close()
- tcp_socket_list.remove(cli_soc)
- tcp_socket.close()
+ # print(HTTP_HOST+' -- ['+str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))+'] "'+REQUEST_METHOD+" "+RAW_URI +" "+SERVER_PROTOCOL + '" '+status+"-")
+ # t=time.time()
+ # header+="Server:kcweb"+str(config.kcweb['version'])+"\n"
+ # header+="Date:%s\n" % datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
+ # for t in resheader:
+ # header+="%s:%s\n" % (t[0],t[1])
+ # header+="\n"
+ # try:
+ # cli_soc.send(header.encode())
+ # cli_soc.send(body)
+ # except Exception as e:
+ # cli_soc.close()
+ # else:
+ # cli_soc.close()
+ # tcp_socket_list.remove(cli_soc)
+ # tcp_socket.close()
diff --git a/common/__init__.py b/kcweb/common/__init__.py
similarity index 100%
rename from common/__init__.py
rename to kcweb/common/__init__.py
diff --git a/kcweb/common/__pycache__/__init__.cpython-36.pyc b/kcweb/common/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fa2ee76e3aac1ca93d76c11b74c79cb50b7d8163
Binary files /dev/null and b/kcweb/common/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/common/__pycache__/autoload.cpython-36.pyc b/kcweb/common/__pycache__/autoload.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..951e3c07e85596f7c3bacd4ec7e8d1b7b902417b
Binary files /dev/null and b/kcweb/common/__pycache__/autoload.cpython-36.pyc differ
diff --git a/kcweb/common/__pycache__/globals.cpython-36.pyc b/kcweb/common/__pycache__/globals.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2bcada23753f4c5f2ee903809d193a387a0f3d48
Binary files /dev/null and b/kcweb/common/__pycache__/globals.cpython-36.pyc differ
diff --git a/kcweb/common/__pycache__/request.cpython-36.pyc b/kcweb/common/__pycache__/request.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..02f189ef27bad70aeef88cdc5f923f795469b7a6
Binary files /dev/null and b/kcweb/common/__pycache__/request.cpython-36.pyc differ
diff --git a/kcweb/common/__pycache__/session.cpython-36.pyc b/kcweb/common/__pycache__/session.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..acf2773e0498a19e5d167cd38dafbdc247663d2a
Binary files /dev/null and b/kcweb/common/__pycache__/session.cpython-36.pyc differ
diff --git a/common/autoload.py b/kcweb/common/autoload.py
similarity index 66%
rename from common/autoload.py
rename to kcweb/common/autoload.py
index fb16645905830b41d5dfb5bb2503839b981daf89..e3d078c6e56bc0d6b22e5dbbf4d5bd78c23578b4 100644
--- a/common/autoload.py
+++ b/kcweb/common/autoload.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-import time,hashlib,json,re,os,platform,sys,shutil,requests,importlib,traceback,pip,gzip,tarfile,zipfile,random,copy
+import time,hashlib,json,re,os,platform,sys,shutil,requests,importlib,traceback,pip,gzip,tarfile,zipfile,random,copy,chardet
import datetime as core_datetime
from kcweb import config
from kcweb.utill.dateutil.relativedelta import relativedelta as core_relativedelta
@@ -18,8 +18,11 @@ from email.mime.text import MIMEText
from email.utils import formataddr
from kcweb.utill import filetype
from . import globals
-
-import asyncio,websockets,urllib,threading
+import asyncio,websockets,urllib,threading,psutil,signal
+python_version=platform.python_version()
+if python_version[0:3]!='3.8':
+ print("\033[1;31;40m "+config.kcweb['name']+"-"+config.kcweb['version']+"依赖python3.8,与你现在的python"+python_version+"不兼容,推荐安装python3.8")
+ exit()
class kcwebsocket:
"websocket服务端"
__clientlists=[] #所有客户端绑定的对象
@@ -162,6 +165,18 @@ class kcwebsocket:
return int 返回一个数字
"""
return len(self.__lists)
+ def getGroupCount(self):
+ """获取组数量
+
+ return int 返回一个数字
+ """
+ return len(self.__group)
+ def getGroupname(self):
+ """获取组名称
+
+ return list 返回一列表
+ """
+ return list(self.__group)
async def send_all(self,message):
"给所有人发送消息,包括自己"
for l in self.__clientlists:
@@ -184,30 +199,39 @@ class kcwebsocket:
await self.send_client(clientid,recv_text) #给当前用户发送消息
async def onClose(self,clientid):
"客户端与websocket的连接断开时触发"
+ await self.CloseSocket(self,clientid)
if config.app['app_debug']:
print("onClose",clientid)
- async def __onClose(self,clientid):
- xb=self.__lists.index(clientid)
- del self.__lists[xb]
- del self.__clientlists[xb]
- if self.__uid:
- for uid in self.__uid.keys():
- try:
- self.__uid[uid]
- except KeyError:
- pass
- else:
+ async def CloseSocket(self,clientid):
+ "关闭当前客户端socket"
+ try:
+ xb=self.__lists.index(clientid)
+ except:pass
+ else:
+ del self.__lists[xb]
+ websockets=self.__clientlists[xb]['socket']
+ del self.__clientlists[xb]
+ if self.__uid:
+ for uid in self.__uid.keys():
try:
- self.__uid[uid]['clientid']
+ self.__uid[uid]
except KeyError:
pass
else:
- self.__uid[uid].remove(clientid)
+ try:
+ self.__uid[uid]['clientid']
+ except KeyError:
+ pass
+ else:
+ self.__uid[uid].remove(clientid)
+ await websockets.close()
async def __main2(self,clientid,websocket,path):
"服务器端主逻辑"
- async for message in websocket:
- await self.onMessage(clientid, message)
- await self.__onClose(clientid)
+ try:
+ async for message in websocket:
+ await self.onMessage(clientid, message)
+ except:pass
+ # await self.__onClose(clientid)
await self.onClose(clientid)
async def __main1(self,clientid,websocket,path):
t = urllib.parse.parse_qs(urllib.parse.urlparse(path).query)
@@ -306,6 +330,15 @@ class DFAFilter():
else:
return False
redis=kcwredis()
+def timestampToDate(times,format="%Y-%m-%d %H:%M:%S"):
+ """时间戳转换时间
+
+ times 10位时间戳
+
+ format 日期格式 如%Y-%m-%d %H:%M:%S
+ """
+ timeArray = time.localtime(int(times))
+ return time.strftime(format.encode('unicode-escape').decode(),timeArray).encode().decode('unicode-escape')
def send_mail(user,text="邮件内容",theme="邮件主题",recNick="收件人昵称"):
"""发送邮件
@@ -383,12 +416,23 @@ def Templates(path,**context):
t=lookup.get_template(path)
body=t.render(**context)
return body
-def getfunction(strs):
+def kcwTemp(contents,**context):
+ "模板渲染引擎函数,传字符串进来"
+ lookup = TemplateLookup(directories=[''])
+ t=kcwTemplate(contents,lookup=lookup,module_directory=config.cache['path']+"/Template")
+ body=t.render(**context)
+ return body
+def getfunction(strs,reload=False):
"""获取指定文件对象
strs :app.index.common.autoload 获取app/index/common/目录下的autoload对象
+
+ reload 是否重新加载已导入的模块(是否每次加载修改后的模块)
"""
- return importlib.import_module(strs)
+ obj=importlib.import_module(strs)
+ if reload:
+ importlib.reload(obj)
+ return obj
def mysql(table=None,configss=None):
"""mysql数据库操作实例
@@ -514,7 +558,9 @@ def json_decode(strs):
"""json字符串转python类型"""
try:
return json.loads(strs)
- except Exception:
+ except Exception as e:
+ if 'JSON object must be str, bytes or bytearray, not list' in str(e):
+ return strs
return []
def json_encode(strs):
"""python列表或字典转成字符串"""
@@ -558,7 +604,73 @@ def dateoperator(date,years=0,formats='%Y%m%d%H%M%S',months=0, days=0, hours=0,
def get_folder():
'获取当前框架目录'
return os.path.split(os.path.realpath(__file__))[0][:-7] #当前框架目录
-# aa=[]
+def get_kcweb_cli_pid(route):
+ """通过路由地址获取pid"""
+ if not os.path.isfile(get_folder()+"/pid/"+md5(route)+"_cli_pid"):
+ return False
+ pid=False
+ with open(get_folder()+"/pid/"+md5(route)+"_cli_pid") as file:
+ pid = file.read()
+ return pid
+def get_kcweb_cli_info(route,types='info'):
+ """通过路由地址获取进程信息
+
+ route 路由地址
+
+ types info表示获取进程信息 否则判断进程号是否存在
+ """
+ pid=get_kcweb_cli_pid(route)
+ if pid:
+ pid=int(pid)
+ try:
+ if types=='info':
+ p = psutil.Process(pid)
+ data={
+ 'pid':pid,
+ 'name':p.name(),
+ 'cli':p.cmdline(),
+ 'cpu':p.cpu_percent(1),
+ 'memory':p.memory_info().rss
+ }
+ return data
+ else:
+ if psutil.pid_exists(pid):
+ return pid
+ else:
+ try:
+ os.remove(get_folder()+"/pid/"+md5(route)+"_cli_pid")
+ except:pass
+ return False
+ except:
+ return False
+ else:
+ return False
+def kill_pid(pid):
+ """通过pid结束进程"""
+ if pid:
+ try:
+ os.kill(int(pid), signal.SIGTERM)
+ except:pass
+ # if get_sysinfo()['uname'][0]=='Linux':
+ # os.popen("kill -9 "+str(pid))
+ # elif get_sysinfo()['uname'][0]=='Windows':
+ # os.popen("taskkill /PID "+str(pid)+" /F /T")
+ # else:
+ # raise Exception('不支持该系统')
+def kill_route_cli(route):
+ """通过路由结束进程"""
+ pid=get_kcweb_cli_pid(route)
+ if pid:
+ kill_pid(pid)
+ try:
+ os.remove(get_folder()+"/pid/"+md5(route)+"_cli_pid")
+ except:pass
+def save_route_cli_pid(route):
+ """通过路由保存pid"""
+ pid = os.getpid()
+ f=open(get_folder()+"/pid/"+md5(route)+"_cli_pid",'w')
+ f.write(str(pid))
+ f.close()
def get_file(folder='./',is_folder=True,suffix="*",lists=[],append=False):
"""获取文件夹下所有文件夹和文件
@@ -613,8 +725,83 @@ def list_to_tree(data, pk = 'id', pid = 'pid', child = 'lowerlist', root=0,child
v[child]=kkkk
arr.append(v)
return arr
+def randoms(lens=6,types=1):
+ """生成随机字符串
+
+ lens 长度
-
+ types 1数字 2字母 3字母加数字
+ """
+ strs="0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM,!@#$%^&*()_+=-;',./:<>?"
+ if types==1:
+ strs="0123456789"
+ elif types==2:
+ strs="qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
+ elif types==3:
+ strs="0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM"
+ k=''
+ i=0
+ while i < lens:
+ k+=random.choice(strs)
+ i+=1
+ return k
+def file_set_content(k,data,encoding="utf-8"):
+ f=open(k,'w',encoding=encoding)
+ f.write(data)
+ f.close()
+ return True
+def file_get_content(filename,encoding=False):
+ """获取文件内容
+
+ filename 完整文件名
+
+ encoding 是否返回文件编码 默认否
+ """
+ fileData=''
+ cur_encoding="utf-8"
+ if os.path.isfile(filename):
+ with open(filename, 'rb') as f:
+ cur_encoding = chardet.detect(f.read())['encoding']
+ #用获取的编码读取该文件而不是python3默认的utf-8读取。
+ with open(filename,encoding=cur_encoding) as file:
+ fileData = file.read()
+ if encoding:
+ return fileData,cur_encoding
+ else:
+ return fileData
+class kcwebsign:
+ def getsign(params):
+ "获取签名"
+ if is_index(params,'sign'):
+ del params['sign']
+ content=kcwebsign.getSignContent(params)
+ return md5(content)
+ def exsignpra(params):
+ "生成签名参数"
+ params['time']=times()
+ params['rands']=randoms()
+ params['sign']=kcwebsign.getsign(params)
+ return params
+ def getSignContent(params):
+ "字典排序"
+ param={}
+ for i in sorted (params) :
+ param[i]=params[i]
+ i=0
+ strs=""
+ for k in param:
+ if k:
+ if isinstance(k,dict):
+ k=json_encode(k)
+ k=k.replace('"', '')
+ k=k.replace("'", '')
+ if param[k]:
+ if i==0:
+ strs+=str(k)+"="+str(param[k])
+ else:
+ strs+="&"+str(k)+"="+str(param[k])
+ i+=1
+ return strs
class kcwebzip:
def packzip(src,dst):
"压缩"
@@ -814,9 +1001,9 @@ class response:
header['Content-Type']="image/png"
return body,status,header
def video(body):
- """输出音频
+ """输出视频
- body 音频二进制内容或音频路径
+ body 视频二进制内容或视频路径
"""
status='200 ok'
header={"Cache-Control":"public, max-age=2592000"}
@@ -827,10 +1014,10 @@ class response:
except:
HTTP_IF_NONE_MATCH=None
if(HTTP_IF_NONE_MATCH and get_cache(ETag)):
+ header=get_cache(ETag)
status="304 Not Modified"
body=''
else:
- set_cache(ETag,1,2592000)
filename=body
f=open(filename,"rb")
body=f.read()
@@ -840,6 +1027,8 @@ class response:
header['Content-Type']=kind.mime
except:
header['Content-Type']="video/mp4"
+ header['content-length']=str(len(body))
+ set_cache(ETag,header,2592000)
dateArray = core_datetime.datetime.utcfromtimestamp(times()-86400)
otherStyleTime = dateArray.strftime('%a, %d %b %Y %H:%M:%S GMT')
header['Last-Modified']=otherStyleTime
@@ -847,24 +1036,42 @@ class response:
else:
header['Content-Type']="video/mp4"
return body,status,header
- # def video(body):
- # """输出音频
+ def audio(body):
+ """输出音频
- # body 音频二进制内容或音频路径
- # """
- # if isinstance(body,str):
- # filename=body
- # f=open(filename,"rb")
- # body=f.read()
- # f.close()
- # kind = filetype.guess(filename)
- # try:
- # ContentType=kind.mime
- # except:
- # ContentType="video/mp4"
- # else:
- # ContentType="video/mp4"
- # return body,'200 ok',{"Content-Type":ContentType,"Cache-Control":"public, max-age=600"}
+ body 音频二进制内容或音频路径
+ """
+ status='200 ok'
+ header={"Cache-Control":"public, max-age=2592000"}
+ if isinstance(body,str):
+ ETag=md5(body)
+ try:
+ HTTP_IF_NONE_MATCH=globals.HEADER.GET['HTTP_IF_NONE_MATCH']
+ except:
+ HTTP_IF_NONE_MATCH=None
+ if(HTTP_IF_NONE_MATCH and get_cache(ETag)):
+ header=get_cache(ETag)
+ status="304 Not Modified"
+ body=''
+ else:
+ filename=body
+ f=open(filename,"rb")
+ body=f.read()
+ f.close()
+ kind = filetype.guess(filename)
+ try:
+ header['Content-Type']=kind.mime
+ except:
+ header['Content-Type']="audio/mpeg"
+ header['content-length']=str(len(body))
+ set_cache(ETag,header,2592000)
+ dateArray = core_datetime.datetime.utcfromtimestamp(times()-86400)
+ otherStyleTime = dateArray.strftime('%a, %d %b %Y %H:%M:%S GMT')
+ header['Last-Modified']=otherStyleTime
+ header['ETag']=ETag
+ else:
+ header['Content-Type']="audio/mpeg"
+ return body,status,header
def download(pathname):
"""下载文件
@@ -895,26 +1102,34 @@ class response:
header['Location']=url
return html,status,header
class create:
+ project=''
appname=None
modular=None
path=get_folder() #当前框架目录
- def __init__(self,appname="app",modular="api"):
+ def __init__(self,appname="app",modular="api",project=''):
self.appname=str(appname)
self.modular=str(modular)
+ if project:
+ if os.path.exists(project):
+ print('项目已存在,请进入'+str(project)+'目录命令执行命令')
+ exit()
+ if not os.path.exists(self.appname):
+ self.project=str(project)+'/'
+ os.makedirs(self.project, exist_ok=True)
def uninstallplug(self,plug):
"""卸载插件
plug 插件名
"""
- f=open(self.appname+"/"+self.modular+"/controller/__init__.py","r",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/__init__.py","r",encoding='utf-8')
text=f.read()
f.close()
text=re.sub("\nfrom . import "+plug,"",text)
text=re.sub("from . import "+plug,"",text)
- f=open(self.appname+"/"+self.modular+"/controller/__init__.py","w",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/__init__.py","w",encoding='utf-8')
f.write(text)
f.close()
- shutil.rmtree(self.appname+"/"+self.modular+"/controller/"+plug)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular+"/controller/"+plug)
return True,"成功"
def packplug(self,plug):
"""打包插件
@@ -922,18 +1137,19 @@ class create:
plug 插件名
"""
"""打包模块"""
- if os.path.exists(self.appname+"/"+self.modular+"/controller/"+plug):
- kcwebzip.packzip(self.appname+"/"+self.modular+"/controller/"+plug,self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ if os.path.exists(self.project+self.appname+"/"+self.modular+"/controller/"+plug):
+ kcwebzip.packzip(self.project+self.appname+"/"+self.modular+"/controller/"+plug,self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return True,"成功"
else:
return False,"失败"
- def uploadplug(self,plug,username='',password='',cli=False):
+ def uploadplug(self,plug,username='',password='',cli=False,relyonlist=[]):
"上传一个插件"
- if not os.path.isfile(self.appname+"/"+self.modular+"/controller/"+plug+".zip"):
+ if not os.path.isfile(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip"):
self.packplug(plug=plug)
i=0
http=Http()
http.set_timeout=300
+ relyonlist=json_encode(relyonlist)
while True:
timestamp=times()
sign=md5(str(username)+str(timestamp)+md5(md5(password)))
@@ -943,13 +1159,13 @@ class create:
http.openurl(config.domain['kcwebapi']+"/user/userinfo/?username="+username+"×tamp="+str(timestamp)+"&sign="+sign)
arr=json_decode(http.get_text)
if not arr:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
if config.app['app_debug']:
print(http.get_text)
return False,"用户身份验证失败,服务器暂时无法处理"
if (arr['code']==-1 or arr['code']==2) and cli:
if i >= 3:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return False,"用户名或密码错误"
elif i:
print("用户名或密码错误,请重新输入")
@@ -962,36 +1178,36 @@ class create:
elif arr['code']==0:
break
else:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return False,arr['msg']
http.openurl(config.domain['kcwebapi']+"/user/uploadplug/?username="+username+"×tamp="+str(timestamp)+"&sign="+sign,'POST',
- data={'name':str(plug),'describes':'','modular':self.modular},
- files={'file':open(self.appname+"/"+self.modular+"/controller/"+plug+".zip", 'rb')})
+ data={'name':str(plug),'describes':'','modular':self.modular,'relyonlist':relyonlist},
+ files={'file':open(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip", 'rb')})
arr=json_decode(http.get_text)
if not arr:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
if config.app['app_debug']:
print(http.get_text)
return False,"上传失败,服务器暂时无法处理上传"
elif arr['code']==-1 or arr['code']==2:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return False,"用户名或密码错误"
elif arr['code']==0:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return True,arr['msg']
elif arr['code']==0:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return False,arr['msg']
else:
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
return False,arr['msg']
- def installplug(self,plug,edition='',token='',cli=False,mandatory=False):
+ def installplug(self,plug,edition='',token='',cli=False,mandatory=False,username=''):
"""创建一个插件,如果您的模块目录下没有插件包,则创建默认插件文件
plug 插件名
"""
plug=str(plug)
- if os.path.exists(self.appname+"/"+self.modular+"/controller/"+plug) and not mandatory:
+ if os.path.exists(self.project+self.appname+"/"+self.modular+"/controller/"+plug) and not mandatory:
return False,"该插件已存在"
else:
http=Http()
@@ -1000,7 +1216,7 @@ class create:
tplug=plug
modular=self.modular
while True:
- http.openurl(config.domain['kcwebapi']+"/pub/plug","GET",params={"modular":modular,"name":str(tplug),"edition":str(edition),"token":token})
+ http.openurl(config.domain['kcwebapi']+"/pub/plug","GET",params={"modular":modular,"name":str(tplug),"edition":str(edition),"token":token,'username':username})
arr=json_decode(http.get_text)
if arr:
if arr['code']==-1 and cli:
@@ -1013,7 +1229,9 @@ class create:
i+=1
elif arr['code']==-1:
return False,plug+"插件授权码错误"
- elif not arr['data']:
+ elif arr['code']==-5:
+ return False,plug+","+arr['data']
+ elif arr['code']==0 and not arr['data']:
modular="api"
tplug="index" #默认插件
elif arr['code']==0 and arr['data']:
@@ -1021,12 +1239,12 @@ class create:
j+=1
arr=arr['data']
r=requests.get(arr['dowurl'],verify=False)
- f = open(self.appname+"/"+self.modular+"/controller/"+plug+".zip", "wb")
+ f = open(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip", "wb")
for chunk in r.iter_content(chunk_size=512):
if chunk:
f.write(chunk)
f.close()
- if zipfile.is_zipfile(self.appname+"/"+self.modular+"/controller/"+plug+".zip") and os.path.isfile(self.appname+"/"+self.modular+"/controller/"+plug+".zip"):
+ if zipfile.is_zipfile(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip") and os.path.isfile(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip"):
break
if j >= 10:
return False,str(plug)+"插件下载失败"
@@ -1035,13 +1253,13 @@ class create:
return False,str(plug)+"插件搜索失败"
else:
return False,self.modular+"模块下找不到"+str(plug)+"插件"
- if os.path.isfile(self.appname+"/"+self.modular+"/controller/"+plug+".zip"):#安装打包好的插件
- kcwebzip.unzip_file(self.appname+"/"+self.modular+"/controller/"+plug+".zip",self.appname+"/"+self.modular+"/controller/"+plug+"/")
- os.remove(self.appname+"/"+self.modular+"/controller/"+plug+".zip")
- if os.path.isfile(self.appname+"/"+self.modular+"/controller/"+plug+"/install.txt"): #安装依赖包
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip"):#安装打包好的插件
+ kcwebzip.unzip_file(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip",self.project+self.appname+"/"+self.modular+"/controller/"+plug+"/")
+ os.remove(self.project+self.appname+"/"+self.modular+"/controller/"+plug+".zip")
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+"/controller/"+plug+"/install.txt"): #安装依赖包
install_requires=[]
try:
- f=open(self.appname+"/"+self.modular+"/controller/"+plug+"/install.txt")
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/"+plug+"/install.txt")
while True:
line = f.readline()
if not line:
@@ -1050,51 +1268,51 @@ class create:
install_requires.append(line)
f.close()
except:
- shutil.rmtree(self.appname+"."+self.modular+"/controller/"+plug)
- return False,"error"
+ shutil.rmtree(self.project+self.appname+"."+self.modular+"/controller/"+plug)
+ return False,"依赖包错误"
if len(install_requires):
try:
install_requires.insert(0,"install")
if 0 != pip.main(install_requires):
- shutil.rmtree(self.appname+"/"+self.modular+"/controller/"+plug)
- return False,"error"
+ shutil.rmtree(self.project+self.appname+"/"+self.modular+"/controller/"+plug)
+ return False,"依赖包安装错误"
except AttributeError as e:
- shutil.rmtree(self.appname+"/"+self.modular+"/controller/"+plug)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular+"/controller/"+plug)
if config.app['app_debug']:
- print("建议更新您的pip版本。参考命令:Python -m pip install --user --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/")
+ print("建议更新您的pip版本。参考命令:python3 -m pip install --upgrade pip==21.2.4 -i https://mirrors.aliyun.com/pypi/simple/")
return False,str(e)
- if os.path.isfile(self.appname+"."+self.modular+"/controller/"+plug+"/install.py"):
+ if os.path.isfile(self.project+self.appname+"."+self.modular+"/controller/"+plug+"/install.py"):
try:
- m=importlib.import_module(self.appname+"."+self.modular+"/controller/"+plug+".install")
+ m=importlib.import_module(self.project+self.appname+"."+self.modular+"/controller/"+plug+".install")
except:
- shutil.rmtree(self.appname+"."+self.modular+"/controller/"+plug)
+ shutil.rmtree(self.project+self.appname+"."+self.modular+"/controller/"+plug)
print(traceback.format_exc())
return False,"插件依赖包文件不存在或依赖包文件格式错误"
else:
try:
a=m.install()
except:
- shutil.rmtree(self.appname+"."+self.modular+"/controller/"+plug)
+ shutil.rmtree(self.project+self.appname+"."+self.modular+"/controller/"+plug)
return False,"插件依赖包install函数被破坏"
# if not a[0]:
- # shutil.rmtree(self.appname+"."+self.modular+"/controller/"+plug)
+ # shutil.rmtree(self.project+self.appname+"."+self.modular+"/controller/"+plug)
# return False,str(a[1])
- f=open(self.appname+"/"+self.modular+"/controller/__init__.py","r",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/__init__.py","r",encoding='utf-8')
text=f.read()
f.close()
text=re.sub("\nfrom . import "+plug,"",text)
text=re.sub("from . import "+plug,"",text)
- f=open(self.appname+"/"+self.modular+"/controller/__init__.py","w",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/__init__.py","w",encoding='utf-8')
text+="\nfrom . import "+plug
f.write(text)
f.close()
- f=open(self.appname+"/"+self.modular+"/controller/"+plug+"/common/autoload.py","r",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/"+plug+"/common/autoload.py","r",encoding='utf-8')
text=f.read()
f.close()
text=re.sub("app.api",self.appname+"."+self.modular,text)
- f=open(self.appname+"/"+self.modular+"/controller/"+plug+"/common/autoload.py","w",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/"+plug+"/common/autoload.py","w",encoding='utf-8')
f.write(text)
f.close()
@@ -1104,30 +1322,31 @@ class create:
return False,str(plug)+"插件获取失败"
def uninstallmodular(self):
"卸载模块"
- f=open(self.appname+"/__init__.py","r")
+ f=open(self.project+self.appname+"/__init__.py","r")
text=f.read()
f.close()
text=re.sub("\nfrom . import "+self.modular,"",text)
text=re.sub("from . import "+self.modular,"",text)
- f=open(self.appname+"/__init__.py","w")
+ f=open(self.project+self.appname+"/__init__.py","w")
f.write(text)
f.close()
- shutil.rmtree(self.appname+"/"+self.modular)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
return True,"成功"
def packmodular(self):
"""打包模块"""
- if os.path.exists(self.appname+"/"+self.modular):
- kcwebzip.packzip(self.appname+"/"+self.modular,self.appname+"/"+self.modular+".zip")
+ if os.path.exists(self.project+self.appname+"/"+self.modular):
+ kcwebzip.packzip(self.project+self.appname+"/"+self.modular,self.project+self.appname+"/"+self.modular+".zip")
return True,"成功"
else:
return False,"失败"
- def uploadmodular(self,username='',password='',cli=False):
+ def uploadmodular(self,username='',password='',cli=False,relyonlist=[]):
"上传模块"
- if not os.path.isfile(self.appname+"/"+self.modular+".zip"):
+ if not os.path.isfile(self.project+self.appname+"/"+self.modular+".zip"):
self.packmodular()
i=0
http=Http()
http.set_timeout=300
+ relyonlist=json_encode(relyonlist)
while True:
timestamp=times()
sign=md5(str(username)+str(timestamp)+md5(md5(password)))
@@ -1135,17 +1354,17 @@ class create:
# http.set_header['timestamp']=str(timestamp)
# http.set_header['sign']=sign
http.openurl(config.domain['kcwebapi']+"/user/uploadmodular/?username="+username+"×tamp="+str(timestamp)+"&sign="+sign,'POST',
- data={'name':str(self.modular),'describes':''},
- files={'file':open(self.appname+"/"+self.modular+".zip", 'rb')})
+ data={'name':str(self.modular),'describes':'','relyonlist':relyonlist},
+ files={'file':open(self.project+self.appname+"/"+self.modular+".zip", 'rb')})
arr=json_decode(http.get_text)
if not arr:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
if config.app['app_debug']:
print(http.get_text)
return False,"用户身份验证失败,服务器暂时无法处理"
if (arr['code']==-1 or arr['code']==2) and cli:
if i >= 3:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return False,"用户名或密码错误"
elif i:
print("用户名或密码错误,请重新输入")
@@ -1158,94 +1377,110 @@ class create:
elif arr['code']==0:
break
elif arr['code']==-1:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return False,"用户名或密码错误"
else:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return False,arr['msg']
http.openurl(config.domain['kcwebapi']+"/user/uploadmodular/?username="+username+"×tamp="+str(timestamp)+"&sign="+sign,'POST',
- data={'name':str(self.modular),'describes':''},
- files={'file':open(self.appname+"/"+self.modular+".zip", 'rb')})
+ data={'name':str(self.modular),'describes':'','relyonlist':relyonlist},
+ files={'file':open(self.project+self.appname+"/"+self.modular+".zip", 'rb')})
arr=json_decode(http.get_text)
if not arr:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
if config.app['app_debug']:
print(http.get_text)
return False,"上传失败,服务器暂时无法处理上传"
elif arr['code']==-1 or arr['code']==2:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return False,"用户名或密码错误"
elif arr['code']==0:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return True,arr['msg']
else:
- os.remove(self.appname+"/"+self.modular+".zip")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
return False,arr['msg']
- def installmodular(self,token='',cli=False):
+ def installmodular(self,token='',cli=False,package='kcweb'):
"创建模块,如果应用不存,则创建默认应用,如果在您的应用目录下没有模块包,则创建默认模块文件"
- if not os.path.exists(self.appname):
- # os.makedirs(self.appname)
- r=requests.get(config.domain['kcwebfile']+"/kcweb/app.zip")
- f = open("./app.zip", "wb")
- for chunk in r.iter_content(chunk_size=512):
- if chunk:
- f.write(chunk)
- f.close()
- kcwebzip.unzip_file("./app.zip","./"+self.appname)
- os.remove("./app.zip")
- if not os.path.isfile("./server.py"):
- if "Windows" in platform.platform():
- pythonname="python"
- else:
- pythonname="python3"
- servertext=('# -*- coding: utf-8 -*-\n #gunicorn -b 0.0.0.0:39010 '+self.appname+':app\n'+
- 'from kcweb import web\n'+
- 'import '+self.appname+' as application\n'+
- 'app=web(__name__,application)\n'+
+ if not os.path.exists(self.project+self.appname):
+ if package=='kcwebplus':
+ r=requests.get(config.domain['kcwebfile']+"/kcweb/kcwebplus.zip")
+ f = open("./"+self.project+"kcwebplus.zip", "wb")
+ for chunk in r.iter_content(chunk_size=512):
+ if chunk:
+ f.write(chunk)
+ f.close()
+ kcwebzip.unzip_file("./"+self.project+"kcwebplus.zip","./"+self.project+self.appname)
+ os.remove("./"+self.project+"kcwebplus.zip")
+ else:
+ r=requests.get(config.domain['kcwebfile']+"/kcweb/app.zip")
+ f = open("./"+self.project+"app.zip", "wb")
+ for chunk in r.iter_content(chunk_size=512):
+ if chunk:
+ f.write(chunk)
+ f.close()
+ kcwebzip.unzip_file("./"+self.project+"app.zip","./"+self.project+self.appname)
+ os.remove("./"+self.project+"app.zip")
+ if not os.path.isfile("./"+self.project+"server.py"):
+ # if "Windows" in platform.platform():
+ # pythonname="python"
+ # else:
+ # pythonname="python3.8"
+ servertext=('#项目运行文件,请务修改\n'+
+ 'import kcweb,sys,'+self.appname+'\n'+
+ 'app=kcweb.web(__name__,'+self.appname+')\n'+
'if __name__ == "__main__":\n'+
- ' #host监听ip port端口 name python解释器名字 (windows一般是python linux一般是python3)\n'+
- ' app.run(host="0.0.0.0",port="39001",name="'+pythonname+'")')
- f=open("./server.py","w+",encoding='utf-8')
+ ' try:\n'+
+ ' route=sys.argv[1]\n'+
+ ' if "eventlog"==route:\n'+
+ ' raise Exception("")\n'+
+ ' except:\n'+
+ ' #host监听ip port端口 name python解释器名字 (windows一般是python linux一般是python3) \n'+
+ ' app.run(host="0.0.0.0",port="39001",name="python3.8")\n'+
+ ' else:\n'+
+ ' app.cli(route)\n'
+ )
+ f=open("./"+self.project+"server.py","w+",encoding='utf-8')
f.write(servertext)
f.close()
- f=open(self.appname+"/common/autoload.py","w",encoding='utf-8')
- f.write("from kcweb.common import *\n"+
- "from "+self.appname+" import config\n"+
- "G=globals.G")
- f.close()
-
- content=''
- f=open(self.appname+"/"+self.modular+"/common/autoload.py","r",encoding='utf-8')
- while True:
- line = f.readline()
- if not line:
- break
- elif 'from' not in line and 'import' not in line:
- content+=line
- f.close()
- f=open(self.appname+"/"+self.modular+"/common/autoload.py","w",encoding='utf-8')
- f.write("from "+self.appname+".common import *\n"+content)
- f.close()
-
- content=''
- f=open(self.appname+"/"+self.modular+"/controller/index/common/autoload.py","r",encoding='utf-8')
- while True:
- line = f.readline()
- if not line:
- break
- elif 'from' not in line and 'import' not in line:
- content+=line
- f.close()
- f=open(self.appname+"/"+self.modular+"/controller/index/common/autoload.py","w",encoding='utf-8')
- f.write("from "+self.appname+"."+self.modular+".common import *\n"+content)
- f.close()
+ # f=open(self.project+self.appname+"/common/autoload.py","w",encoding='utf-8')
+ # f.write("from kcweb.common import *\n"+
+ # "from "+self.appname+" import config\n"+
+ # "G=globals.G")
+ # f.close()
+
+ # content=''
+ # f=open(self.project+self.appname+"/"+self.modular+"/common/autoload.py","r",encoding='utf-8')
+ # while True:
+ # line = f.readline()
+ # if not line:
+ # break
+ # elif 'from' not in line and 'import' not in line:
+ # content+=line
+ # f.close()
+ # f=open(self.project+self.appname+"/"+self.modular+"/common/autoload.py","w",encoding='utf-8')
+ # f.write("from "+self.appname+".common import *\n"+content)
+ # f.close()
+
+ # content=''
+ # f=open(self.project+self.appname+"/"+self.modular+"/controller/index/common/autoload.py","r",encoding='utf-8')
+ # while True:
+ # line = f.readline()
+ # if not line:
+ # break
+ # elif 'from' not in line and 'import' not in line:
+ # content+=line
+ # f.close()
+ # f=open(self.project+self.appname+"/"+self.modular+"/controller/index/common/autoload.py","w",encoding='utf-8')
+ # f.write("from "+self.appname+"."+self.modular+".common import *\n"+content)
+ # f.close()
return True,"应用创建成功"
else:
- if not os.path.isfile(self.appname+"/__init__.py") or not os.path.exists(self.appname+"/common"):
+ if not os.path.isfile(self.project+self.appname+"/__init__.py") or not os.path.exists(self.project+self.appname+"/common"):
return False,self.appname+"不是kcweb应用"
- if os.path.exists(self.appname+"/"+self.modular):
- return False,self.appname+"/"+self.modular+"已存在"
+ if os.path.exists(self.project+self.appname+"/"+self.modular):
+ return False,self.project+self.appname+"/"+self.modular+"已存在"
else:
http=Http()
i=0
@@ -1272,23 +1507,23 @@ class create:
i=0
while i < 5:
r=requests.get(arr['dowurl'])
- f = open(self.appname+"/"+self.modular+".zip", "wb")
+ f = open(self.project+self.appname+"/"+self.modular+".zip", "wb")
for chunk in r.iter_content(chunk_size=1024*100):
if chunk:
f.write(chunk)
f.close()
time.sleep(0.3)
- if os.path.isfile(self.appname+"/"+self.modular+".zip"):
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+".zip"):
break
i+=1
- if os.path.isfile(self.appname+"/"+self.modular+".zip"):#安装打包好的模块
- kcwebzip.unzip_file(self.appname+"/"+self.modular+".zip",self.appname+"/"+self.modular+"/")
- os.remove(self.appname+"/"+self.modular+".zip")
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+".zip"):#安装打包好的模块
+ kcwebzip.unzip_file(self.project+self.appname+"/"+self.modular+".zip",self.project+self.appname+"/"+self.modular+"/")
+ os.remove(self.project+self.appname+"/"+self.modular+".zip")
- if os.path.isfile(self.appname+"/"+self.modular+"/install.txt"): #安装依赖包
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+"/install.txt"): #安装依赖包
install_requires=[]
try:
- f=open(self.appname+"/"+self.modular+"/install.txt")
+ f=open(self.project+self.appname+"/"+self.modular+"/install.txt")
while True:
line = f.readline()
if not line:
@@ -1297,42 +1532,42 @@ class create:
install_requires.append(line)
f.close()
except:
- shutil.rmtree(self.appname+"/"+self.modular)
- return False,"error"
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
+ return False,"模块依赖包错误"
if len(install_requires):
try:
install_requires.insert(0,"install")
if 0 != pip.main(install_requires):
- shutil.rmtree(self.appname+"/"+self.modular)
- return False,"error"
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
+ return False,"模块依赖包安装错误"
except AttributeError as e:
- shutil.rmtree(self.appname+"/"+self.modular)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
if config.app['app_debug']:
print("建议更新您的pip版本。参考命令:Python -m pip install --user --upgrade pip -i https://mirrors.aliyun.com/pypi/simple/")
return False,str(e)
- if os.path.isfile(self.appname+"/"+self.modular+"/install.py"):#如果存在依赖文件
+ if os.path.isfile(self.project+self.appname+"/"+self.modular+"/install.py"):#如果存在依赖文件
try:
- m=importlib.import_module(self.appname+'.'+self.modular+'.install')
+ m=importlib.import_module(self.project+self.appname+'.'+self.modular+'.install')
except:
- shutil.rmtree(self.appname+"/"+self.modular)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
print(traceback.format_exc())
return False,"模块依赖包文件不存在或依赖包文件格式错误"
else:
try:
a=m.install()
except:
- shutil.rmtree(self.appname+"/"+self.modular)
+ shutil.rmtree(self.project+self.appname+"/"+self.modular)
return False,"模块依赖包install方法被破坏"
# if not a[0]:
- # shutil.rmtree(self.appname+"/"+self.modular)
+ # shutil.rmtree(self.project+self.appname+"/"+self.modular)
# return False,str(a[1])
content="\nfrom . import "+self.modular
- f=open(self.appname+"/__init__.py","a",encoding='utf-8')
+ f=open(self.project+self.appname+"/__init__.py","a",encoding='utf-8')
f.write(content)
f.close()
content=''
- f=open(self.appname+"/"+self.modular+"/common/autoload.py","r",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/common/autoload.py","r",encoding='utf-8')
while True:
line = f.readline()
if not line:
@@ -1340,22 +1575,22 @@ class create:
elif 'from' not in line and 'import' not in line:
content+=line
f.close()
- f=open(self.appname+"/"+self.modular+"/common/autoload.py","w",encoding='utf-8')
+ f=open(self.project+self.appname+"/"+self.modular+"/common/autoload.py","w",encoding='utf-8')
f.write("from "+self.appname+".common import *\n"+content)
f.close()
-
- content=''
- f=open(self.appname+"/"+self.modular+"/controller/index/common/autoload.py","r",encoding='utf-8')
- while True:
- line = f.readline()
- if not line:
- break
- elif 'from' not in line and 'import' not in line:
- content+=line
- f.close()
- f=open(self.appname+"/"+self.modular+"/controller/index/common/autoload.py","w",encoding='utf-8')
- f.write("from "+self.appname+"."+self.modular+".common import *\n"+content)
- f.close()
+ if os.path.exists(self.project+self.appname+"/"+self.modular+"/controller/index"):
+ content=''
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/index/common/autoload.py","r",encoding='utf-8')
+ while True:
+ line = f.readline()
+ if not line:
+ break
+ elif 'from' not in line and 'import' not in line:
+ content+=line
+ f.close()
+ f=open(self.project+self.appname+"/"+self.modular+"/controller/index/common/autoload.py","w",encoding='utf-8')
+ f.write("from "+self.appname+"."+self.modular+".common import *\n"+content)
+ f.close()
else:
return False,self.modular+"模块下载失败"
if not os.path.isfile("./server.py"):
@@ -1371,7 +1606,7 @@ class create:
'if __name__ == "__main__":\n'+
' #host监听ip port端口 name python解释器名字 (windows一般是python linux一般是python3)\n'+
' app.run(host="0.0.0.0",port="39001",name="'+pythonname+'")')
- f=open("./server.py","w+",encoding='utf-8')
+ f=open("./"+self.project+"server.py","w+",encoding='utf-8')
f.write(servertext)
f.close()
return True,"安装成功"
@@ -1383,7 +1618,7 @@ class create:
# def __zxmodular(self,sourcep):
# "处理模块文件"
# path1=self.path+"/application/api"+sourcep
- # path2=self.appname+"/"+self.modular+sourcep
+ # path2=self.project+self.appname+"/"+self.modular+sourcep
# lists=os.listdir(path1)
# for files in lists:
# if os.path.isfile(path1+"/"+files):
@@ -1402,4 +1637,54 @@ class create:
# elif files != '__pycache__':
# if not os.path.exists(path2+"/"+files):
# os.makedirs(path2+"/"+files)
- # self.__zxmodular(sourcep+"/"+files)
\ No newline at end of file
+ # self.__zxmodular(sourcep+"/"+files)
+if not os.path.exists(get_folder()+"/pid/"):
+ os.makedirs(get_folder()+"/pid/", exist_ok=True)
+if 'Linux' in get_sysinfo()['platform']:
+ #添加自启命令
+ if not os.path.isfile('/usr/bin/startkcweb.sh'):
+ open('/usr/bin/startkcweb.sh', 'w').close()
+ os.system("sed -i 's/bash startkcweb.sh//g' /etc/rc.d/rc.local")
+ os.system("echo 'bash startkcweb.sh' >> /etc/rc.d/rc.local")
+ os.system('chmod 777 /etc/rc.d/rc.local')
+ os.system('chmod 777 /usr/bin/startkcweb.sh')
+def insert_system_up(cmd):
+ """添加开机启动命令
+
+ cmd 命令
+ """
+ if 'Linux' in get_sysinfo()['platform']:
+ f=open("/usr/bin/startkcweb.sh","a")
+ f.write("\n"+cmd+"\n")
+ f.close()
+ return True
+ else:
+ raise Exception('暂不支持linux以外的系统')
+def del_system_up(cmd,vague=False):
+ """删除开机启动命令
+
+ cmd 命令
+
+ vague 是否模糊匹配
+ """
+ if 'Linux' in get_sysinfo()['platform']:
+ if vague:
+ f = open("/usr/bin/startkcweb.sh")
+ con=''
+ while True:
+ line = f.readline()
+ if not line:
+ break
+ if cmd in line:
+ line=''
+ con=con+line
+ f.close()
+ file_set_content("/usr/bin/startkcweb.sh",con)
+ else:
+ content=file_get_content("/usr/bin/startkcweb.sh")
+ content=content.replace("\n"+cmd+"\n","")
+ file_set_content("/usr/bin/startkcweb.sh",content)
+ return True
+ else:
+ raise Exception('暂不支持linux以外的系统')
+
\ No newline at end of file
diff --git a/common/globals.py b/kcweb/common/globals.py
similarity index 100%
rename from common/globals.py
rename to kcweb/common/globals.py
diff --git a/common/request.py b/kcweb/common/request.py
similarity index 100%
rename from common/request.py
rename to kcweb/common/request.py
diff --git a/common/session.py b/kcweb/common/session.py
similarity index 100%
rename from common/session.py
rename to kcweb/common/session.py
diff --git a/config/__init__.py b/kcweb/config/__init__.py
similarity index 86%
rename from config/__init__.py
rename to kcweb/config/__init__.py
index ccab9c90c33f5f6f56cbe1e1427152ab75490c82..d6188e99c4b5ae797d856df8d3815bf3041bfeab 100644
--- a/config/__init__.py
+++ b/kcweb/config/__init__.py
@@ -8,13 +8,8 @@ app['before_request']='' #设置请求前执行的函数
app['after_request']='' #设置请求后执行的函数
app['staticpath']='static'
app['http_server']='wsgiref' #使用的开发服务器 支持 wsgiref、kcweb、kcweb_server
-try:
- if sys.argv[2]=='--cli':
- app['cli']=True
- else:
- app['cli']=False
-except:
- app['cli']=False
+app['cli']=False
+app['save_cli_pid']=False #是否开启cli运行时保存pid
# redis配置
redis={}
redis['host']='127.0.0.1' #服务器地址
@@ -58,7 +53,7 @@ database['password']=['root'] #密码 [密码1,密码2,密码3...]
database['db']=['test'] #数据库名 [数据库名1,数据库名2,数据库名3...]
database['charset']='utf8mb4' #数据库编码默认采用utf8mb4
database['pattern']=False # True数据库长连接模式 False数据库短连接模式 注:建议web应用有效,cli应用方式下,如果长时间运行建议使用mysql().close()关闭
-database['cli']=app['cli'] # 是否以cli方式运行
+database['cli']=False # 是否以cli方式运行
database['dbObjcount']=1 # 连接池数量(单个数据库地址链接数量),数据库链接实例数量 mysql长链接模式下有效
database['deploy']=0 # 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) mysql数据库有效
database['master_num']=1 #主服务器数量 不能超过host服务器数量 (等于服务器数量表示读写不分离:主主复制。 小于服务器表示读写分离:主从复制。) mysql数据库有效
@@ -102,12 +97,12 @@ email['recNick']='' #默认收件人昵称
kcweb={}
kcweb['name']='kcweb' #项目的名称
-kcweb['version']='4.13.26' #项目版本
-kcweb['description']='' #项目的简单描述
-kcweb['long_description']='' #项目详细描述
+kcweb['version']='5.328' #项目版本
+kcweb['description']='python web框架' #项目的简单描述
+kcweb['long_description']='kcweb作为web开发而设计的高性能框架,采用全新的架构思想,注重易用性。遵循MIT开源许可协议发布,意味着个人和企业可以免费使用kcweb,甚至允许把你基于kcweb开发的应用开源或商业产品发布或销售' #项目详细描述
kcweb['license']='MIT' #开源协议 mit开源
kcweb['url']=''
-kcweb['author']='禄可集团-坤坤' #名字
+kcweb['author']='百里-坤坤' #名字
kcweb['author_email']='fk1402936534@qq.com' #邮件地址
kcweb['maintainer']='坤坤' #维护人员的名字
kcweb['maintainer_email']='fk1402936534@qq.com' #维护人员的邮件地址
@@ -115,11 +110,10 @@ kcweb['username']=''
kcweb['password']=''
domain={}
-domain['kcwebfile']="https://fanshufile.oss-cn-beijing.aliyuncs.com"
-domain['kcwebstatic']="https://fanshustatic.oss-cn-beijing.aliyuncs.com"
-domain['kcwebimg']="https://fanshuimg.oss-cn-beijing.aliyuncs.com"
-# domain['kcwebapi']="//kcweb.kwebapp.cn"
-domain['kcwebapi']="http://124.223.99.60:49001/index/index"
+domain['kcwebfile']="https://file.kwebapp.cn"
+domain['kcwebstatic']="https://static.kwebapp.cn"
+domain['kcwebimg']="https://img.kwebapp.cn"
+domain['kcwebapi']="https://kcwebapi.kwebapp.cn"
#其他配置
other={}
diff --git a/kcweb/config/__pycache__/__init__.cpython-36.pyc b/kcweb/config/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..07496b34237f06daed0791625bc6b24f3e35306b
Binary files /dev/null and b/kcweb/config/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/kcweb.py b/kcweb/kcweb.py
new file mode 100644
index 0000000000000000000000000000000000000000..b77fa7cba61a53cd4f8b6e8f0a8661379b0b96fd
--- /dev/null
+++ b/kcweb/kcweb.py
@@ -0,0 +1,280 @@
+from .common import *
+import getopt,site
+PATH=os.getcwd()
+sys.path.append(PATH)
+# import subprocess
+def __get_cmd_par():
+ python_version=platform.python_version()
+ if python_version[0:3]!='3.8':
+ print("\033[1;31;40m "+config.kcweb['name']+"-"+config.kcweb['version']+"依赖python3.8,与你现在的python"+python_version+"不兼容")
+ exit()
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "h", ["project=","app=","modular=","plug=","user=","pwd=","host=","port=","timeout=","processcount=",
+ "install","uninstall","pack","upload","cli"])
+ # print("opts",opts)
+ # print("args",args)
+ server=False
+ if 'server' in args:
+ server=True
+ help=False
+ if 'help' in args:
+ help=True
+
+ project='' #项目名称
+ appname='app' #应用名 目前是固定值 app
+ modular='index' #模块名
+ plug='' #插件名
+ username=''
+ password=''
+ host='0.0.0.0'
+ port=30000
+ timeout='600'
+ processcount='4'
+
+ install=False
+ uninstall=False
+ pack=False
+ upload=False
+ cli=False
+
+ if '--cli' in args:
+ cli=True
+ i=0
+ for data in opts:
+ if '--project' == data[0]:
+ project=data[1]
+ # if '--app' == data[0]:
+ # appname=data[1]
+ elif '--modular' == data[0]:
+ modular=data[1]
+ elif '--plug' == data[0]:
+ plug=data[1]
+ elif '--user' == data[0]:
+ username=data[1]
+ elif '--pwd' == data[0]:
+ password=data[1]
+ elif '--host' == data[0]:
+ host=data[1]
+ elif '--port' == data[0]:
+ port=data[1]
+ elif '--timeout' == data[0]:
+ timeout=data[1]
+ elif '--processcount' == data[0]:
+ processcount=data[1]
+
+ elif '--help' == data[0]:
+ help=True
+ elif '--install' == data[0]:
+ install=True
+ elif '--uninstall' == data[0]:
+ uninstall=True
+ elif '--pack' == data[0]:
+ pack=True
+ elif '--upload' == data[0]:
+ upload=True
+ elif '--cli' == data[0]:
+ cli=True
+ i+=1
+ except Exception as e:
+ try:
+ gcs=sys.argv[1]
+ except:
+ gcs=''
+ if gcs=='-v':
+ print(config.kcweb['name']+"-"+config.kcweb['version'])
+ else:
+ print("\033[1;31;40m有关kcweb命令的详细信息,请键入 kcweb help",e)
+ return False
+ else:
+ return {
+ 'server':server,
+ 'project':project,'appname':appname,'modular':modular,'username':username,'password':password,'plug':plug,'host':host,'port':port,'timeout':timeout,'processcount':processcount,
+ 'help':help,'install':install,'uninstall':uninstall,'pack':pack,'upload':upload,'cli':cli,
+ 'index':i
+ }
+def executable():
+ cmd_par=__get_cmd_par()
+ if not cmd_par:
+ exit()
+ if cmd_par['help']:
+ try:
+ cs=sys.argv[2:][0]
+ except:
+ cs=None
+ print("\033[1;31;40m有关某个命令的详细信息,请键入 kcweb help 命令名")
+ print("\033[36m执行 kcweb help server 可查看server相关命令")
+ print("\033[36m执行 kcweb help modular 可查看赋值相关命令")
+ print("\033[36m执行 kcweb help install 可查看安装相关命令")
+ print("\033[36m执行 kcweb help pack 可查看打包相关命令")
+ print("\033[36m执行 kcweb help upload 可查看上传相关命令")
+ print("\033[36m执行 kcweb help uninstall 可查看卸载相关命令\n")
+ if 'server' == cs:
+ print("\033[32mkcweb --host 0.0.0.0 --port 39001 server 启动web服务")
+ print("\033[32mhost、port并不是必须的,如果要使用默认值,您可以使用下面简短的命令来启动服务")
+ print("\033[32mkcweb server\n")
+ if 'modular' == cs:
+ print("\033[32mkcweb --modular api --plug plug --install 进行安装")
+ print("\033[1;31;40m初始化一个web应用示例,通常情况下modular、plug、install同时使用")
+ print("\033[32mmodular、plug并不是必须的,如果要使用默认值,您可以使用下面简短的命令来安装")
+ print("\033[32mkcweb install\n")
+ if 'install' == cs:
+ print("\033[32mkcweb --install 安装一个默认的应用")
+ print("\033[32mkcweb --modular base --install 在app应用中安装一个base模块")
+ print("\033[32mkcweb --modular base --plug plug1 --install 在app应用base模块中安装一个plug1插件")
+ print("\033[32mkcweb --modular intapp --plug plug1 --user 181*** --install 在app应用intapp模块中安装一个指定用户的plug1插件")
+ print("\033[32m如果您需要新建一个项目 可以使用以下命令")
+ print("\033[32mkcweb --project projectname --app app --modular intapp --plug plug1 --user 181*** --install 在projectname项目下的app应用下intapp模块中安装一个指定用户的plug1插件\n")
+ if 'pack' == cs:
+ print("\033[32mkcweb --modular api --pack 打包一个模块")
+ print("\033[32mkcweb --modular api --plug plug1 --pack 可以打包一个插件\n")
+ if 'upload' == cs:
+ print("\033[32mkcweb --modular intapp --user 181*** --pwd pwd123 --upload 上传一个intapp模块")
+ print("\033[32mkcweb --modular intapp --plug plug1 --user 181*** --pwd pwd123 --upload 向intapp模块中上传一个plug1插件")
+ print("\033[1;31;40m注意:181*** 和 pwd123 是您的用户或密码")
+ if 'uninstall' == cs:
+ print("\033[32mkcweb --modular api --uninstall 卸载app/api模块")
+ print("\033[32mkcweb --modular api --plug plug1 --uninstall 卸载app/api/plug1插件\n")
+ else:
+ # print(cmd_par)
+ if cmd_par['cli']:#通过命令行执行控制器的方法
+ from . import web
+ try:
+ import app as application
+ except Exception as e:
+ if "No module named 'app'" in str(e):
+ print("请在kcweb项目下运行")
+ else:
+ print(traceback.format_exc())
+ exit()
+ else:
+ app=web(__name__,application)
+ try:
+ RAW_URI=sys.argv[1]
+ except:pass
+ else:
+ if RAW_URI=='--cli':
+ RAW_URI=''
+ app.cli(RAW_URI)
+ elif cmd_par['server']:#启动web服务
+ types=sys.argv[len(sys.argv)-1]
+ try:
+ Queues.delwhere("code in (2,3)")
+ except:pass
+ if get_sysinfo()['uname'][0]=='Linux':
+ pythonpath=site.getsitepackages()[0].replace('\\','/')
+ t=pythonpath.split('/')
+ tt='/'+t[-3]+'/'+t[-2]+'/'+t[-1]
+ pythonpath=pythonpath.replace(tt,'')
+ if not os.path.exists('/usr/bin/kcweb') and os.path.isfile(pythonpath+'/bin/kcweb'):
+ os.system("ln -s "+pythonpath+"/bin/kcweb /usr/bin/kcweb")
+ # if types=='-stop' or types=='-start':
+ # pass
+ # else:
+ # print("启动参数错误,支持 -start和-stop")
+ # exit()
+ # try:
+ # f=open("pid",'r')
+ # pid=f.read()
+ # f.close()
+ # if pid:
+ # os.system("kill "+pid)
+ # except:pass
+ if __name__ == 'kcweb.kcweb':
+ kill_route_cli('pid/kcweb_server_pid')
+ if types=='-stop':
+ pass
+ else:
+ save_route_cli_pid('pid/kcweb_server_pid')
+ from gunicorn.app.wsgiapp import run
+ sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$','',sys.argv[0])
+ sys.argv=[sys.argv[0], '-w', str(cmd_par['processcount']), '-b', cmd_par['host']+':'+str(cmd_par['port']),'-t',cmd_par['timeout'], 'server:'+cmd_par['appname']]
+ sys.exit(run())
+ exit()
+ else:
+
+ from . import web
+ try:
+ import app as application
+ except Exception as e:
+ if "No module named 'app'" in str(e):
+ print("请在kcweb项目下运行")
+ else:
+ print(traceback.format_exc())
+ exit()
+ else:
+ app=web(__name__,application)
+ if __name__ == "kcweb.kcweb":
+ tar=len(sys.argv)
+ kill_route_cli('pid/'+str(sys.argv[tar-1])+'kcweb_server_pid')
+ if types=='-stop':
+ pass
+ else:
+ save_route_cli_pid('pid/'+str(sys.argv[tar-1])+'kcweb_server_pid')
+ app.run(host=cmd_par['host'],port=int(cmd_par['port']))
+ else:
+ if cmd_par['install']:#插入 应用、模块、插件
+ if cmd_par['appname'] and cmd_par['modular']:
+ server=create(cmd_par['appname'],cmd_par['modular'],project=cmd_par['project'])
+ t=server.installmodular(cli=True)
+ if cmd_par['plug']:
+ res=server.installplug(cmd_par['plug'],cli=True,username=cmd_par['username'])
+ print(res)
+ if not res[0]:
+ exit()
+ else:
+ if '应用创建成功' in t[1]:
+ print("创建应用成功,接下来进入入项目目录 在终端中执行:kcweb server 运行项目")
+ else:
+ print(t)
+ else:
+ print("\033[1;31;40m安装时 必须指定应该app和modular,参考命令: kcweb --app app --modular api")
+ exit()
+ if cmd_par['pack']:#打包 模块、插件
+ if cmd_par['appname'] and cmd_par['modular']:
+ server=create(cmd_par['appname'],cmd_par['modular'],project=cmd_par['project'])
+ if cmd_par['plug']:
+ res=server.packplug(plug=cmd_par['plug'])
+ else:
+ res=server.packmodular()
+ print(res)
+ if not res[0]:
+ exit()
+ else:
+ print("\033[1;31;40m打包时 必须指定应该app和modular,参考命令: kcweb --app app --modular api")
+ exit()
+ if cmd_par['upload']:#上传 模块、插件
+ if cmd_par['appname'] and cmd_par['modular']:
+ server=create(cmd_par['appname'],cmd_par['modular'],project=cmd_par['project'])
+ if cmd_par['plug']:
+ res=server.packplug(plug=cmd_par['plug'])
+ if res[0]:
+ res=server.uploadplug(cmd_par['plug'],cmd_par['username'],cmd_par['password'],cli=True)
+ else:
+ print(res)
+ exit()
+ else:
+ res=server.packmodular()
+ if res[0]:
+ res=server.uploadmodular(cmd_par['username'],cmd_par['password'],cli=True)
+ else:
+ print(res)
+ exit()
+ print(res)
+ if not res[0]:
+ exit()
+ else:
+ print("\033[1;31;40m上传时 必须指定应该app和modular,参考命令: kcweb --app app --modular api")
+ exit()
+ if cmd_par['uninstall']:#卸载 模块、插件
+ if cmd_par['appname'] and cmd_par['modular']:
+ server=create(cmd_par['appname'],cmd_par['modular'],project=cmd_par['project'])
+ if cmd_par['plug']:
+ res=server.uninstallplug(plug=cmd_par['plug'])
+ else:
+ res=server.uninstallmodular()
+ print(res)
+ if not res[0]:
+ exit()
+ else:
+ print("\033[1;31;40m卸载时 必须指定应该app和modular,参考命令: kcweb --app app --modular api")
+ exit()
\ No newline at end of file
diff --git a/tpl/err.html b/kcweb/tpl/err.html
similarity index 100%
rename from tpl/err.html
rename to kcweb/tpl/err.html
diff --git a/tpl/error.html b/kcweb/tpl/error.html
similarity index 100%
rename from tpl/error.html
rename to kcweb/tpl/error.html
diff --git a/kcweb/utill/__pycache__/http.cpython-36.pyc b/kcweb/utill/__pycache__/http.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9dd39e0ea419022810cec0faafd0f6d235aa5fb1
Binary files /dev/null and b/kcweb/utill/__pycache__/http.cpython-36.pyc differ
diff --git a/kcweb/utill/__pycache__/queues.cpython-36.pyc b/kcweb/utill/__pycache__/queues.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8586926c4cb8aba51160942d1c4936daee69831f
Binary files /dev/null and b/kcweb/utill/__pycache__/queues.cpython-36.pyc differ
diff --git a/kcweb/utill/__pycache__/redis.cpython-36.pyc b/kcweb/utill/__pycache__/redis.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..686d0a666ea2da83b8e5a5338a97675cb4136ca3
Binary files /dev/null and b/kcweb/utill/__pycache__/redis.cpython-36.pyc differ
diff --git a/utill/app.py b/kcweb/utill/app.py
similarity index 100%
rename from utill/app.py
rename to kcweb/utill/app.py
diff --git a/kcweb/utill/cache/__pycache__/cache.cpython-36.pyc b/kcweb/utill/cache/__pycache__/cache.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..af3601d0b641120085d3bbc090e85974dac0a19b
Binary files /dev/null and b/kcweb/utill/cache/__pycache__/cache.cpython-36.pyc differ
diff --git a/utill/cache/cache.py b/kcweb/utill/cache/cache.py
similarity index 100%
rename from utill/cache/cache.py
rename to kcweb/utill/cache/cache.py
diff --git a/utill/dateutil/__init__.py b/kcweb/utill/dateutil/__init__.py
similarity index 100%
rename from utill/dateutil/__init__.py
rename to kcweb/utill/dateutil/__init__.py
diff --git a/kcweb/utill/dateutil/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/dateutil/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..509c0785a3b66a6123848e17b71e36a95acb404a
Binary files /dev/null and b/kcweb/utill/dateutil/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/utill/dateutil/__pycache__/_common.cpython-36.pyc b/kcweb/utill/dateutil/__pycache__/_common.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a3f2a89c744bcb0929914ff577528f14c9698fc6
Binary files /dev/null and b/kcweb/utill/dateutil/__pycache__/_common.cpython-36.pyc differ
diff --git a/kcweb/utill/dateutil/__pycache__/_version.cpython-36.pyc b/kcweb/utill/dateutil/__pycache__/_version.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e507bf19823cf04e4b59bddc203aff57a4a039c0
Binary files /dev/null and b/kcweb/utill/dateutil/__pycache__/_version.cpython-36.pyc differ
diff --git a/kcweb/utill/dateutil/__pycache__/relativedelta.cpython-36.pyc b/kcweb/utill/dateutil/__pycache__/relativedelta.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e476ac5a7c32fef2824849251c5b8f2129003c71
Binary files /dev/null and b/kcweb/utill/dateutil/__pycache__/relativedelta.cpython-36.pyc differ
diff --git a/utill/dateutil/_common.py b/kcweb/utill/dateutil/_common.py
similarity index 100%
rename from utill/dateutil/_common.py
rename to kcweb/utill/dateutil/_common.py
diff --git a/utill/dateutil/_version.py b/kcweb/utill/dateutil/_version.py
similarity index 100%
rename from utill/dateutil/_version.py
rename to kcweb/utill/dateutil/_version.py
diff --git a/utill/dateutil/easter.py b/kcweb/utill/dateutil/easter.py
similarity index 100%
rename from utill/dateutil/easter.py
rename to kcweb/utill/dateutil/easter.py
diff --git a/utill/dateutil/parser/__init__.py b/kcweb/utill/dateutil/parser/__init__.py
similarity index 100%
rename from utill/dateutil/parser/__init__.py
rename to kcweb/utill/dateutil/parser/__init__.py
diff --git a/utill/dateutil/parser/_parser.py b/kcweb/utill/dateutil/parser/_parser.py
similarity index 100%
rename from utill/dateutil/parser/_parser.py
rename to kcweb/utill/dateutil/parser/_parser.py
diff --git a/utill/dateutil/parser/isoparser.py b/kcweb/utill/dateutil/parser/isoparser.py
similarity index 100%
rename from utill/dateutil/parser/isoparser.py
rename to kcweb/utill/dateutil/parser/isoparser.py
diff --git a/utill/dateutil/relativedelta.py b/kcweb/utill/dateutil/relativedelta.py
similarity index 100%
rename from utill/dateutil/relativedelta.py
rename to kcweb/utill/dateutil/relativedelta.py
diff --git a/utill/dateutil/rrule.py b/kcweb/utill/dateutil/rrule.py
similarity index 100%
rename from utill/dateutil/rrule.py
rename to kcweb/utill/dateutil/rrule.py
diff --git a/utill/dateutil/tz/__init__.py b/kcweb/utill/dateutil/tz/__init__.py
similarity index 100%
rename from utill/dateutil/tz/__init__.py
rename to kcweb/utill/dateutil/tz/__init__.py
diff --git a/utill/dateutil/tz/_common.py b/kcweb/utill/dateutil/tz/_common.py
similarity index 100%
rename from utill/dateutil/tz/_common.py
rename to kcweb/utill/dateutil/tz/_common.py
diff --git a/utill/dateutil/tz/_factories.py b/kcweb/utill/dateutil/tz/_factories.py
similarity index 100%
rename from utill/dateutil/tz/_factories.py
rename to kcweb/utill/dateutil/tz/_factories.py
diff --git a/utill/dateutil/tz/tz.py b/kcweb/utill/dateutil/tz/tz.py
similarity index 100%
rename from utill/dateutil/tz/tz.py
rename to kcweb/utill/dateutil/tz/tz.py
diff --git a/utill/dateutil/tz/win.py b/kcweb/utill/dateutil/tz/win.py
similarity index 100%
rename from utill/dateutil/tz/win.py
rename to kcweb/utill/dateutil/tz/win.py
diff --git a/utill/dateutil/tzwin.py b/kcweb/utill/dateutil/tzwin.py
similarity index 100%
rename from utill/dateutil/tzwin.py
rename to kcweb/utill/dateutil/tzwin.py
diff --git a/utill/dateutil/utils.py b/kcweb/utill/dateutil/utils.py
similarity index 100%
rename from utill/dateutil/utils.py
rename to kcweb/utill/dateutil/utils.py
diff --git a/utill/dateutil/zoneinfo/__init__.py b/kcweb/utill/dateutil/zoneinfo/__init__.py
similarity index 100%
rename from utill/dateutil/zoneinfo/__init__.py
rename to kcweb/utill/dateutil/zoneinfo/__init__.py
diff --git a/utill/dateutil/zoneinfo/rebuild.py b/kcweb/utill/dateutil/zoneinfo/rebuild.py
similarity index 100%
rename from utill/dateutil/zoneinfo/rebuild.py
rename to kcweb/utill/dateutil/zoneinfo/rebuild.py
diff --git a/kcweb/utill/db/__pycache__/model.cpython-36.pyc b/kcweb/utill/db/__pycache__/model.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..90b4af7780515fff87a11611cdd2be7ea881be96
Binary files /dev/null and b/kcweb/utill/db/__pycache__/model.cpython-36.pyc differ
diff --git a/kcweb/utill/db/__pycache__/mongodb.cpython-36.pyc b/kcweb/utill/db/__pycache__/mongodb.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f5937ea50adb2ba56f80569ab167fadf88b14352
Binary files /dev/null and b/kcweb/utill/db/__pycache__/mongodb.cpython-36.pyc differ
diff --git a/kcweb/utill/db/__pycache__/mysql.cpython-36.pyc b/kcweb/utill/db/__pycache__/mysql.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c02e527d62476b747dcd6f2c1d66f1b1e87c4971
Binary files /dev/null and b/kcweb/utill/db/__pycache__/mysql.cpython-36.pyc differ
diff --git a/kcweb/utill/db/__pycache__/sqlite.cpython-36.pyc b/kcweb/utill/db/__pycache__/sqlite.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..73c876945ba43e0a9c791b8c844cb241849e2cdd
Binary files /dev/null and b/kcweb/utill/db/__pycache__/sqlite.cpython-36.pyc differ
diff --git a/utill/db/model.py b/kcweb/utill/db/model.py
similarity index 100%
rename from utill/db/model.py
rename to kcweb/utill/db/model.py
diff --git a/utill/db/mongodb.py b/kcweb/utill/db/mongodb.py
similarity index 100%
rename from utill/db/mongodb.py
rename to kcweb/utill/db/mongodb.py
diff --git a/utill/db/mysql.py b/kcweb/utill/db/mysql.py
similarity index 100%
rename from utill/db/mysql.py
rename to kcweb/utill/db/mysql.py
diff --git a/utill/db/pymysql/__init__.py b/kcweb/utill/db/pymysql/__init__.py
similarity index 100%
rename from utill/db/pymysql/__init__.py
rename to kcweb/utill/db/pymysql/__init__.py
diff --git a/kcweb/utill/db/pymysql/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c781e16d74ae1342a5a843a31bd69e9fad7f70d6
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/_auth.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/_auth.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..57b3c43f07ff799d319352469e73bf2319ee3bbf
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/_auth.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/_compat.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/_compat.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9de03b094ad6ccf46f6fb9783fa7bef1cdd0d102
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/_compat.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/charset.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/charset.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..676143078bad99bb3bd68c7bd46bc3daa0798013
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/charset.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/connections.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/connections.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ef312c359d2bc834617f02492d144c2105c30a08
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/connections.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/converters.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/converters.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c6ba9b8868d22ce7710033bb0b0dad2438769f10
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/converters.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/cursors.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/cursors.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4360937cae8b9737d28760a7161092324cb44a7e
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/cursors.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/err.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/err.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a9a0db3797740590a5ca462b1810b0d79e82e805
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/err.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/optionfile.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/optionfile.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a7f0a629fa0fe2cae94b8b52b623fde491ee5c26
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/optionfile.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/protocol.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/protocol.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c99007e3dd8b56d689d9b18e01ae4b62d030d373
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/protocol.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/times.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/times.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2d2fec599280f6a27abb1acfdc9c9390bf7f465f
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/times.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/__pycache__/util.cpython-36.pyc b/kcweb/utill/db/pymysql/__pycache__/util.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1764e844120467d961eb138dbb1aceacb3caf4ed
Binary files /dev/null and b/kcweb/utill/db/pymysql/__pycache__/util.cpython-36.pyc differ
diff --git a/utill/db/pymysql/_auth.py b/kcweb/utill/db/pymysql/_auth.py
similarity index 100%
rename from utill/db/pymysql/_auth.py
rename to kcweb/utill/db/pymysql/_auth.py
diff --git a/utill/db/pymysql/_compat.py b/kcweb/utill/db/pymysql/_compat.py
similarity index 100%
rename from utill/db/pymysql/_compat.py
rename to kcweb/utill/db/pymysql/_compat.py
diff --git a/utill/db/pymysql/_socketio.py b/kcweb/utill/db/pymysql/_socketio.py
similarity index 100%
rename from utill/db/pymysql/_socketio.py
rename to kcweb/utill/db/pymysql/_socketio.py
diff --git a/utill/db/pymysql/charset.py b/kcweb/utill/db/pymysql/charset.py
similarity index 100%
rename from utill/db/pymysql/charset.py
rename to kcweb/utill/db/pymysql/charset.py
diff --git a/utill/db/pymysql/connections.py b/kcweb/utill/db/pymysql/connections.py
similarity index 100%
rename from utill/db/pymysql/connections.py
rename to kcweb/utill/db/pymysql/connections.py
diff --git a/utill/db/pymysql/constants/CLIENT.py b/kcweb/utill/db/pymysql/constants/CLIENT.py
similarity index 100%
rename from utill/db/pymysql/constants/CLIENT.py
rename to kcweb/utill/db/pymysql/constants/CLIENT.py
diff --git a/utill/db/pymysql/constants/COMMAND.py b/kcweb/utill/db/pymysql/constants/COMMAND.py
similarity index 100%
rename from utill/db/pymysql/constants/COMMAND.py
rename to kcweb/utill/db/pymysql/constants/COMMAND.py
diff --git a/utill/db/pymysql/constants/CR.py b/kcweb/utill/db/pymysql/constants/CR.py
similarity index 100%
rename from utill/db/pymysql/constants/CR.py
rename to kcweb/utill/db/pymysql/constants/CR.py
diff --git a/utill/db/pymysql/constants/ER.py b/kcweb/utill/db/pymysql/constants/ER.py
similarity index 100%
rename from utill/db/pymysql/constants/ER.py
rename to kcweb/utill/db/pymysql/constants/ER.py
diff --git a/utill/db/pymysql/constants/FIELD_TYPE.py b/kcweb/utill/db/pymysql/constants/FIELD_TYPE.py
similarity index 100%
rename from utill/db/pymysql/constants/FIELD_TYPE.py
rename to kcweb/utill/db/pymysql/constants/FIELD_TYPE.py
diff --git a/utill/db/pymysql/constants/FLAG.py b/kcweb/utill/db/pymysql/constants/FLAG.py
similarity index 100%
rename from utill/db/pymysql/constants/FLAG.py
rename to kcweb/utill/db/pymysql/constants/FLAG.py
diff --git a/utill/db/pymysql/constants/SERVER_STATUS.py b/kcweb/utill/db/pymysql/constants/SERVER_STATUS.py
similarity index 100%
rename from utill/db/pymysql/constants/SERVER_STATUS.py
rename to kcweb/utill/db/pymysql/constants/SERVER_STATUS.py
diff --git a/utill/db/pymysql/constants/__init__.py b/kcweb/utill/db/pymysql/constants/__init__.py
similarity index 100%
rename from utill/db/pymysql/constants/__init__.py
rename to kcweb/utill/db/pymysql/constants/__init__.py
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/CLIENT.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/CLIENT.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fc727edc791134ec2e2840d7e0606838bc2688cd
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/CLIENT.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/COMMAND.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/COMMAND.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e2a6acec4242571b9ed2fcebc19a4c3de247abae
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/COMMAND.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/CR.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/CR.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1c1a759743a3cd2a6f8444eaf8dd07f3d03f6b2b
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/CR.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/ER.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/ER.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..982e80578079f4257478e802d795965588c9de59
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/ER.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/FIELD_TYPE.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/FIELD_TYPE.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8dc47c2face04270335e1437eba89a3f4efc935a
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/FIELD_TYPE.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/FLAG.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/FLAG.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2b0038b9e1a7338e8567ccef6d5e99213454c5f3
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/FLAG.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/SERVER_STATUS.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/SERVER_STATUS.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0c2dd4406e72885dacc69398ba4f90085d4728ef
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/SERVER_STATUS.cpython-36.pyc differ
diff --git a/kcweb/utill/db/pymysql/constants/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/db/pymysql/constants/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0412b212026fc4ce25d491dca6fd7b731115c0e3
Binary files /dev/null and b/kcweb/utill/db/pymysql/constants/__pycache__/__init__.cpython-36.pyc differ
diff --git a/utill/db/pymysql/converters.py b/kcweb/utill/db/pymysql/converters.py
similarity index 100%
rename from utill/db/pymysql/converters.py
rename to kcweb/utill/db/pymysql/converters.py
diff --git a/utill/db/pymysql/cursors.py b/kcweb/utill/db/pymysql/cursors.py
similarity index 100%
rename from utill/db/pymysql/cursors.py
rename to kcweb/utill/db/pymysql/cursors.py
diff --git a/utill/db/pymysql/err.py b/kcweb/utill/db/pymysql/err.py
similarity index 100%
rename from utill/db/pymysql/err.py
rename to kcweb/utill/db/pymysql/err.py
diff --git a/utill/db/pymysql/optionfile.py b/kcweb/utill/db/pymysql/optionfile.py
similarity index 100%
rename from utill/db/pymysql/optionfile.py
rename to kcweb/utill/db/pymysql/optionfile.py
diff --git a/utill/db/pymysql/protocol.py b/kcweb/utill/db/pymysql/protocol.py
similarity index 100%
rename from utill/db/pymysql/protocol.py
rename to kcweb/utill/db/pymysql/protocol.py
diff --git a/utill/db/pymysql/times.py b/kcweb/utill/db/pymysql/times.py
similarity index 100%
rename from utill/db/pymysql/times.py
rename to kcweb/utill/db/pymysql/times.py
diff --git a/utill/db/pymysql/util.py b/kcweb/utill/db/pymysql/util.py
similarity index 100%
rename from utill/db/pymysql/util.py
rename to kcweb/utill/db/pymysql/util.py
diff --git a/utill/db/sqlite.py b/kcweb/utill/db/sqlite.py
similarity index 100%
rename from utill/db/sqlite.py
rename to kcweb/utill/db/sqlite.py
diff --git a/utill/db/sqlitedata/kcwdb b/kcweb/utill/db/sqlitedata/kcwdb
similarity index 100%
rename from utill/db/sqlitedata/kcwdb
rename to kcweb/utill/db/sqlitedata/kcwdb
diff --git a/utill/filetype/__init__.py b/kcweb/utill/filetype/__init__.py
similarity index 100%
rename from utill/filetype/__init__.py
rename to kcweb/utill/filetype/__init__.py
diff --git a/kcweb/utill/filetype/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/filetype/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..154205f26626baa206ea2df39b28c4bddab3b558
Binary files /dev/null and b/kcweb/utill/filetype/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/__pycache__/filetype.cpython-36.pyc b/kcweb/utill/filetype/__pycache__/filetype.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..237061ace833c009eb22c2becefe4e5265194c6e
Binary files /dev/null and b/kcweb/utill/filetype/__pycache__/filetype.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/__pycache__/helpers.cpython-36.pyc b/kcweb/utill/filetype/__pycache__/helpers.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7364051f69e84d4d73ca37d646ec1ca8151e865f
Binary files /dev/null and b/kcweb/utill/filetype/__pycache__/helpers.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/__pycache__/match.cpython-36.pyc b/kcweb/utill/filetype/__pycache__/match.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f14325fa64c7572afbc649705272dde3a5c76718
Binary files /dev/null and b/kcweb/utill/filetype/__pycache__/match.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/__pycache__/utils.cpython-36.pyc b/kcweb/utill/filetype/__pycache__/utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0e423806a12cc727f695120c189bc1927a82a219
Binary files /dev/null and b/kcweb/utill/filetype/__pycache__/utils.cpython-36.pyc differ
diff --git a/utill/filetype/filetype.py b/kcweb/utill/filetype/filetype.py
similarity index 100%
rename from utill/filetype/filetype.py
rename to kcweb/utill/filetype/filetype.py
diff --git a/utill/filetype/helpers.py b/kcweb/utill/filetype/helpers.py
similarity index 100%
rename from utill/filetype/helpers.py
rename to kcweb/utill/filetype/helpers.py
diff --git a/utill/filetype/match.py b/kcweb/utill/filetype/match.py
similarity index 100%
rename from utill/filetype/match.py
rename to kcweb/utill/filetype/match.py
diff --git a/utill/filetype/types/__init__.py b/kcweb/utill/filetype/types/__init__.py
similarity index 100%
rename from utill/filetype/types/__init__.py
rename to kcweb/utill/filetype/types/__init__.py
diff --git a/kcweb/utill/filetype/types/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..904083e8d25c8fae512eb7032aafc3d735c96e2d
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/archive.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/archive.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2e1cccd15ce0ce5ebac7ee26f7eb039762cd9eef
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/archive.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/audio.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/audio.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..943f60d991fd228cc08244b50e09e556a2913397
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/audio.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/base.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/base.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e0397ea0f1f9fab292521aa26aca7c138ae10a0c
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/base.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/font.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/font.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8d3cb8c67417dbe76d1b63f75a61ef663ea76286
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/font.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/image.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/image.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..488dcaeb941ce4b318520719744887005dc6a71f
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/image.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/isobmff.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/isobmff.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bd35125a6d067834526df83407441b1b225bcaee
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/isobmff.cpython-36.pyc differ
diff --git a/kcweb/utill/filetype/types/__pycache__/video.cpython-36.pyc b/kcweb/utill/filetype/types/__pycache__/video.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6536b3fa42c9a881964e317b602a55c2b0d17ad0
Binary files /dev/null and b/kcweb/utill/filetype/types/__pycache__/video.cpython-36.pyc differ
diff --git a/utill/filetype/types/archive.py b/kcweb/utill/filetype/types/archive.py
similarity index 100%
rename from utill/filetype/types/archive.py
rename to kcweb/utill/filetype/types/archive.py
diff --git a/utill/filetype/types/audio.py b/kcweb/utill/filetype/types/audio.py
similarity index 100%
rename from utill/filetype/types/audio.py
rename to kcweb/utill/filetype/types/audio.py
diff --git a/utill/filetype/types/base.py b/kcweb/utill/filetype/types/base.py
similarity index 100%
rename from utill/filetype/types/base.py
rename to kcweb/utill/filetype/types/base.py
diff --git a/utill/filetype/types/font.py b/kcweb/utill/filetype/types/font.py
similarity index 100%
rename from utill/filetype/types/font.py
rename to kcweb/utill/filetype/types/font.py
diff --git a/utill/filetype/types/image.py b/kcweb/utill/filetype/types/image.py
similarity index 100%
rename from utill/filetype/types/image.py
rename to kcweb/utill/filetype/types/image.py
diff --git a/utill/filetype/types/isobmff.py b/kcweb/utill/filetype/types/isobmff.py
similarity index 100%
rename from utill/filetype/types/isobmff.py
rename to kcweb/utill/filetype/types/isobmff.py
diff --git a/utill/filetype/types/video.py b/kcweb/utill/filetype/types/video.py
similarity index 100%
rename from utill/filetype/types/video.py
rename to kcweb/utill/filetype/types/video.py
diff --git a/utill/filetype/utils.py b/kcweb/utill/filetype/utils.py
similarity index 100%
rename from utill/filetype/utils.py
rename to kcweb/utill/filetype/utils.py
diff --git a/utill/http.py b/kcweb/utill/http.py
similarity index 69%
rename from utill/http.py
rename to kcweb/utill/http.py
index e8561bd7b724279db03395f45c2eb9bf8eead97b..9a0b786343ecb83c31f292fceb64612ee646e6e9 100644
--- a/utill/http.py
+++ b/kcweb/utill/http.py
@@ -7,7 +7,7 @@ class Http:
set_proxies=None #设置代理
set_cookies={} #设置请求cookie
set_header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'} #请求头
- set_timeout=10 #超时 20秒
+ set_timeout=10 #超时 10秒
set_max_retries=2 #重试次数 (实际请求3次)
set_verify=False #SSL 证书的验证 sll证书路径
set_encoding="utf-8" #设置text输出编码
@@ -20,8 +20,31 @@ class Http:
get_content='' #获取body响应二进制内容
get_response='' #获取响应对象
get_status_code=None #获取响应状态码
-
+ keep_alive=True #默认的http connection是keep-alive的 False表示关闭
req=None
+ def __init(self):
+ self.set_proxies=None #设置代理
+ self.set_cookies={} #设置请求cookie
+ self.set_header={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'} #请求头
+ self.set_timeout=10 #超时 20秒
+ self.set_max_retries=2 #重试次数 (实际请求3次)
+ self.set_verify=False #SSL 证书的验证 sll证书路径
+ self.set_encoding="utf-8" #设置text输出编码
+ self.set_session=True #是否启用会话
+
+ self.get_header={} #获取响应头
+ self.get_cookies={} #获取最后的响应cookie
+ self.get_cookie_str='' #获取最后的响应cookie 字符串
+ self.get_text='' #获取body响应内容
+ self.get_content='' #获取body响应二进制内容
+ self.get_response='' #获取响应对象
+ self.get_status_code=None #获取响应状态码
+ self.keep_alive=True #默认的http connection是keep-alive的 False表示关闭
+ self.req=None
+ def __init__(self):
+ self.__init()
+ def __del__(self):
+ self.__init()
def gettext(self):
"""得到响应text"""
return self.get_text
@@ -47,11 +70,16 @@ class Http:
self.req = requests.Session()
self.req.mount('http://', requests.adapters.HTTPAdapter(max_retries=self.set_max_retries))
self.req.mount('https://', requests.adapters.HTTPAdapter(max_retries=self.set_max_retries))
+ # print('requests初始化')
else:
if self.req is None:
self.req = requests
+ # print('requests初始化')
+ if not self.keep_alive:
+ self.req.keep_alive=False
if self.set_cookies and isinstance(self.set_cookies,str):
self.cookieserTdict()
+ # print(url,url,data,params,jsonparams,self.set_cookies)
response=self.req.request(method, url,data=data,params=params,json=jsonparams,files=files,proxies=self.set_proxies,cookies=self.set_cookies,headers=self.set_header,timeout=self.set_timeout,verify=self.set_verify,allow_redirects=allow_redirects)
response.encoding=self.set_encoding
self.get_header=dict(response.headers)
@@ -65,6 +93,8 @@ class Http:
if self.get_cookies:
cookies=''
for key in self.get_cookies:
+ if not self.get_cookies[key]:
+ self.get_cookies[key]=''
cookies=cookies+key+"="+self.get_cookies[key]+";"
self.get_cookie_str=cookies
self.get_text=response.text
diff --git a/utill/queues.py b/kcweb/utill/queues.py
similarity index 97%
rename from utill/queues.py
rename to kcweb/utill/queues.py
index ae6b8c090d97c4f6e2ef074fde13d643a47c2199..c11f3eeb3548317ddb0572ab1c4a01ae6fcd0fd0 100644
--- a/utill/queues.py
+++ b/kcweb/utill/queues.py
@@ -108,6 +108,12 @@ class Queues():
def delwhere(where):
"通过where条件删除 (不推荐使用)"
return kcwsqlite.sqlite().connect(queuesdbpath).table("model_kcweb_queues").where(where).delete()
+ def seltitle(title):
+ "通过标题查询 (不推荐使用)"
+ try:
+ return kcwsqlite.sqlite().connect(queuesdbpath).table("model_kcweb_queues").where("title='"+title+"'").select()
+ except:
+ return ''
def setfield(taskid,key,value):
"""设置指定字段(不建议使用)"""
try:
diff --git a/utill/redis.py b/kcweb/utill/redis.py
similarity index 99%
rename from utill/redis.py
rename to kcweb/utill/redis.py
index ba3c1e15cbe8fd695568ec1967e9eeb5a2f47b76..db5a889467729daa20cda8e9fbb6940353b7e1a6 100644
--- a/utill/redis.py
+++ b/kcweb/utill/redis.py
@@ -28,6 +28,7 @@ class redis:
self.__redisObj=red.Redis(host=self.__config['host'],password=self.__config['password'],port=self.__config['port'],db=self.__config['db'])
else:
self.__redisObj=red.Redis(host=self.__config['host'],port=self.__config['port'],db=self.__config['db'])
+
if config.app['app_debug']:
print("建立redis连接",self.__identifier)
@@ -69,7 +70,8 @@ class redis:
return self
def redisObj(self):
"得到一个redis连接对象,执行更多高级操作"
- self.__connects()
+ if not self.__redisObj:
+ self.__connects()
return self.__redisObj
def getstr(self,name):
"""获取name的值
diff --git a/utill/rediss/__init__.py b/kcweb/utill/rediss/__init__.py
similarity index 100%
rename from utill/rediss/__init__.py
rename to kcweb/utill/rediss/__init__.py
diff --git a/kcweb/utill/rediss/__pycache__/__init__.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c25f98a7d63fded4a0731248bb99c64b1c6f80c6
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/__init__.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/_compat.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/_compat.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..efde0f6138549c9c6b28c10f9a7c2014742083f2
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/_compat.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/client.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/client.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..eacb05fb13b854f9895ad29aec80643f7f1e6144
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/client.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/connection.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/connection.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..26c19a91523bb17fc00347a542a9c296a34adba3
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/connection.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/exceptions.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/exceptions.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7a04b8fe392d707800ca7a2d9effd3f7d60318fc
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/exceptions.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/lock.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/lock.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..81d948feb06391b381a151d78c3c95ef70913daa
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/lock.cpython-36.pyc differ
diff --git a/kcweb/utill/rediss/__pycache__/utils.cpython-36.pyc b/kcweb/utill/rediss/__pycache__/utils.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f70007565a60e40925f0e770411cabb0d5d2626c
Binary files /dev/null and b/kcweb/utill/rediss/__pycache__/utils.cpython-36.pyc differ
diff --git a/utill/rediss/_compat.py b/kcweb/utill/rediss/_compat.py
similarity index 100%
rename from utill/rediss/_compat.py
rename to kcweb/utill/rediss/_compat.py
diff --git a/utill/rediss/client.py b/kcweb/utill/rediss/client.py
similarity index 100%
rename from utill/rediss/client.py
rename to kcweb/utill/rediss/client.py
diff --git a/utill/rediss/connection.py b/kcweb/utill/rediss/connection.py
similarity index 100%
rename from utill/rediss/connection.py
rename to kcweb/utill/rediss/connection.py
diff --git a/utill/rediss/exceptions.py b/kcweb/utill/rediss/exceptions.py
similarity index 100%
rename from utill/rediss/exceptions.py
rename to kcweb/utill/rediss/exceptions.py
diff --git a/utill/rediss/lock.py b/kcweb/utill/rediss/lock.py
similarity index 100%
rename from utill/rediss/lock.py
rename to kcweb/utill/rediss/lock.py
diff --git a/utill/rediss/sentinel.py b/kcweb/utill/rediss/sentinel.py
similarity index 100%
rename from utill/rediss/sentinel.py
rename to kcweb/utill/rediss/sentinel.py
diff --git a/utill/rediss/utils.py b/kcweb/utill/rediss/utils.py
similarity index 100%
rename from utill/rediss/utils.py
rename to kcweb/utill/rediss/utils.py
diff --git a/setup.py b/setup.py
index e972b327b53eeebcadad711c35d046f5ed3a17ff..a05dc375f11f8637900a55c84f32a2c487a13c54 100644
--- a/setup.py
+++ b/setup.py
@@ -1,11 +1,12 @@
-# python3 setup.py sdist upload
-# python setup.py sdist upload
+# 打包上传 python setup.py sdist upload
+# 打包 python setup.py sdist
# twine upload --repository-url https://test.pypi.org/legacy/ dist/* #上传到测试
# pip install --index-url https://pypi.org/simple/ kcweb #安装测试服务上的kcweb pip3 install kcweb==4.12.4 -i https://pypi.org/simple/
+# 安装 python setup.py install
#############################################
from setuptools import setup, find_packages,Extension
-import os,shutil
+import os
def file_get_content(k):
"获取文件内容"
if os.path.isfile(k):
@@ -17,14 +18,14 @@ def file_get_content(k):
return con
confkcw={}
confkcw['name']='kcweb' #项目的名称
-confkcw['version']='4.13.26' #项目版本
-confkcw['description']='' #项目的简单描述
-confkcw['long_description']="mysql优化" #项目详细描述
+confkcw['version']='5.328' #项目版本
+confkcw['description']='kcweb作为web开发而设计的高性能框架,采用全新的架构思想,注重易用性。遵循MIT开源许可协议发布,意味着个人和企业可以免费使用kcweb,甚至允许把你基于kcweb开发的应用开源或商业产品发布或销售' #项目的简单描述
+confkcw['long_description']="增加 kcweb 命令" #项目详细描述
confkcw['license']='MIT License' #开源协议 mit开源
confkcw['url']=''
-confkcw['author']='禄可集团-坤坤' #名字
+confkcw['author']='坤坤' #名字
confkcw['author_email']='fk1402936534@qq.com' #邮件地址
-confkcw['maintainer']='坤坤' #维护人员的名字
+confkcw['maintainer']='百里' #维护人员的名字
confkcw['maintainer_email']='fk1402936534@qq.com' #维护人员的邮件地址
def get_file(folder='./',lists=[]):
lis=os.listdir(folder)
@@ -53,8 +54,13 @@ setup(
url=confkcw['url'],
packages = b,
# data_files=[('Scripts', ['kcweb/bin/kcw.exe'])],
- install_requires = ['pymongo>=3.10.0','Mako>=1.1.2','requests>=2.23.0','six>=1.12.0','watchdog>=0.9.0','websockets==8.1'], #第三方包
+ install_requires = ['gunicorn==20.0.4','pymongo>=3.10.0','Mako>=1.1.2','requests>=2.23.0','six>=1.12.0','watchdog>=0.9.0','websockets==8.1','psutil==5.8.0'], #第三方包
package_data = {
'': ['*.html', '*.js','*.css','*.jpg','*.png','*.gif'],
+ },
+ entry_points = {
+ 'console_scripts':[
+ 'kcweb = kcweb.kcweb:executable'
+ ]
}
)
\ No newline at end of file
diff --git a/utill/db/sqlite copy.py b/utill/db/sqlite copy.py
deleted file mode 100644
index ba6140e4864d52bc452e473eb630d9a117debd11..0000000000000000000000000000000000000000
--- a/utill/db/sqlite copy.py
+++ /dev/null
@@ -1,685 +0,0 @@
-# -*- coding: utf-8 -*-
-from kcweb.config import sqlite as sqliteconfig
-import time,traceback,re
-import random,sqlite3,os,hashlib
-class sqlite:
- __config=sqliteconfig
- __configt={}
- __conn={}
- __cursor={}
- __sql=None
- __sqls=None
- def md5(self,strs):
- """md5加密
-
- 参数 strs:要加密的字符串
-
- return String类型
- """
- m = hashlib.md5()
- b = strs.encode(encoding='utf-8')
- m.update(b)
- return m.hexdigest()
- def close(self):
- "关闭连接"
- for k in sqlite.__conn.keys():
- sqlite.__cursor[k].close()
- sqlite.__conn[k].close()
- sqlite.__conn={}
- sqlite.__cursor={}
- sqlite.__configt={}
- def __setconn(self):
- if not self.__configt:
- self.__configt=sqliteconfig
- try:
- self.__conn[self.md5(self.__configt['db'])]
- except KeyError:
- try:
- if '/' in self.__configt['db']:
- self.__conn[self.md5(self.__configt['db'])] = sqlite3.connect(self.__configt['db'],check_same_thread=False)
- else:
- self.__conn[self.md5(self.__configt['db'])] = sqlite3.connect(os.path.split(os.path.realpath(__file__))[0]+"/sqlitedata/"+self.__configt['db'],check_same_thread=False)
- except Exception as e:
- raise Exception(e)
- self.__cursor[self.md5(self.__configt['db'])]=self.__conn[self.md5(self.__configt['db'])].cursor()
- def __execute(self,typess='DQL'):
- self.__setconn()
- # print(self.__sql)
- try:
- res=self.__cursor[self.md5(self.__configt['db'])].execute(self.__sql)
- except Exception as e:
-
- raise Exception(e)
- else:
- return res
- def connect(self,config):
- if isinstance(config,str):
- self.__configt['db']=config
- elif isinstance(config,dict):
- if 'db' in config:
- self.__configt['db']=config['db']
- return self
- __table=""
- def table(self,table):
- """设置表名
-
- 参数 table:str 表名
- """
- self.__table=table
- return self
- def query(self,sql):
- self.__sql=sql
- self.__execute(sql,'DQL')
- # self.close()
- def execute(self,sql):
- self.__sql=sql
- res=self.__execute('DML')
- rowcount=res.rowcount
- # self.close()
- return rowcount
- # def create_table(self):
- # self.__sql=("CREATE TABLE "+self.__table+
- # "(ID INT PRIMARY KEY NOT NULL,"+
- # "NAME TEXT NOT NULL,"+
- # "AGE INT NOT NULL,"+
- # "ADDRESS CHAR(50),"+
- # "SALARY REAL);")
- # # print(self.__sql)
- # # exit()
- # self.execute(self.__sql)
- def select(self,id=None):
- """select查询
-
- 返回 list(列表)
- """
- if id :
- self.__where="id=%d" % id
- self.__setsql()
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- self.__None()
- return self.__sqls
- self.__execute()
- description=self.__cursor[self.md5(self.__configt['db'])].description #获取字段
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- lists=[]
- data_dict=[]
- for field in description:#获取字段
- data_dict.append(field[0])
- for k in result:
- i=0
- dicts={}
- for j in k:
- dicts[data_dict[i]]=j
- i=i+1
- lists.append(dicts)
- self.__None(table=False)
- return lists
- def find(self,id=None):
- """查询一条记录
-
- 返回 字典
- """
- if id :
- self.__where="id=%s" % id
- self.limit(1)
- self.__setsql()
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- self.__None()
- return self.__sqls
-
- self.__execute()
- description=self.__cursor[self.md5(self.__configt['db'])].description #获取字段
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- data_dict=[]
- for field in description:#获取字段
- data_dict.append(field[0])
- dicts={}
- for k in result:
- i=0
- for j in k:
- dicts[data_dict[i]]=j
- i=i+1
- self.__None(table=False)
- return dicts
- def count(self,field="*"):
- """查询数量
-
- 返回 int 数字
- """
- self.__field=field
- self.__setsql('count')
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- return self.__sql
- self.__execute()
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- if self.__group:
- cou=len(result)
- else:
- try:
- cou=int(result[0][0])
- except IndexError:
- cou=0
- self.__None(table=False)
- return cou
- def max(self,field):
- """查询某字段的最大值
-
- 返回 int 数字
- """
- self.__field=field
- self.__setsql('max')
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- return self.__sql
- self.__execute()
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- cou=int(result[0][0])
- self.__None(table=False)
- return cou
- def min(self,field):
- """查询某字段的最小值
-
- 返回 int 数字
- """
- self.__field=field
- self.__setsql('min')
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- return self.__sql
- self.__execute()
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- cou=int(result[0][0])
- self.__None(table=False)
- return cou
- def avg(self,field):
- """查询某字段的平均值
-
- 返回 int 数字
- """
- self.__field=field
- self.__setsql('avg')
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- return self.__sql
- self.__execute()
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- cou=int(result[0][0])
- self.__None(table=False)
- return cou
- def sum(self,field):
- """查询某字段之和
-
- 返回 int 数字
- """
- self.__field=field
- self.__setsql('sum')
- if self.__buildSql:
- self.__sqls="("+self.__sql+")"
- return self.__sql
- self.__execute()
- result = self.__cursor[self.md5(self.__configt['db'])].fetchall() #获取查询结果
- # self.close()
- cou=int(result[0][0])
- self.__None(table=False)
- return cou
- def update(self,data,affair=False):
- """数据表更新
-
- 参数 data 要更新的内容 格式:{"name":"测试","age":20}
-
- 参数 affair 是否开启事务 True表示手动提交事务 False表示自动提交事务
- """
- self.__setsql('update',data)
- res=self.__execute('DML')
- if affair==False and self.__startTrans==False:
- self.commit()
- rowcount=res.rowcount
- # self.close()
- self.__None(table=False)
- return rowcount
- def delete(self,affair=False):
- """数据表删除
-
- 参数 affair 是否开启事务 True表示手动提交事务 False表示自动提交事务
- """
- self.__setsql('delete')
- if self.__where:
- res=self.__execute('DML')
- else:
- return 0
- if affair==False and self.__startTrans==False:
- self.commit()
- rowcount=res.rowcount
- # self.close()
- self.__None(table=False)
- return rowcount
- def insert(self,dicts,affair=False):
- """插入数据库 单条插入或多条插入
-
- 参数 dicts 要插入的内容 单条格式:{"name":"测试","age":20} 。 多条格式:[{"name":"测试","age":20},{"name":"测试","age":20}]
-
- 参数 affair 是否开启事务 True表示手动提交事务 False表示自动提交事务
-
- 返回插入的数量
- """
- self.__setsql('insert',dicts)
- res=self.__execute('DML')
- if affair==False and self.__startTrans==False:
- self.commit()
- rowcount=res.rowcount
- # self.close()
- self.__None(table=False)
- return rowcount
- __startTrans=False
- def startTrans(self):
- "开启事务,仅对 update方法、delete方法、install方法有效"
- self.__startTrans=True
- def commit(self):
- """事务提交
-
- 增删改后的任务进行提交
- """
- self.__conn[self.md5(self.__configt['db'])].commit()
- def rollback(self):
- """事务回滚
-
- 增删改后的任务进行撤销
- """
- self.__conn[self.md5(self.__configt['db'])].rollback()
- def getsql(self):
- """得到生成的sql语句"""
- return self.__sql
- __buildSql=None
- def buildSql(self):
- """构造子查询"""
- self.__buildSql=True
- return self
- def __None(self,table=True):
- "清除所有赋值条件"
- self.__lock=None
- self.__distinct=None
- self.__join=None
- self.__joinstr=''
- self.__alias=None
- self.__having=None
- self.__group=None
- self.__group1=None
- self.__order=None
- self.__order1=None
- self.__limit=None
- self.__field="*"
- self.__where=None
- self.__wheres=()
- self.__buildSql=None
- if table:
- self.__table=None
- __where=None
- __wheres=()
- def where(self,where = None,*wheres):
- """设置过滤条件
-
- 传入方式:
- "id",2 表示id='2'
-
- "id","in",2,3,4,5,6,...表示 id in (2,3,4,5,6,...)
-
- "id","in",[2,3,4,5,6,...]表示 id in (2,3,4,5,6,...)
-
- [("id","gt",6000),"and",("name","like","%超")] 表示 ( id > "6000" and name LIKE "%超" )
-
- "id","eq",1 表示 id = '1'
-
- eq 等于
- neq 不等于
- gt 大于
- egt 大于等于
- lt 小于
- elt 小于等于
- like LIKE
- """
- self.__where=where
- self.__wheres=wheres
- # print(len(self.__wheres))
- return self
- __field='*'
- def field(self,field = "*"):
- """设置过滤显示条件
-
- 参数 field:str 字符串
- """
- self.__field=field
- return self
- __limit=[]
- def limit(self,offset, length = None):
- """设置查询数量
-
- 参数 offset:int 起始位置
-
- 参数 length:int 查询数量
- """
- self.__limit=[offset,length]
- return self
- def page(self,pagenow=1, length = 20):
- """设置分页查询
-
- 参数 pagenow:int 页码
-
- 参数 length:int 查询数量
- """
- offset=(pagenow-1)*length
- self.__limit=[offset,length]
- return self
- __order=None
- __order1=None
- def order(self,strs=None,*strs1):
- """设置排序查询
-
- 传入方式:
-
- "id desc"
-
- "id",'name','appkey','asc'
-
- "id",'name','appkey' 不包含asc或desc的情况下 默认是desc
-
- ['id','taskid',{"task_id":"desc"}]
- """
- self.__order=strs
- self.__order1=strs1
- return self
- __group=None
- __group1=None
- def group(self,strs=None,*strs1):
- """设置分组查询
-
- 传入方式:
-
- "id,name"
-
- "id","name"
- """
- self.__group=strs
- self.__group1=strs1
- return self
- __having=None
- def having(self,strs=None):
- """用于配合group方法完成从分组的结果中筛选(通常是聚合条件)数据
-
- 参数 strs:string 如:"count(time)>3"
- """
- self.__having=strs
- return self
-
- __alias=None
- def alias(self,strs=None):
- """用于设置当前数据表的别名,便于使用其他的连贯操作例如join方法等。
-
- 参数 strs:string 默认当前表作为别名
- """
- if strs:
- self.__alias=strs
- else:
- self.__alias=self.__table
- return self
- __join=None
- __joinstr=''
- def join(self,strs,on=None,types='INNER'):
- """用于根据两个或多个表中的列之间的关系,从这些表中查询数据
-
- 参数 strs string 如:"test t1" test表设置别名t1
-
- 参数 on string 如:"t1.id=t2.pid" 设置连接条件
-
- 参数 types 支持INNER、LEFT、RIGHT、FULL 默认INNER
-
- """
- joinstr=''
- if strs and on:
- joinstr=joinstr+types+" JOIN "+strs+" ON "+on+" "
- if joinstr:
- self.__joinstr=self.__joinstr+joinstr
- return self
- __distinct=None
- def distinct(self,bools=None):
- "用于返回唯一不同的值,配合field方法使用生效,消除所有重复的记录,并只获取唯一一次记录。"
- self.__distinct=bools
- return self
- __lock=None
- def lock(self,strs=None):
- """用于数据库的锁机制,在查询或者执行操作的时候使用 (暂未实现)
-
- 排他锁 (Exclusive lock)
-
- 共享锁 (Shared lock)
-
- 参数 strs 如:True表示自动在生成的SQL语句最后加上FOR UPDATE,
-
-
- """
- # self.__lock=strs
- return self
- def __setsql(self,types=None,data = {}):
- """生成sql语句"""
- if types==None:
- self.__sql="SELECT"
- if self.__distinct and self.__field:
- self.__sql=self.__sql+" DISTINCT"
- if self.__alias:
- self.__sql=self.__sql+" %s FROM %s %s" % (self.__field,self.__table,self.__alias)
- else:
- self.__sql=self.__sql+" %s FROM %s" % (self.__field,self.__table)
- elif types=='count':
- self.__sql="SELECT COUNT(%s) FROM %s" % (self.__field,self.__table)
- elif types=='max':
- self.__sql="SELECT MAX(%s) FROM %s" % (self.__field,self.__table)
- elif types=='min':
- self.__sql="SELECT MIN(%s) FROM %s" % (self.__field,self.__table)
- elif types=='avg':
- self.__sql="SELECT AVG(%s) FROM %s" % (self.__field,self.__table)
- elif types=='sum':
- self.__sql="SELECT SUM(%s) FROM %s" % (self.__field,self.__table)
- elif types=='update':
- strs=''
- for k in data:
- if isinstance(data[k],str):
- strs=strs+" %s = '%s' ," % (k,self.escape_string(data[k]))
- else:
- strs=strs+" %s = %s ," % (k,data[k])
- strs=strs[:-1]
- self.__sql="UPDATE %s SET %s" % (self.__table,strs)
- # print(self.__sql)
- elif types=='delete':
- self.__sql="DELETE FROM %s" % (self.__table)
- elif types=='insert':
- if isinstance(data,dict):
- strs=''
- val=''
- for k in data:
- strs=strs+"%s," % k
- if isinstance(data[k],str):
- val=val+"'%s'," % self.escape_string(data[k])
- else:
- val=val+"%s," % data[k]
- strs=strs[:-1]
- val=val[:-1]
- self.__sql="INSERT INTO "+str(self.__table)+" ("+strs+") VALUES ("+val+")"
- # print(self.__sql)
- elif isinstance(data,list):
- strs=''
- val='('
- for k in data[0]:
- strs=strs+" , "+k
- for k in data:
- for j in k:
- if isinstance(k[j],str):
- val=val+"'"+str(k[j])+"',"
- else:
- val=val+str(k[j])+","
- val=val[:-1]
- val=val+"),("
- val=val[:-2]
- self.__sql="INSERT INTO "+str(self.__table)+" ("+strs[3:]+") VALUES "+val
-
- if self.__joinstr:
- # print(self.__sql)
- self.__sql=self.__sql+" "+self.__joinstr
- if self.__where:
- if isinstance(self.__where,str):
- if self.__wheres:
- if len(self.__wheres) == 2:
- if isinstance(self.__wheres[1],list):
- self.__sql=self.__sql + " WHERE %s %s (" % (self.__where,self.__operator(self.__wheres[0]))
- for k in self.__wheres[1]:
- self.__sql=self.__sql+str(k)+","
- self.__sql=self.__sql[:-1]+")"
- else:
- self.__sql=self.__sql + " WHERE %s %s '%s'" % (self.__where,self.__operator(self.__wheres[0]),self.__wheres[1])
- elif len(self.__wheres) > 2:
- if self.__wheres[0]=='in':
- strs=str(self.__wheres[1])
- i=0
- for k in self.__wheres:
- if i > 1:
- strs=strs+","+str(k)
- i=i+1
- self.__sql=self.__sql + " WHERE %s in (%s)" % (self.__where,strs)
- else:
- self.__sql=self.__sql + " WHERE %s = '%s'" % (self.__where,self.__wheres[0])
- else:
- self.__sql=self.__sql + " WHERE %s" % self.__where
- elif isinstance(self.__where,list):
- self.__sql=self.__sql + " WHERE %s" % self.__listTrans()
- else:
- print("参数where类型错误",type(self.__where),self.__where)
- if self.__order:
- s=''
- if isinstance(self.__order,list):
- for strs in self.__order:
- if isinstance(strs,str):
- s=s+strs+","
- else:
- pass
- for key in strs:
- s=s+key+" "+strs[key]
- s=s+","
- s=s[:-1]
- if isinstance(self.__order,str):
- if self.__order1:
- if len(self.__order1) > 1:
- if self.__order1[len(self.__order1)-1] == 'desc' or self.__order1[len(self.__order1)-1] == 'asc':
- i=0
- while i