rabin 7 years ago
parent
commit
9db50619ac
6 changed files with 1064 additions and 11 deletions
  1. 8 11
      core.py
  2. 613 0
      model.py
  3. 74 0
      mqtt.py
  4. 70 0
      service.py
  5. 68 0
      tcp.py
  6. 231 0
      web.py

+ 8 - 11
core.py

@@ -11,7 +11,6 @@ import sys
 import getopt
 import ConfigParser
 import subprocess
-PATH = ''
 class Demeter(object):
 	path = ''
 	config = {}
@@ -28,10 +27,7 @@ class Demeter(object):
 
 	@classmethod
 	def initConfig(cls):
-		global PATH
-		if PATH == '':
-			PATH = File.path()
-		cls.path = PATH
+		cls.path = File.path()
 		if cls.config == {}:
 			name = 'dev'
 			if 'DEMETER_CONF' in os.environ:
@@ -73,20 +69,21 @@ class Demeter(object):
 		if name not in cls.serviceObj:
 			path = 'service.'
 			if name == 'common':
-				path = 'demeter.' + path
+				path = 'demeter.'
+				name = 'service'
 			service = cls.getClass(name, path)
 			cls.serviceObj[name] = service()
 		return cls.serviceObj[name]
 
 	@classmethod
-	def model(cls, table, type='rdb'):
+	def model(cls, table, name='rdb'):
 		if table not in cls.modelObj:
-			type = cls.config['db'][type]
-			config = cls.config[type]
-			db = cls.getClass(type, 'demeter.db.')
+			name = cls.config['db'][name]
+			config = cls.config[name]
+			db = cls.getClass(name, 'demeter.db.')
 			connect = db(config).get()
 			model = cls.getClass(table, 'model.')
-			cls.modelObj[table] =  model(type, connect, config)
+			cls.modelObj[table] =  model(name, connect, config)
 		return cls.modelObj[table]
 
 	@classmethod

+ 613 - 0
model.py

