core.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. # -*- coding: utf-8 -*-
  2. """
  3. demeter
  4. name:core.py
  5. author:rabin
  6. """
  7. import time
  8. import os
  9. import signal
  10. import re
  11. import sys
  12. import json
  13. import subprocess
  14. import importlib
  15. class Demeter(object):
  16. path = ''
  17. root = ''
  18. config = {}
  19. option = {}
  20. web = ''
  21. request = False
  22. route = []
  23. def __new__(self, *args, **kwargs):
  24. sys.exit()
  25. def __init__(self):
  26. pass
  27. @staticmethod
  28. def checkPy3():
  29. if sys.version > '3':
  30. state = True
  31. else:
  32. state = False
  33. return state
  34. @classmethod
  35. def getConfig(self):
  36. state = self.checkPy3()
  37. if state:
  38. import configparser
  39. return configparser.ConfigParser()
  40. else:
  41. import ConfigParser
  42. return ConfigParser.ConfigParser()
  43. @staticmethod
  44. def isset(v):
  45. try :
  46. type (eval(v))
  47. except :
  48. return 0
  49. else :
  50. return 1
  51. @classmethod
  52. def initConfig(self):
  53. self.path = File.path()
  54. self.root = File.cur_path()
  55. if self.config == {}:
  56. name = 'dev'
  57. if 'DEMETER_CONF' in os.environ:
  58. name = os.environ['DEMETER_CONF']
  59. filename = self.path + 'conf/'+name+'.conf'
  60. if File.exists(filename):
  61. config = self.getConfig()
  62. config.read(filename)
  63. for item in config.sections():
  64. self.config[item] = self.readConfig(config, item)
  65. return True
  66. else:
  67. Demeter.echo(filename + ' is not exists')
  68. sys.exit()
  69. @staticmethod
  70. def readConfig(config, type):
  71. value = config.options(type)
  72. result = {}
  73. for item in value:
  74. result[item] = config.get(type, item)
  75. return result
  76. @classmethod
  77. """
  78. param = {}
  79. param['action'] = 'a'
  80. param['name'] = 'n'
  81. param['param'] = 'p'
  82. Demeter.getopt(param)
  83. """
  84. def getopt(self, param = {}):
  85. import getopt
  86. param['help'] = 'h'
  87. shortopts = ''
  88. longopts = []
  89. check = []
  90. for k,v in param.items():
  91. if k == 'help':
  92. shortopts = shortopts + v
  93. else:
  94. shortopts = shortopts + v + ':'
  95. longopts.append(k)
  96. try:
  97. options, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
  98. for name, value in options:
  99. for k,v in param.items():
  100. if name in ('-' + v, '--' + k):
  101. if k == 'help':
  102. self.usage()
  103. else:
  104. self.option[k] = value
  105. except getopt.GetoptError:
  106. self.usage()
  107. @classmethod
  108. def usage(self, name = 'usage'):
  109. file = self.path + name
  110. if not File.exists(file):
  111. file = self.root + name
  112. print File.read(file)
  113. sys.exit()
  114. @classmethod
  115. def temp(self, key='', name='', value=''):
  116. temp = Demeter.path + 'conf/temp.conf'
  117. if File.exists(temp):
  118. config = self.getConfig()
  119. config.read(temp)
  120. if key and name:
  121. config.set(key, name, value)
  122. config.write(open(temp, 'w'))
  123. else:
  124. result = {}
  125. for item in config.sections():
  126. result[item] = self.readConfig(config, item)
  127. return result
  128. @classmethod
  129. def echo(self, args):
  130. import pprint
  131. pprint.pprint(args)
  132. @classmethod
  133. def record(self, key, value):
  134. # 记录日志
  135. # self.log(key, value)
  136. service = self.service('record')
  137. service.push(key, value)
  138. @classmethod
  139. def service(self, name):
  140. path = 'service.'
  141. if name == 'common':
  142. path = 'demeter.'
  143. name = 'service'
  144. service = self.getClass(name, path)
  145. return service()
  146. @classmethod
  147. def adminModel(self, table):
  148. config = ('manage_admin', 'manage_log', 'manage_role')
  149. if table in config:
  150. return self.getClass(table, 'demeter.admin.model.')
  151. return False
  152. @classmethod
  153. def model(self, table, name='rdb'):
  154. name = self.config['db'][name]
  155. config = self.config[name]
  156. obj = self.getObject('db', 'demeter.')
  157. db = getattr(obj, name.capitalize())
  158. connect = db(config).get()
  159. model = self.adminModel(table)
  160. if not model:
  161. model = self.getClass(table, 'model.')
  162. return model(name, connect, config)
  163. @classmethod
  164. def getMethod(self, module):
  165. import inspect
  166. return inspect.getmembers(module, callable)
  167. @classmethod
  168. def getPackage(self, package):
  169. import pkgutil
  170. for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__, prefix=package.__name__ + '.', onerror=lambda x: None):
  171. yield modname
  172. @staticmethod
  173. def getObject(name, path = ''):
  174. return importlib.import_module(path + name)
  175. """
  176. @classmethod
  177. def getObject(self, name, path = ''):
  178. module = __import__(path + name)
  179. return getattr(module, name)
  180. """
  181. @classmethod
  182. def getClass(self, name, path=''):
  183. obj = self.getObject(name, path)
  184. return getattr(obj, name.capitalize())
  185. @staticmethod
  186. def bool(value, type = 'db'):
  187. if type == 'mysql':
  188. value = value == str(True)
  189. if value == True:
  190. return '1'
  191. else:
  192. return '2'
  193. else:
  194. return value == str(True)
  195. @classmethod
  196. def runtime(self, path, file, content=''):
  197. path = self.path + 'runtime/' + path + '/'
  198. File.mkdir(path)
  199. file = path + file
  200. if File.exists(file):
  201. return False
  202. else:
  203. File.write(file, content)
  204. return True
  205. @classmethod
  206. def webInit(self, name):
  207. self.web = name
  208. self.webPath = self.path + self.web + '/'
  209. if self.web == 'admin':
  210. self.webPath = self.root + self.web + '/'
  211. self.getObject('main', name + '.')
  212. @classmethod
  213. def md5(self, value, salt=False):
  214. import hashlib
  215. if salt:
  216. if salt == True:
  217. salt = self.rand()
  218. value = value + salt
  219. return hashlib.md5(value.encode("utf-8")).hexdigest() + '_' + salt
  220. else:
  221. return hashlib.md5(value.encode("utf-8")).hexdigest()
  222. @classmethod
  223. def rand(self, length = 4):
  224. module = self.getObject('random')
  225. rand = getattr(module, 'randint')
  226. salt = ''
  227. chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  228. len_chars = len(chars) - 1
  229. for i in range(length):
  230. salt += chars[rand(0, len_chars)]
  231. return salt
  232. @staticmethod
  233. def hour(value):
  234. if value < 10:
  235. return '0' + str(value)
  236. return value
  237. @staticmethod
  238. def time():
  239. return int(time.time())
  240. @staticmethod
  241. def mktime(value, string='%Y-%m-%d %H:%M:%S'):
  242. if ' ' in string and ' ' not in value:
  243. value = value + ' 00:00:00'
  244. return int(time.mktime(time.strptime(value,string)))
  245. @classmethod
  246. def date(self, value, string='%Y-%m-%d %H:%M:%S'):
  247. module = self.getObject('datetime')
  248. datetime = getattr(module, 'datetime')
  249. fromtimestamp = getattr(datetime, 'fromtimestamp')
  250. return str(fromtimestamp(value).strftime(string))
  251. @staticmethod
  252. def isJson(value):
  253. result = False
  254. try:
  255. result = json.loads(value)
  256. except ValueError:
  257. return result
  258. return result
  259. @staticmethod
  260. def compressUuid(value):
  261. row = value.replace('-', '')
  262. code = ''
  263. hash = [x for x in "0123456789-abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
  264. for i in xrange(10):
  265. enbin = "%012d" % int(bin(int(row[i * 3] + row[i * 3 + 1] + row[i * 3 + 2], 16))[2:], 10)
  266. code += (hash[int(enbin[0:6], 2)] + hash[int(enbin[6:12], 2)])
  267. return code
  268. @staticmethod
  269. def checkMobile(request):
  270. if 'Demeter-Mobile' in request.headers:
  271. return True
  272. userAgent = request.headers['User-Agent']
  273. # userAgent = env.get('HTTP_USER_AGENT')
  274. _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'
  275. _long_matches = re.compile(_long_matches, re.IGNORECASE)
  276. _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\-'
  277. _short_matches = re.compile(_short_matches, re.IGNORECASE)
  278. if _long_matches.search(userAgent) != None:
  279. return True
  280. user_agent = userAgent[0:4]
  281. if _short_matches.search(user_agent) != None:
  282. return True
  283. return False
  284. @staticmethod
  285. def exp(exp, value):
  286. if exp:
  287. exp = exp.replace('{n}', value)
  288. value = str(eval(exp))
  289. return value
  290. @classmethod
  291. def curl(self, url):
  292. import urllib2
  293. req = urllib2.Request(url)
  294. response = urllib2.urlopen(req)
  295. return response.read()
  296. @classmethod
  297. def error(self, string):
  298. from tornado.web import Finish
  299. if self.request:
  300. self.request.out(string)
  301. #self.request.finish()
  302. raise Finish()
  303. else:
  304. self.echo(string)
  305. #os._exit(0)
  306. class File(object):
  307. @staticmethod
  308. def write(file, content):
  309. handle = open(file, 'w')
  310. handle.write(content)
  311. handle.close()
  312. Shell.popen('chmod +x ' + file)
  313. @staticmethod
  314. def read(path, name = ''):
  315. handle = open(path + name, 'r')
  316. content = handle.read()
  317. handle.close()
  318. return content
  319. @staticmethod
  320. def cur_path():
  321. return os.path.split(os.path.realpath(__file__))[0] + '/'
  322. @staticmethod
  323. def path():
  324. return os.sys.path[0] + '/'
  325. @staticmethod
  326. def exists(name):
  327. return os.path.exists(name)
  328. @staticmethod
  329. def rename(old, new):
  330. return os.rename(old, new)
  331. @staticmethod
  332. def remove(file):
  333. return os.remove(file)
  334. @staticmethod
  335. def mkdir(path):
  336. if File.exists(path) == False:
  337. os.mkdir(path)
  338. return path
  339. @staticmethod
  340. def mkdirs(path):
  341. if File.exists(path) == False:
  342. os.makedirs(path)
  343. return path
  344. class Shell(object):
  345. @staticmethod
  346. def popen(command, sub=False, bg=False, timeout=0):
  347. string = command
  348. if bg == True:
  349. command = command + ' 1>/dev/null 2>&1 &'
  350. if timeout > 0:
  351. proc = subprocess.Popen(command,bufsize=0,stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True, close_fds=True, preexec_fn = os.setsid)
  352. poll_seconds = .250
  353. deadline = time.time() + timeout
  354. while time.time() < deadline and proc.poll() == None:
  355. time.sleep(poll_seconds)
  356. if proc.poll() == None:
  357. os.killpg(proc.pid, signal.SIGTERM)
  358. return 'timeout'
  359. stdout,stderr = proc.communicate()
  360. return stdout
  361. elif sub == False:
  362. process = os.popen(command)
  363. output = process.read()
  364. process.close()
  365. return output
  366. else:
  367. popen = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
  368. output = ''
  369. Demeter.echo(string)
  370. while True:
  371. output = popen.stdout.readline()
  372. Demeter.echo(output)
  373. if popen.poll() is not None:
  374. break
  375. return output
  376. class Check(object):
  377. @staticmethod
  378. def match(rule, value):
  379. if not rule.match(value):
  380. return False
  381. return True
  382. @staticmethod
  383. def mobile(value):
  384. rule = re.compile(r'1\d{10}')
  385. return Check.match(rule, value)
  386. @staticmethod
  387. def number(value):
  388. try:
  389. int(value)
  390. return True
  391. except ValueError:
  392. return False
  393. @staticmethod
  394. def numberFloat(value):
  395. try:
  396. float(value)
  397. return True
  398. except ValueError:
  399. return False
  400. Demeter.initConfig()