core.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. demeter core
  5. name:demeter.py
  6. author:rabin
  7. """
  8. import time
  9. import os
  10. import signal
  11. import re
  12. import sys
  13. import getopt
  14. import json
  15. import ConfigParser
  16. import subprocess
  17. import ssl
  18. from tornado.web import Finish
  19. class Demeter(object):
  20. path = ''
  21. config = {}
  22. serviceObj = {}
  23. modelObj = {}
  24. web = ''
  25. request = False
  26. def __new__(self, *args, **kwargs):
  27. print 'error'
  28. sys.exit()
  29. def __init__(self):
  30. pass
  31. @staticmethod
  32. def isset(v):
  33. try :
  34. type (eval(v))
  35. except :
  36. return 0
  37. else :
  38. return 1
  39. @classmethod
  40. def initConfig(self):
  41. self.path = File.path()
  42. if self.config == {}:
  43. name = 'dev'
  44. if 'DEMETER_CONF' in os.environ:
  45. name = os.environ['DEMETER_CONF']
  46. filename = self.path + 'conf/'+name+'.conf'
  47. if File.exists(filename):
  48. config = ConfigParser.ConfigParser()
  49. config.read(filename)
  50. for item in config.sections():
  51. self.config[item] = self.readConfig(config, item)
  52. return True
  53. else:
  54. print filename + ' is not exists'
  55. sys.exit()
  56. @staticmethod
  57. def readConfig(config, type):
  58. value = config.options(type)
  59. result = {}
  60. for item in value:
  61. result[item] = config.get(type, item)
  62. return result
  63. @classmethod
  64. def temp(self, key='', name='', value=''):
  65. temp = Demeter.path + 'conf/temp.conf'
  66. if File.exists(temp):
  67. config = ConfigParser.ConfigParser()
  68. config.read(temp)
  69. if key and name:
  70. config.set(key, name, value)
  71. config.write(open(temp, 'w'))
  72. else:
  73. result = {}
  74. for item in config.sections():
  75. result[item] = self.readConfig(config, item)
  76. return result
  77. @classmethod
  78. def echo(self, args):
  79. module = self.getObject('pprint')
  80. module.pprint(args)
  81. @classmethod
  82. def record(self, key, value):
  83. # 记录日志
  84. # self.log(key, value)
  85. service = self.service('record')
  86. service.push(key, value)
  87. @classmethod
  88. def service(self, name):
  89. path = 'service.'
  90. if name == 'common':
  91. path = 'demeter.'
  92. name = 'service'
  93. service = self.getClass(name, path)
  94. return service()
  95. """
  96. if name not in self.serviceObj:
  97. path = 'service.'
  98. if name == 'common':
  99. path = 'demeter.'
  100. name = 'service'
  101. service = self.getClass(name, path)
  102. self.serviceObj[name] = service()
  103. return self.serviceObj[name]
  104. """
  105. @classmethod
  106. def model(self, table, name='rdb'):
  107. name = self.config['db'][name]
  108. config = self.config[name]
  109. obj = self.getObject('db', 'demeter.')
  110. db = getattr(obj, name.capitalize())
  111. connect = db(config).get()
  112. model = self.getClass(table, 'model.')
  113. return model(name, connect, config)
  114. """
  115. if table not in self.modelObj:
  116. name = self.config['db'][name]
  117. config = self.config[name]
  118. obj = self.getObject('db', 'demeter.')
  119. db = getattr(obj, name.capitalize())
  120. connect = db(config).get()
  121. model = self.getClass(table, 'model.')
  122. self.modelObj[table] = model(name, connect, config)
  123. return self.modelObj[table]
  124. """
  125. @classmethod
  126. def getClass(self, name, path=''):
  127. obj = self.getObject(name, path)
  128. return getattr(obj, name.capitalize())
  129. @staticmethod
  130. def getObject(name, path = ''):
  131. module = __import__(path + name)
  132. return getattr(module, name)
  133. @staticmethod
  134. def bool(value):
  135. return value == str(True)
  136. @classmethod
  137. def runtime(self, path, file, content=''):
  138. path = self.path + 'runtime/' + path + '/'
  139. File.mkdir(path)
  140. file = path + file
  141. if File.exists(file):
  142. return False
  143. else:
  144. File.write(file, content)
  145. return True
  146. @classmethod
  147. def webstart(self, name):
  148. self.web = name
  149. self.webPath = self.path + self.web + '/'
  150. self.getObject('main', name + '.')
  151. @classmethod
  152. def md5(self, value, salt=False):
  153. module = __import__('md5')
  154. md5 = getattr(module, 'new')
  155. md5_obj = md5()
  156. if salt:
  157. if salt == True:
  158. salt = self.rand()
  159. md5_obj.update(value + salt)
  160. return md5_obj.hexdigest() + '_' + salt
  161. else:
  162. md5_obj.update(value)
  163. return md5_obj.hexdigest()
  164. @staticmethod
  165. def rand(length = 4):
  166. module = __import__('random')
  167. rand = getattr(module, 'randint')
  168. salt = ''
  169. chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  170. len_chars = len(chars) - 1
  171. for i in xrange(length):
  172. salt += chars[rand(0, len_chars)]
  173. return salt
  174. @staticmethod
  175. def hour(value):
  176. if value < 10:
  177. return '0' + str(value)
  178. return value
  179. @staticmethod
  180. def time():
  181. return int(time.time())
  182. @staticmethod
  183. def mktime(value, string='%Y-%m-%d %H:%M:%S'):
  184. if ' ' in string and ' ' not in value:
  185. value = value + ' 00:00:00'
  186. return int(time.mktime(time.strptime(value,string)))
  187. @staticmethod
  188. def date(value, string='%Y-%m-%d %H:%M:%S'):
  189. module = __import__('datetime')
  190. datetime = getattr(module, 'datetime')
  191. fromtimestamp = getattr(datetime, 'fromtimestamp')
  192. return str(fromtimestamp(value).strftime(string))
  193. @staticmethod
  194. def isJson(value):
  195. result = False
  196. try:
  197. result = json.loads(value)
  198. except ValueError:
  199. return result
  200. return result
  201. @staticmethod
  202. def compressUuid(value):
  203. row = value.replace('-', '')
  204. code = ''
  205. hash = [x for x in "0123456789-abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
  206. for i in xrange(10):
  207. enbin = "%012d" % int(bin(int(row[i * 3] + row[i * 3 + 1] + row[i * 3 + 2], 16))[2:], 10)
  208. code += (hash[int(enbin[0:6], 2)] + hash[int(enbin[6:12], 2)])
  209. return code
  210. @staticmethod
  211. def checkMobile(request):
  212. if 'Demeter-Mobile' in request.headers:
  213. return True
  214. userAgent = request.headers['User-Agent']
  215. # userAgent = env.get('HTTP_USER_AGENT')
  216. _long_matches = r'googlebot-mobile|android|avantgo|blackberry|blazer|elaine|hiptop|ip(hone|od)|kindle|midp|mmp|mobile|o2|opera mini|palm( os)?|pda|plucker|pocket|psp|smartphone|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce; (iemobile|ppc)|xiino|maemo|fennec'
  217. _long_matches = re.compile(_long_matches, re.IGNORECASE)
  218. _short_matches = r'1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-'
  219. _short_matches = re.compile(_short_matches, re.IGNORECASE)
  220. if _long_matches.search(userAgent) != None:
  221. return True
  222. user_agent = userAgent[0:4]
  223. if _short_matches.search(user_agent) != None:
  224. return True
  225. return False
  226. @staticmethod
  227. def exp(exp, value):
  228. if exp:
  229. exp = exp.replace('{n}', value)
  230. value = str(eval(exp))
  231. return value
  232. @classmethod
  233. def curl(self, url):
  234. module = __import__('tornado')
  235. http = getattr(module, 'httpclient')
  236. http_client = http.HTTPClient()
  237. response = http_client.fetch(url)
  238. return response
  239. @classmethod
  240. def error(self, string):
  241. if self.request:
  242. self.request.out(string)
  243. #self.request.finish()
  244. raise Finish()
  245. else:
  246. print string
  247. #os._exit(0)
  248. class File(object):
  249. @staticmethod
  250. def write(file, content):
  251. handle = open(file, 'w')
  252. handle.write(content)
  253. handle.close()
  254. Shell.popen('chmod +x ' + file)
  255. @staticmethod
  256. def read(path, name):
  257. handle = open(path + name, 'r')
  258. content = handle.read()
  259. handle.close()
  260. return content
  261. @staticmethod
  262. def cur_path():
  263. return os.path.split(os.path.realpath(__file__))[0] + '/'
  264. @staticmethod
  265. def path():
  266. return os.sys.path[0] + '/'
  267. @staticmethod
  268. def exists(name):
  269. return os.path.exists(name)
  270. @staticmethod
  271. def rename(old, new):
  272. return os.rename(old, new)
  273. @staticmethod
  274. def remove(file):
  275. return os.remove(file)
  276. @staticmethod
  277. def mkdir(path):
  278. if File.exists(path) == False:
  279. os.mkdir(path)
  280. return path
  281. @staticmethod
  282. def mkdirs(path):
  283. if File.exists(path) == False:
  284. os.makedirs(path)
  285. return path
  286. class Shell(object):
  287. @staticmethod
  288. def popen(command, sub=False, bg=False, timeout=0):
  289. string = command
  290. if bg == True:
  291. command = command + ' 1>/dev/null 2>&1 &'
  292. if timeout > 0:
  293. proc = subprocess.Popen(command,bufsize=0,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True, close_fds=True, preexec_fn = os.setsid)
  294. poll_seconds = .250
  295. deadline = time.time() + timeout
  296. while time.time() < deadline and proc.poll() == None:
  297. time.sleep(poll_seconds)
  298. if proc.poll() == None:
  299. os.killpg(proc.pid, signal.SIGTERM)
  300. return 'timeout'
  301. stdout,stderr = proc.communicate()
  302. return stdout
  303. elif sub == False:
  304. process = os.popen(command)
  305. output = process.read()
  306. process.close()
  307. return output
  308. else:
  309. popen = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
  310. output = ''
  311. print string
  312. while True:
  313. output = popen.stdout.readline()
  314. print output
  315. if popen.poll() is not None:
  316. break
  317. return output
  318. class Check(object):
  319. @staticmethod
  320. def match(rule, value):
  321. if not rule.match(value):
  322. return False
  323. return True
  324. @staticmethod
  325. def mobile(value):
  326. rule = re.compile(r'1\d{10}')
  327. return Check.match(rule, value)
  328. @staticmethod
  329. def number(value):
  330. try:
  331. int(value)
  332. return True
  333. except ValueError:
  334. return False
  335. @staticmethod
  336. def numberFloat(value):
  337. try:
  338. float(value)
  339. return True
  340. except ValueError:
  341. return False
  342. Demeter.initConfig()