@@ -0,0 +1,613 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter database
+    name:__base__.py
+    author:rabin
+"""
+import os
+import uuid
+import short_url
+import json
+import traceback
+import uuid
+import re
+import math
+from demeter.core import *
+class Model(object):
+	__table__ = ''
+	__comment__ = ''
+	def __init__(self, type, db, config):
+		self.db = db
+		self._type = type
+		self._config = config
+		self._table = self._config['prefix'] + '_' + self.__table__
+		self._set = ''
+		self._bind = {}
+		self._attr = {}
+		self._key = {}
+		self.create()
+
+	def cur(self):
+		return self.db.cursor()
+
+	def query(self, sql, method='select', fetch='fetchall'):
+		cur = self.cur()
+		bind = []
+		if self._set:
+			for key in self._set:
+				if self._set[key] == 'time':
+					self._set[key] = self.time()
+				elif self._set[key] == 'True':
+					self._set[key] = True
+				elif self._set[key] == 'False':
+					self._set[key] = False
+				elif 'date' in key:
+					self._set[key] = self.mktime(self._set[key])
+				bind.append(self._set[key])
+		for value in self._key:
+			if value[0] in self._bind and self._bind[value[0]] != None:
+				val = self._bind[value[0]]
+				self._attr[value[0]].unset()
+				if type(val) == list and val:
+					for i in val:
+						bind.append(i)
+				else:
+					bind.append(val)
+		if method == 'select' and ';' in sql:
+			temp = sql.split(';')
+			sql = temp[1]
+			totalSql = temp[0]
+			cur.execute(totalSql, bind)
+			Demeter.config['page']['totalNum'] = self.fetch(cur, 'fetchone', 'count')
+			Demeter.config['page']['total'] = math.ceil(round(float(Demeter.config['page']['totalNum'])/float(Demeter.config['page']['num']),2))
+		cur.execute(sql, bind)
+		if method == 'select':
+			return self.fetch(cur, fetch)
+		id = True
+		if method == 'insert':
+			id = cur.fetchone()[0]
+		self.db.commit()
+		self._set = {}
+		return id
+		"""
+		try:
+			
+		except Exception, e:
+			print e.message
+			os._exit(0)
+		"""
+
+
+	def fetch(self, cur, type, method = ''):
+		load = getattr(cur, type)
+		rows = load()
+		if type == 'fetchall':
+			result = []
+			if rows:
+				for key in rows:
+					row = {}
+					i = 0
+					for v in key:
+						row[self._key[i][0]] = v
+						i = i + 1
+					result.append(row)
+		elif method == 'count':
+			return rows[0]
+		else:
+			result = {}
+			i = 0
+			if rows:
+				for key in rows:
+					if not key:
+						key = ''
+					result[self._key[i][0]] = key
+					i = i + 1
+		return result
+
+	def attr(self, method):
+		fields = vars(self.__class__)
+		self._attr = {}
+		self._bind = {}
+		self._key = {}
+		col = (int, str, long, float, unicode, bool, uuid.UUID)
+		for field in fields:
+			if isinstance(fields[field], Fields):
+				self._attr[field] = fields[field]
+				self._key[field] = self._attr[field].getKey()
+				insert = (method == 'insert')
+				if insert and self._attr[field].uuid:
+					self.setUuid(field, col)
+				bind = False
+				val = self._attr[field].getArgv()
+				if val:
+					bind = True
+				else:
+					val = getattr(self, field)
+					if isinstance(val, col):
+						setattr(self, field, self._attr[field])
+						bind = True
+					elif insert and self._attr[field].default:
+						val = self._attr[field].default
+						bind = True
+						if val == 'time':
+							val = self.time()
+						elif '.' in val:
+							temp = val.split('.')
+							val = Demeter.config[temp[0]][temp[1]]
+					elif method == 'select' and self._attr[field].default and field == 'state':
+						val = self._attr[field].default
+						bind = True
+				if bind and val:
+					if type(val) == list:
+						length = len(val)
+						if length <= 1:
+							val = val[0]
+					if insert and self._attr[field].md5:
+						val = self.createMd5(val)
+					if self._attr[field].type == 'boolean' and isinstance(val, (str, unicode)):
+						val = Demeter.bool(val)
+					self.check(field, val, self._attr[field])
+					self._bind[field] = val
+					self._attr[field].val(self._bind[field])
+					self._attr[field].bind('%s')
+
+		self._key = sorted(self._key.items(), key=lambda d:d[1], reverse = False)
+		Counter().unset()
+
+	def check(self, field, val, attr):
+		if attr.match == 'not':
+			if not val:
+				Demeter.error(field + ' not exists')
+		elif attr.match:
+			result = re.search(attr.match, val)
+			if not result:
+				Demeter.error(field + ' not match:' + attr.match)
+
+	def time(self):
+		module = __import__('time')
+		time = getattr(module, 'time')
+		return int(time())
+
+	def mktime(self, value):
+		return Demeter.mktime(value)
+
+	def setUuid(self, field, col):
+		id = getattr(self, self._attr[field].uuid)
+		if isinstance(id, col):
+			system = short_url.encode_url(id)
+		else:
+			system = self._attr[field].uuid
+		name = system + '.' + self.__table__
+		result = uuid.uuid5(uuid.uuid1(), name)
+		result = str(result)
+		setattr(self, field, result)
+
+	def createMd5(self, value):
+		return Demeter.md5(value, salt=True)
+
+	def createState(self):
+		create = Demeter.bool(self._config['create'])
+		if create:
+			return Demeter.runtime(self._type, self.__table__, json.dumps(self._key))
+		return False
+
+	def drop(self):
+		return self.handle('drop')
+
+	def create(self):
+		return self.handle('create')
+
+	def insert(self):
+		return self.handle('insert')
+
+	def update(self, *args, **kwargs):
+		if args:
+			self._set = args[0]
+		else:
+			self._set = kwargs
+		return self.handle('update', set=self._set)
+
+	def delete(self):
+		return self.handle('delete')
+
+	def select(self, type='fetchall',col = '*', order = 'cdate desc', group = '', limit = '0,100', page=False):
+		pageConfig = {}
+		if page and 'page' in Demeter.config:
+			pageConfig['current'] = Demeter.config['page']['current']
+			if page == True:
+				pageConfig['num'] = 15
+			elif 'num' in page:
+				pageConfig['num'] = page['num']
+			Demeter.config['page']['num'] = pageConfig['num']
+		return self.handle('select', type=type, col=col, order=order, group=group, limit=limit, page=pageConfig)
+
+	def manage(self):
+		self.attr(method)
+		return
+
+	def handle(self, method='select', type='fetchall', col = '*', order = '', group = '', limit = '0,100', page=False, set = ''):
+		self.attr(method)
+		if method == 'create':
+			create = self.createState()
+			if create == False:
+				return False
+		if type == 'fetchone':
+			limit = '0,1'
+		load = getattr(Sql(self._type), method)
+		return self.query(load(self._table, {'key':self._key, 'fields':self._attr, 'col':col, 'order':order, 'group':group, 'limit':limit, 'page':page, 'set':set, 'table_comment':self.__comment__}), method, type)
+
+
+class Fields(object):
+	def __init__(self, type='', default='', primaryKey=False, autoIncrement=False, null=True, unique=False, check='', constraint='', comment='', uuid='', index=False, indexs=False, md5=False, match='', manage=''):
+		self.type = type
+		self.default = default
+		self.primaryKey = primaryKey
+		self.autoIncrement = autoIncrement
+		self.null = null
+		self.unique = unique
+		self.check = check
+		self.constraint = constraint
+		self.comment = comment
+		self.uuid = uuid
+		self.index = index
+		self.indexs = indexs
+		self.md5 = md5
+		self.key = Counter().inc()
+		self.match = match
+		self.value = ''
+		self.argv = ''
+		self.bindValue = ''
+		self.expValue = '='
+		self.logicValue = 'and'
+		self.manage = manage
+
+
+	def assgin(self, value, exp='=', logic='and'):
+		self.add(value)
+		self.exp(exp)
+		self.logic(logic)
+		return self
+
+	def bind(self, value):
+		self.bindValue = value
+		return self
+
+	def exp(self, value):
+		if type(self.expValue) != list:
+			self.expValue = []
+		self.expValue.append(value)
+		return self
+
+	def logic(self, value):
+		if type(self.logicValue) != list:
+			self.logicValue = []
+		self.logicValue.append(value)
+		return self
+
+	def val(self, value, exp='=', logic='and'):
+		if type(value) == list:
+			length = len(value)
+			if length <= 1:
+				value = value[0]
+		self.value = value
+		if not self.expValue:
+			self.exp(exp)
+		if not self.logicValue:
+			self.logic(logic)
+		return self
+
+	def getArgv(self):
+		return self.argv
+
+	def getVal(self):
+		return self.value
+
+	def getBind(self):
+		return self.bindValue
+
+	def getExp(self):
+		if not self.expValue:
+			return ''
+		if type(self.expValue) == list:
+			length = len(self.expValue)
+			if length <= 1:
+				result = self.expValue[0]
+			else:
+				result = self.expValue
+		else:
+			result = self.expValue
+		return result
+
+	def getKey(self):
+		return self.key
+
+	def getLogic(self):
+		if not self.logicValue:
+			return ''
+		if type(self.logicValue) == list:
+			length = len(self.logicValue)
+			if length <= 1:
+				result = self.logicValue[0]
+			else:
+				result = self.logicValue
+		else:
+			result = self.logicValue
+		return result
+
+	def unset(self):
+		self.argv = None
+		self.value = None
+		self.bindValue = None
+		self.expValue = '='
+		self.logicValue = 'and'
+		return self
+
+	def add(self, value):
+		if not self.argv:
+			self.argv = []
+		self.argv.append(value)
+		return self
+
+	def ins(self, value):
+		self.argv = value
+		self.exp('in')
+		return self
+
+	def nq(self, value):
+		self.argv = value
+		self.exp('!=')
+		return self
+
+	def like(self, value):
+		self.argv = '%' + value + '%'
+		self.exp('like')
+		return self
+
+	def mlike(self, value):
+		self.argv = value
+		self.exp('~')
+		self.logic('and')
+		return self
+
+	def time(self, value):
+		self.add(Demeter.mktime(value))
+		return self
+
+	def start(self, value):
+		self.time(value)
+		self.exp('>=')
+		self.logic('and')
+		return self
+
+	def end(self, value):
+		self.time(value)
+		self.exp('<=')
+		self.logic('and')
+		return self
+
+class Counter(object):
+	num = 0
+	instance = None
+
+	def __new__(cls, *args, **kwd):
+		if Counter.instance is None:
+			Counter.instance = object.__new__(cls, *args, **kwd)
+		return Counter.instance
+
+	def inc(self):
+		self.num = self.num + 1
+		return self.num
+
+	def dec(self):
+		self.num = self.num - 1
+		return self.num
+
+	def unset(self):
+		self.num = 0
+		return self.num
+
+class Sql(object):
+	instance = None
+	def __new__(cls, *args, **kwd):
+		if Sql.instance is None:
+			Sql.instance = object.__new__(cls, *args, **kwd)
+		return Sql.instance
+
+	def __init__(self, type):
+		self.type = type
+
+	def drop(self, table, args):
+		sql = 'DROP TABLE IF EXISTS ' + table
+		return sql
+
+	def alter(self, table, args):
+		sql = 'ALTER TABLE ' + table + ' ADD COLUMN '
+		return sql
+
+	def create(self, table, args):
+		create = []
+		primary = []
+		unique = []
+		indexs = []
+		index = []
+		comment = {}
+		for value in args['key']:
+			key = value[0]
+			val = args['fields'][key]
+			if val.primaryKey:
+				primary.append(key)
+			if val.unique:
+				unique.append(key)
+			if val.index:
+				index.append((key, val.index))
+			if val.indexs:
+				indexs.append(key)
+
+			fields = []
+			fields.append(key)
+			if val.autoIncrement and self.type == 'postgresql':
+				fields.append('SERIAL')
+			else:
+				fields.append(val.type)
+
+			if not val.null:
+				fields.append('NOT NULL')
+				
+
+			if val.autoIncrement and self.type == 'mysql':
+				fields.append('AUTO_INCREMENT')
+
+			#约束
+			if val.constraint:
+				fields.append('CONSTRAINT ' + val.constraint)
+			if val.check:
+				fields.append('CHECK ' + val.check)
+			
+			if val.default:
+				default = val.default
+				if val.default == 'time':
+					default = '0'
+				if '.' in val.default:
+					temp = val.default.split('.')
+					default = Demeter.config[temp[0]][temp[1]]
+				fields.append('DEFAULT \'' + str(default) + '\'')
+
+			if val.comment:
+				if self.type == 'mysql':
+					fields.append('COMMENT \'' + val.comment + '\'')
+				else:
+					comment[key] = val.comment
+
+			fields = ' '.join(fields)
+			create.append(fields)
+
+		if primary:
+			create.append('PRIMARY KEY (' + ','.join(primary) + ')')
+		if unique:
+			create.append('UNIQUE (' + ','.join(unique) + ')')
+
+		create = ','.join(create)
+		sql = 'CREATE TABLE ' + table + '(' + create + ')'
+		sql = self.drop(table, args) + ';' + sql
+		if indexs:
+			name = '_'.join(indexs)
+			value = ','.join(indexs)
+			sql = sql + ';' + 'CREATE INDEX ' + table + '_' + name +' ON ' + table + '(' + value + ')'
+
+		if index:
+			for value in index:
+				sql = sql + ';' + 'CREATE INDEX ' + table + '_' + value[0] +' ON ' + table + value[1]
+
+		if comment:
+			if args['table_comment']:
+				sql = sql + ';' + 'COMMENT ON TABLE ' + table + ' IS \''+args['table_comment']+'\''
+			for key in comment:
+				sql = sql + ';' + 'COMMENT ON COLUMN ' + table + '.'+key+' IS \''+comment[key]+'\''
+		return sql
+
+	def insert(self, table, args):
+		fields = []
+		values = []
+		for value in args['key']:
+			key = value[0]
+			val = args['fields'][key].getBind()
+			if val:
+				values.append(val)
+				fields.append(key)
+
+		fields = ','.join(fields)
+		values = ','.join(values)
+		sql = 'INSERT INTO ' + table + ' (' + fields + ') VALUES (' + values + ')'
+		if self.type == 'postgresql':
+			sql = sql + ' RETURNING id'
+		return sql
+
+	def update(self, table, args):
+		fields = []
+		for key in args['set']:
+			fields.append(key + ' = %s')
+
+		fields = ','.join(fields)
+		sql = 'UPDATE ' + table + ' SET ' + fields + self.where(args['key'], args['fields'])
+		return sql
+
+	def delete(self, table, args):
+		sql = 'DELETE FROM ' + table + self.where(args['fields'])
+		return sql
+
+	def select(self, table, args):
+		string = ' FROM ' + table + self.where(args['key'], args['fields']) + ' ' + self.group(args['group'])
+		sql = ''
+		if args['page']:
+			sql = 'SELECT count(1) as total' + string + ';'
+		sql = sql + 'SELECT ' + args['col'] + string + ' ' + self.order(args['order']) + ' ' + self.limit(args['limit'], args['page'])
+		return sql
+
+	def where(self, key, fields):
+		fields = self.fields(key, fields)
+		if fields:
+			return ' WHERE ' + fields
+		return ''
+
+	def fields(self, key, fields):
+		result = ''
+		k = 0
+		for value in key:
+			key = value[0]
+			field = fields[key]
+			bind = field.getBind()
+			val = field.getVal()
+			logic = field.getLogic()
+			exp = field.getExp()
+			if type(val) == list and val:
+				n = 0
+				for i in val:
+					data = self.field(field, bind, key, k, logic[n], exp[n])
+					n = n + 1
+					if data:
+						result = result + data
+						k = 1
+			else:
+				data = self.field(field, bind, key, k, logic, exp)
+				if data:
+					result = result + data
+					k = 1
+		return result
+
+	def field(self, field, val, key, k, logic, exp):
+		result = ''
+		if val:
+			if k == 0:
+				logic = ''
+			else:
+				logic = ' ' + logic
+			result = logic + ' ' + key + ' ' + exp + ' ' + str(val)
+		return result
+
+	def order(self, value):
+		result = ''
+		if value:
+			result = ' ORDER BY ' + value
+
+		return result
+
+	def group(self, value):
+		result = ''
+		if value:
+			result = ' GROUP BY ' + value
+
+		return result
+
+	def limit(self, value, page):
+		result = ''
+		if page:
+			value = str((int(page['current'])-1) * page['num']) + ',' + str(page['num'])
+		if value:
+			value = value.split(',')
+			if self.type == 'mysql':
+				result = ' LIMIT ' + value[0] + ',' + value[1]
+			elif self.type == 'postgresql':
+				result = ' LIMIT ' + value[1] + ' OFFSET ' + value[0]
+
+		return result

+ 74 - 0
mqtt.py

@@ -0,0 +1,74 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter mqtt
+    name:connect.py
+    author:rabin
+"""
+from demeter.core import *
+import paho.mqtt.client as mqtt
+#from gevent import monkey; monkey.patch_all()
+#import gevent
+
+class Connect(object):
+
+	def __init__(self, act):
+		act.connect = self
+		self.client = mqtt.Client()
+		self.client.on_connect = self.connect
+		state = hasattr(act, 'message')
+		if state:
+			self.client.on_message = act.message
+		self.client.connect(Demeter.config['mqtt']['host'], Demeter.config['mqtt']['port'], int(Demeter.config['mqtt']['timeout']))
+		if state:
+			self.client.loop_forever()
+
+	def __del__(self):
+		pass
+
+	def getClient(self):
+		return self.client
+
+	def connect(self, client, userdata, flags, rc):
+		#print("Connected with result code "+str(rc))
+		#client.subscribe("sensor/#")
+		client.subscribe("pic/#")
+		"""
+		gevent.joinall([
+			gevent.spawn(self.subscribe, client, 'sensor/#'),
+			gevent.spawn(self.subscribe, client, 'pic/#'),
+			gevent.spawn(self.subscribe, client, 'msg/#'),
+		])
+		"""
+
+	@staticmethod
+	def subscribe(client, key):
+		client.subscribe(key)
+
+	def handle(self, key, value):
+		Demeter.record(key, value)
+
+
+class Pub(object):
+
+	def __init__(self):
+		Connect(self)
+
+	def __del__(self):
+		pass
+
+	def push(self, key, msg):
+		self.connect.getClient().publish(key,msg)
+
+
+class Sub(object):
+
+	def __init__(self):
+		Connect(self)
+
+	def __del__(self):
+		pass
+
+	def message(self, client, userdata, msg):
+		#print(msg.topic+" "+str(msg.payload))
+		self.connect.handle(msg.topic, str(msg.payload))

