rabin 6 years ago
parent
commit
2c94ca7cd1

+ 3 - 0
MANIFEST.in

@@ -0,0 +1,3 @@
+include requirements.txt
+include README.rst
+include LICENSE

+ 7 - 0
README.rst

@@ -0,0 +1,7 @@
+# demeter框架
+
+开发语言:python
+框架:gevent+tornado+demeter类库
+
+安装:
+pip git+https://github.com/shemic/demeter

+ 6 - 3
demeter/core.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-	demeter core
-	name:demeter.py
+	demeter
+	name:core.py
 	author:rabin
 """
 import time
@@ -15,11 +15,13 @@ import ConfigParser
 import subprocess
 class Demeter(object):
 	path = ''
+	root = ''
 	config = {}
 	serviceObj = {}
 	modelObj = {}
 	web = ''
 	request = False
+	route = []
 
 	def __new__(self, *args, **kwargs):
 		sys.exit()
@@ -39,6 +41,7 @@ class Demeter(object):
 	@classmethod
 	def initConfig(self):
 		self.path = File.path()
+		self.root = File.cur_path()
 		if self.config == {}:
 			name = 'dev'
 			if 'DEMETER_CONF' in os.environ:
@@ -156,7 +159,7 @@ class Demeter(object):
 			return True
 
 	@classmethod
-	def webstart(self, name):
+	def web(self, name):
 		self.web = name
 		self.webPath = self.path + self.web + '/'
 		self.getObject('main', name + '.')

+ 1 - 1
demeter/db.py

@@ -1,6 +1,6 @@
 # -*- coding: utf-8 -*-
 """
-    demeter database
+    demeter
     name:db.py
     author:rabin
 """

+ 2 - 2
demeter/model.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-    demeter database
-    name:__base__.py
+    demeter
+    name:model.py
     author:rabin
 """
 import os

+ 2 - 2
demeter/mqtt.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-    demeter mqtt
-    name:connect.py
+    demeter
+    name:mqtt.py
     author:rabin
 """
 from demeter.core import *

+ 2 - 7
demeter/service.py

@@ -1,14 +1,13 @@
 # -*- coding: utf-8 -*-
 """
-    demeter service
-    name:service.py 通用业务
+    demeter
+    name:service.py
     author:rabin
 """
 from demeter.core import *
 
 class Service(object):
 
-	# 获取某个model下的列表数据
 	def list(self, name, state = True, search=None, page=False, order='cdate desc', limit = '0,100'):
 		model = self.model(name)
 		model.state = state
@@ -28,7 +27,6 @@ class Service(object):
 		data = model.select(page=page, order=order, limit=limit)
 		return data
 
-	# 获取某个model下的数据
 	def one(self, name, **kwd):
 		model = self.model(name)
 		if kwd:
@@ -37,7 +35,6 @@ class Service(object):
 		data = model.select(type='fetchone')
 		return data
 
-	# 更新
 	def update(self, name, id, data, cdate=True):
 		model = self.model(name)
 		if id:
@@ -54,13 +51,11 @@ class Service(object):
 				self.assgin(model, key, value, method)
 			return model.insert()
 
-	# 删除
 	def delete(self, name, id, state = False):
 		model = self.model(name)
 		model.id = id
 		return model.update(state=state)
 
-	# 物理删除
 	def rDelete(self, name, id):
 		model = self.model(name)
 		model.id = id

+ 2 - 2
demeter/tcp.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-	demeter tcp
-	name:server.py
+	demeter
+	name:tcp.py
 	author:rabin
 """
 import socket  

+ 15 - 4
demeter/web.py

@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """
-	demeter web
-	name:application.py
+	demeter
+	name:web.py
 	author:rabin
 """
 from gevent import monkey
@@ -221,6 +221,16 @@ class Web(object):
 			#return gevent.spawn(method, self, *args, **kwargs)
 		return callback
 
+	@classmethod
+	def load(self, file, local):
+		path = os.path.split(os.path.realpath(file))[0] + '/'
+		files = self.file(path)
+		url = []
+		for key in files:
+			module = __import__(key, local)
+			url = self.url(module, key, url)
+		Demeter.route = Demeter.route + url
+
 	@staticmethod
 	def file(path):
 		files = os.listdir(path)
@@ -248,7 +258,8 @@ class Web(object):
 				url.append((r'/'+key+'/'+act, attr))
 		return url
 	@staticmethod
-	def start(url):
+	def start():
+		print Demeter.route
 		config = Demeter.config[Demeter.web]
 		cookie = False
 		if 'xsrf_cookies' in config:
@@ -272,7 +283,7 @@ class Web(object):
 			handlers.append((r"/camera/(.*)", tornado.web.StaticFileHandler, {"path": Demeter.path + 'runtime/camera/'}))
 			handlers.append((r"/static/(.*)", tornado.web.StaticFileHandler, {"path":"static"}))
 			handlers.append((r"/(apple-touch-icon\.png)", tornado.web.StaticFileHandler, dict(path=settings['static_path'])))
-			handlers.extend(url)
+			handlers.extend(Demeter.route)
 
 		application_setting()
 		application = tornado.web.Application(handlers=handlers, **settings)

+ 10 - 0
demos/helloworld/admin.py

@@ -0,0 +1,10 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:admin.py
+    author:rabin
+"""
+from demeter.core import *
+
+if __name__ == "__main__":
+	Demeter.web('admin')

+ 1 - 0
demos/helloworld/admin/__init__.py

@@ -0,0 +1 @@
+# -*- coding: utf-8 -*-

+ 5 - 0
demos/helloworld/admin/main.py

@@ -0,0 +1,5 @@
+# -*- coding: utf-8 -*-
+from demeter.web import *
+from demeter.admin.page import *
+from page import *
+Web.start()

+ 52 - 0
demos/helloworld/admin/page/__init__.py

@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+Web.load(__file__, globals())
+
+
+class Load(Base):
+    KEYS = ('admin',)
+
+    def setting(self):
+        self.search()
+        self.admin()
+
+    def admin(self):
+        admin = 1
+        self.data['auth'] = True
+        
+        if 'admin' in self.data['setting'] and self.data['setting']['admin'] > 0:
+            self.data['setting']['adminInfo'] = self.service('common').one('manage_admin', id=self.data['setting']['admin'])
+            if self.data['setting']['adminInfo']:
+                self.data['setting']['roleInfo'] = self.service('common').one('manage_role', id=self.data['setting']['adminInfo']['role_id'])
+        else:
+            #self.redirect('/user/login')
+            return
+
+        self.data['setting']['menuList'] = self.menu()
+
+        if self.data['setting']['adminInfo']['id'] == admin:
+            if 'menu' in self.data['setting']:
+                del self.data['setting']['menu']
+        else:
+            self.data['setting']['menu'] = ['_/', '_/login', '_/main', '_/admin/log_update']
+            menu = self.data['setting']['roleInfo']['auth'] + ','
+            for i,j in enumerate(self.data['setting']['menuList'][1]):
+                m = 0
+                for n in j[0]:
+                    if n+',' in menu:
+                        l = str(i)+'_'+str(n)
+                        self.data['setting']['menu'].append(l)
+                        self.data['setting']['menu'].append(l + '_update')
+                    m = m + 1
+            self.data['setting']['menu'] = ',' + ",".join(self.data['setting']['menu'])+','
+
+            uri = '_' + self.request.uri + ','
+            if self.data['setting']['admin'] != admin and uri not in self.data['setting']['menu']:
+                self.data['auth'] = False
+
+    def menu(self):
+        parent = [['站点设置', '基础设置'],['', '']]
+        child = [
+            [['/site/site', '/site/product'],['站点管理', '抢购商品设置']]
+            ,[['/admin/admin','/admin/role', '/admin/log'],['管理员设置', '管理权限设置', '系统日志']]
+            ]
+        return (parent,child)

+ 135 - 0
demos/helloworld/admin/page/site.py

@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter web page
+    name:site.py 站点相关
+    author:rabin
+"""
+
+class site_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.common(
+			name = u'站点管理'
+			,path = '/site/site'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','workdate-time-start','workdate-time-end','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'站点名称'))
+			,thead = (u'站点名称', u'快捷功能', u'更新时间')
+			,tbody = ('name','func', 'cdate')
+			,state = True
+		)
+		menu = (
+			{'name':'抢购商品管理', 'url':'/site/product'}
+			,
+			)
+		self.commonList('site')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				id = str(value['id'])
+				param = '?search_site_id-select-=' + id
+				self.data['list'][key]['func'] = ''
+				for i in menu:
+					self.data['list'][key]['func'] = self.data['list'][key]['func'] + '<a href="'+i['url']+''+param+'">'+i['name']+'</a>&nbsp;&nbsp;&nbsp;&nbsp;'
+		self.commonView('list')
+
+class site_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.common(
+			path = '/site/site'
+			,label = (u'站点名称',u'站点网址',u'登录页链接',u'登录账号',u'登录密码')
+			,update = ('name-input-required','link-input-required','login_link-input-required','username-input-required','password-password-required')
+		)
+		self.commonOne('site')
+		self.commonView('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.commonUpdate('site')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.commonDelete('site')
+
+class product_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.common(
+			name = u'抢购商品'
+			,path = '/site/product'
+			,width = '600'
+			,height = '600'
+			,search = (('label-1','cdate-time-start','cdate-time-end','site_id-select-','name-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'选择站点',u'商品名'))
+			,thead = (u'所属站点', u'商品名', u'状态', u'更新时间')
+			,tbody = ('site', 'name', 'status', 'cdate')
+			,state = True
+		)
+		self.data['common']['search_site_id-select-'] = self.service('common').list('site')
+		self.commonList('product')
+		status = {}
+		status[1] = '待机'
+		status[2] = '入队'
+		status[3] = '抢购中'
+		status[4] = '抢购完成'
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				site = self.service('common').one('site', id=value['site_id'])
+				self.data['list'][key]['site'] = site['name']
+				self.data['list'][key]['status'] = '<a href="/site/order?search_product_id-select-='+str(value['id'])+'">'+status[value['status']]+'[查看二维码]</a>'
+
+		self.commonView('list')
+
+class product_update_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		status = [
+			{'id':'1', 'name': '待机-如果之前抢购完成,选择此项可以重新开始抢购'},
+		]
+		self.common(
+			path = '/site/product'
+			,label = (u'所属站点', u'商品名称', u'商品链接', u'状态控制')
+			,update = ('site_id-select-required', 'name-input-required','link-input-required', 'status-select-required')
+			,update_site_id = self.service('common').list('site')
+			,update_status = status
+		)
+		self.commonOne('product')
+		self.commonView('update')
+	@Web.auth
+	@Web.setting
+	def post(self):
+		self.commonUpdate('product')
+	@Web.auth
+	@Web.setting
+	def delete(self):
+		self.commonDelete('product')
+
+class order_path(Load):
+	@Web.auth
+	@Web.setting
+	def get(self):
+		self.common(
+			name = u'商品订单列表'
+			,path = '/site/order'
+			,width = '600'
+			,height = '600'
+			,edit = False
+			,add = False
+			,search = (('label-1','cdate-time-start','cdate-time-end', 'orderID-input-mlike'), (u'日期范围',u'开始时间',u'截止时间',u'订单ID'))
+			,thead = (u'商品名称', u'订单ID', u'二维码', u'更新时间')
+			,tbody = ('name', 'orderID', 'pic', 'cdate')
+			,state = False
+		)
+		#self.data['common']['search_product_id-select-'] = self.service('common').list('product')
+		self.commonList('order')
+		if self.data['list']:
+			for key, value in enumerate(self.data['list']):
+				product = self.service('common').one('product', id=value['product_id'])
+				self.data['list'][key]['name'] = product['name']
+				value['pic'] = value['pic'].replace(Demeter.path + 'runtime', '')
+				self.data['list'][key]['pic'] = '<img src="'+value['pic']+'" width="200px" />'
+
+		self.commonView('list')

+ 29 - 0
demos/helloworld/conf/dev.conf

@@ -0,0 +1,29 @@
+[base]
+
+[setting]
+name				= 抢购平台
+site				= http://www.dever.cc/
+copyright			= 2017 dever.cc v1.0.0
+phantomjs			= http://192.168.15.10:8910/
+
+[db]
+rdb					= postgresql
+
+[postgresql]
+host				= 0.0.0.0
+port				= 5432
+username			= postgres
+password			= 123456
+dbname				= buy
+prefix				= demeter
+;允许自动建表
+create				= True
+
+;后台配置
+[admin]
+port				= 8087
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0

+ 30 - 0
demos/helloworld/conf/env.conf

@@ -0,0 +1,30 @@
+[base]
+
+[setting]
+name				= 抢购程序
+site				= http://www.dever.cc/
+copyright			= 2017 dever.cc v1.0.0
+phantomjs			= http://py-phantomjs:8910/
+
+[db]
+;rdb				= mysql
+rdb					= postgresql
+
+[mysql]
+host				= buy-mysql
+port				= 5432
+username			= root
+password			= 123456
+dbname				= buy
+prefix				= demeter
+;允许自动建表
+create				= True
+
+;后台配置
+[admin]
+port				= 8087
+debug				= True
+;请求的buffersize
+max_buffer_size		= 210763776
+;子进程
+process				= 0

+ 25 - 0
demos/helloworld/install.py

@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+from demeter.core import *
+
+def manage():
+	model = Demeter.model('manage_admin')
+	model.id = 1
+	info = model.select(type='fetchone')
+	if not info:
+		model.role_id = 1
+		model.username = 'admin'
+		model.mobile = '15810090845'
+		model.password = '123456'
+		model.insert()
+
+	model = Demeter.model('manage_role')
+	model.id = 1
+	info = model.select(type='fetchone')
+	if not info:
+		model.name = '管理员'
+		model.insert()
+
+manage()
+
+print 'install success!'

+ 6 - 0
demos/helloworld/model/__init__.py

@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter init
+    author:rabin
+"""

+ 9 - 0
demos/helloworld/model/__load__.py

@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:__load__.py
+    author:rabin
+"""
+from demeter.model import *
+from demeter.core import *

+ 19 - 0
demos/helloworld/model/manage_admin.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:manage_admin.py
+    author:rabin
+"""
+from __load__ import *
+
+class Manage_admin(Model):
+	__table__ = 'manage_admin'
+	__comment__ = '超级管理员'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='管理员ID')
+	role_id = Fields(type='int', comment='角色ID')
+	username = Fields(type='varchar(50)', comment='管理员账号')
+	mobile = Fields(type='bigint', comment='园区管理员手机号', unique=True)
+	password = Fields(type='varchar(38)', comment='安全密码', md5=True)
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 19 - 0
demos/helloworld/model/manage_log.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:manage_log.py
+    author:rabin
+"""
+from __load__ import *
+
+class Manage_log(Model):
+	__table__ = 'manage_log'
+	__comment__ = '后台日志表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='日志ID')
+	admin_id = Fields(type='int', comment='管理员ID')
+	model = Fields(type='varchar(50)', comment='操作的表')
+	method = Fields(type='varchar(50)', comment='操作的方法')
+	data = Fields(type='text', comment='数据记录')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 19 - 0
demos/helloworld/model/manage_role.py

@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:manage_role.py
+    author:rabin
+"""
+from __load__ import *
+
+class Manage_role(Model):
+	__table__ = 'manage_role'
+	__comment__ = '角色表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='角色ID')
+	name = Fields(type='varchar(50)', comment='角色名称')
+	auth = Fields(type='varchar(600)', comment='左侧菜单权限')
+	top = Fields(type='varchar(500)', comment='头部菜单权限')
+	oper = Fields(type='varchar(100)', comment='操作权限增删改查搜等')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 18 - 0
demos/helloworld/model/order.py

@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:order.py
+    author:rabin
+"""
+from __load__ import *
+
+class Order(Model):
+	__table__ = 'order'
+	__comment__ = '订单表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='订单ID')
+	orderID = Fields(type='varchar(500)', comment='原订单ID')
+	pic = Fields(type='varchar(300)', comment='订单图片')
+	site_id = Fields(type='int', comment='所属站点')
+	product_id = Fields(type='int', comment='商品id')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 18 - 0
demos/helloworld/model/product.py

@@ -0,0 +1,18 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:product.py
+    author:rabin
+"""
+from __load__ import *
+
+class Product(Model):
+	__table__ = 'product'
+	__comment__ = '商品表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='商品ID')
+	name = Fields(type='varchar(200)', comment='商品名')
+	link = Fields(type='varchar(500)', comment='商品链接')
+	site_id = Fields(type='int', comment='所属站点')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	status = Fields(type='int', default='1', comment='抢购状态1待机2入队3抢购中4抢购完成')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 19 - 0
demos/helloworld/model/site.py

@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:site.py
+    author:rabin
+"""
+from __load__ import *
+
+class Site(Model):
+	__table__ = 'site'
+	__comment__ = '站点主表'
+	id = Fields(type='int', primaryKey=True, autoIncrement=True, comment='站点ID')
+	name = Fields(type='varchar(200)', comment='站点名')
+	link = Fields(type='varchar(200)', comment='站点网址')
+	login_link = Fields(type='varchar(300)', comment='登录页链接')
+	username = Fields(type='varchar(300)', comment='账号')
+	password = Fields(type='varchar(300)', comment='密码')
+	state = Fields(type='boolean', default='True', comment='数据存在状态')
+	cdate = Fields(type='int', default='time', comment='创建时间')

+ 6 - 0
demos/helloworld/runtime/__init__.py

@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter init
+    author:rabin
+"""

+ 9 - 0
requirements.txt

@@ -0,0 +1,9 @@
+tornado
+gevent
+pymysql
+psycopg2
+influxdb
+redis
+celery
+short_url
+requests

+ 9 - 2
setup.py

@@ -12,9 +12,13 @@ def read(filename):
     """Read and return `filename` in root dir of project and return string"""
     return codecs.open(os.path.join(__DIR__, filename), 'r').read()
 
+class install(object):
+    def run(self):
+        print 22
+
 
 install_requires = read("requirements.txt").split()
-long_description = read('README.md')
+long_description = read('README.rst')
 
 
 setup(
@@ -23,12 +27,15 @@ setup(
     url='https://github.com/shemic/demeter',
     license='MIT License',
     author='Rabin',
+    author_email='2934170@qq.com',
     description=('A simple framework based on Tornado'),
     long_description=long_description,
     packages=['demeter'],
     install_requires = install_requires,
     #tests_require=['pytest'],
-    #cmdclass = {'test': Pytest},
+    cmdclass = {'test': install},
+    include_package_data=True,
+    package_data = {},
     data_files=[
         # Populate this with any files config files etc.
     ],