+ 70 - 0
service.py

@@ -0,0 +1,70 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter service
+    name:service.py 通用业务
+    author:rabin
+"""
+from demeter.core import *
+
+class Service(object):
+
+	# 获取某个model下的列表数据
+	def list(self, name, state = True, search = None, page=False):
+		model = self.model(name)
+		model.state = state
+		if search:
+			for key, value in search.items():
+				if value:
+					key = key.split('-')
+					if hasattr(model, key[0]):
+						attr = getattr(model, key[0])
+						if hasattr(attr, key[2]):
+							method = key[2]
+						else:
+							method = 'assgin'
+						func = getattr(attr, method)
+						func(value)
+		data = model.select(page=page)
+		return data
+
+	# 获取某个model下的数据
+	def one(self, name, **kwd):
+		model = self.model(name)
+		if kwd:
+			for key,value in kwd.items():
+				if hasattr(model, key):
+					attr = getattr(model, key)
+					func = getattr(attr, 'assgin')
+					func(value)
+		data = model.select(type='fetchone')
+		return data
+
+	# 更新
+	def update(self, name, id, data):
+		model = self.model(name)
+		if id:
+			model.id = id
+			if 'cdate' not in data:
+				data['cdate'] = 'time'
+			model.update(data)
+			return id
+		else:
+			for key, value in data.items():
+				if hasattr(model, key):
+					attr = getattr(model, key)
+					method = 'assgin'
+					if 'date' in key:
+						method = 'time'
+					func = getattr(attr, method)
+					func(value)
+			return model.insert()
+
+	# 删除
+	def delete(self, name, id, state = False):
+		model = self.model(name)
+		model.id = id
+		return model.update(state=state)
+
+	def model(self, name):
+		return Demeter.model(name)

+ 68 - 0
tcp.py

@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+	demeter tcp
+	name:server.py
+	author:rabin
+"""
+import socket  
+import time
+from demeter.core import *
+from tornado.tcpserver import TCPServer
+from tornado.ioloop  import IOLoop
+
+class Connection(object):
+	clients = set()
+	def __init__(self, stream, address):
+		Connection.clients.add(self)
+		self._stream = stream
+		self._address = address
+		self._stream.set_close_callback(self.on_close)
+		self.read_message()
+		
+	def read_message(self):
+		self._stream.read_until('\n', self.broadcast_messages)
+	
+	def broadcast_messages(self, data):
+		pub = Pub()
+		temp = data.split(':')
+		key = temp[0]
+		value = temp[1]
+		pub.push(key, value)
+		
+		#print "User said:", data[:-1], self._address
+		"""
+		for conn in Connection.clients:
+			conn.send_message(data)
+		"""
+		self.read_message()
+		
+	def send_message(self, data):
+		self._stream.write(data)
+			
+	def on_close(self):
+		#print "A user has left the chat room.", self._address
+		Connection.clients.remove(self)
+	
+class Server(TCPServer):	
+	def handle_stream(self, stream, address):
+		#print "New connection :", address, stream
+		Connection(stream, address)
+		#print "connection num is:", len(Connection.clients)
+
+class Client(object):
+	HOST = '0.0.0.0'	# The remote host  
+	PORT = 8000		   # The same port as used by the server  
+	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
+	s.connect((HOST, PORT))  
+	  
+	s.sendall('Hello, \nw')  
+	time.sleep(5)  
+	s.sendall('ord! \n')  
+	  
+	data = s.recv(1024)  
+	  
+	print 'Received', repr(data)  
+	  
+	time.sleep(60)  
+	s.close() 

+ 231 - 0
web.py

@@ -0,0 +1,231 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+    demeter web
+    name:application.py
+    author:rabin
+"""
+import os
+import json
+from demeter.core import *
+import tornado.web
+import tornado.ioloop
+import tornado.httpserver
+
+class Base(tornado.web.RequestHandler):
+    def initialize(self):
+        self.data = {}
+        self.page()
+        self.search()
+        self.cookie()
+        self.setting()
+        self.assign()
+
+    def get_current_user(self):
+        return self.get_secure_cookie(self.KEYS[1])
+
+    def assign(self):
+        self.data['setting'] = Demeter.config['setting']
+        
+    def cookie(self):
+        for key in self.KEYS:
+            cookie = None
+            if key in Demeter.config['base']:
+                cookie = Demeter.config['base'][key]
+            if not cookie:
+                cookie = self.get_secure_cookie(key)
+                #cookie = self.get_cookie(key)
+            if not cookie:
+                value = self.input(key)
+                if value:
+                    #self.set_secure_cookie(key, value)
+                    Demeter.config['setting'][key] = value
+                else:
+                    Demeter.config['setting'][key] = 0
+            else:
+                Demeter.config['setting'][key] = cookie
+
+    def page(self):
+        Demeter.config['page'] = {}
+        page = self.input('page')
+        if page:
+            Demeter.config['page']['ajax'] = True
+        else:
+            Demeter.config['page']['ajax'] = False
+            page = 1
+        Demeter.config['page']['current'] = page
+        Demeter.config['page']['total'] = 0
+        self.data['page'] = Demeter.config['page']
+
+    def search(self):
+        data = self.request.arguments
+        self.data['search'] = {}
+        self.data['update'] = {}
+        for key in data:
+            if 'search_' in key:
+                index = key.replace('search_', '')
+                self.data['search'][index] = ",".join(data[key])
+            if 'update_' in key:
+                index = key.replace('update_', '')
+                self.data['update'][index] = ",".join(data[key])
+
+    def input(self, key, value=None):
+        return self.get_argument(key, value)
+
+    def service(self, name):
+        return Demeter.service(name)
+
+    def model(self, name):
+        return Demeter.model(name)
+
+    def common(self, **kwd):
+        self.data['common'] = kwd
+        farm = str(Demeter.config['setting']['farm'])
+        self.data['common']['argvs'] = '&farm=' + farm + '&search_farm_id-select-=' + farm
+
+    def commonView(self, name):
+        self.view('common/'+name+'.html')
+
+    def commonList(self, model):
+        self.data['state'] = self.input('state', True)
+        self.data['list'] = self.service('common').list(model, state=self.data['state'], search=self.data['search'], page=True)
+
+    def commonOne(self, model, **kwd):
+        id = self.input('id')
+        self.data['info'] = {}
+        if id:
+            kwd['id'] = id
+        if kwd:
+            self.data['info'] = self.service('common').one(model, **kwd)
+        if not self.data['info'] and Demeter.config['setting']['farm'] > 0:
+            self.data['info']['farm_id'] = Demeter.config['setting']['farm']
+
+    def commonUpdate(self, model, msg='', id=0, **kwd):
+        if not self.data['auth']:
+            self.auth()
+        else:
+            if id <= 0:
+                id = self.input('id')
+            if kwd:
+                info = self.service('common').one(model, **kwd)
+                if id:
+                    id = int(id)
+                if info and (id != info['id']):
+                    self.out(msg)
+                    return
+            state = self.service('common').update(model, id, self.data['update'])
+            self.log(model, 'update', self.data['update'])
+            self.out('yes', {'id':state})
+            return state
+
+    def commonDelete(self, model):
+        if not self.data['auth']:
+            self.auth()
+        else:
+            id = self.input('id')
+            state = self.input('state', False)
+            state = self.service('common').delete(model, id, state)
+            self.log(model, 'delete', {id:id, state:state})
+            self.out('yes', {'state':state})
+
+    def log(self, model, method, data):
+        insert = {}
+        insert['admin_id'] = Demeter.config['setting']['admin']
+        insert['model'] = model
+        insert['method'] = method
+        insert['data'] = json.dumps(data)
+        self.service('common').update('manage_log', None, insert)
+
+    def view(self, name):
+        if not self.data['auth']:
+            self.auth()
+        else:
+            self.render(name, data=self.data)
+
+    def auth(self):
+        self.out('您没有权限')
+
+    def out(self, msg='', data={}, code=0):
+        callback = self.input('callback')
+        function = self.input('function')
+        result = ''
+        send = {}
+        send['status'] = 1
+        send['msg'] = msg
+        send['data'] = data
+        send['code'] = code
+        if not send['data']:
+            send['status'] = 2
+        result = json.dumps(send)
+        if callback:
+            result = callback + '(' + result + ')'
+        elif function:
+            result = '<script>parent.' + function + '(' + result + ')' + '</script>';
+        self.write(result)
+        #self.finish(result)
+
+class Web(object):
+    @staticmethod
+    def file(path):
+        files = os.listdir(path)
+        result = []
+        for key in files:
+            if '.DS_Store' not in key and  '__' not in key and 'pyc' not in key:
+                key = key.replace('.py', '')
+                result.append(key)
+        return result
+    @staticmethod
+    def url(module, key, url):
+        str = dir(module)
+        for i in str:
+            act = ''
+            if '_path' in i:
+                act = i.replace('_path', '')
+            if '_html' in i:
+                act = i.replace('_html', '.html')
+            if act:
+                attr = getattr(module, i)
+                if key == 'main' and act == 'index':
+                    url.append((r'/', attr))
+                elif key == act:
+                    url.append((r'/'+act, attr))
+                url.append((r'/'+key+'/'+act, attr))
+        return url
+    @staticmethod
+    def start(url):
+        config = Demeter.config[Demeter.web]
+        settings = {
+            "static_path": os.path.join(os.path.dirname(__file__), "static"),
+            "template_path": os.path.join(os.path.dirname(__file__), 'templates'),
+            "cookie_secret": "61oETzKXQAGaYekL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=",
+            "login_url": "/user/login",
+            "xsrf_cookies": True,
+            "debug": Demeter.bool(config['debug']),
+            #"autoreload": Demeter.bool(config['autoreload']),
+            "port": config['port'],
+            "max_buffer_size": int(config['max_buffer_size']),
+            "process": int(config['process'])
+        }
+        handlers = []
+        def application_setting():
+            handlers.append((r"/upload/(.*)", tornado.web.StaticFileHandler, {"path": Demeter.path + 'runtime/upload/'}))
+            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)
+
+        application_setting()
+        application = tornado.web.Application(handlers=handlers, **settings)
+        
+        if settings['debug'] == True:
+            application.listen(settings['port'])
+            tornado.ioloop.IOLoop.instance().start()
+        else:
+            server = tornado.httpserver.HTTPServer(application, settings['max_buffer_size'])
+            server.bind(settings['port'])
+            server.start(settings['process'])
+            try:        
+                print 'running on port %s' % settings['port']
+                tornado.ioloop.IOLoop.instance().start()
+
+            except KeyboardInterrupt:
+                tornado.ioloop.IOLoop.instance().stop()