diff --git a/class/core/db.py b/class/core/db.py new file mode 100755 index 000000000..e15339ca1 --- /dev/null +++ b/class/core/db.py @@ -0,0 +1,276 @@ +# coding: utf-8 + + +import sqlite3 +import os + + +class Sql(): + #------------------------------ + # 数据库操作类 For sqlite3 + #------------------------------ + __DB_FILE = None # 数据库文件 + __DB_CONN = None # 数据库连接对象 + __DB_TABLE = "" # 被操作的表名称 + __OPT_WHERE = "" # where条件 + __OPT_LIMIT = "" # limit条件 + __OPT_ORDER = "" # order条件 + __OPT_FIELD = "*" # field条件 + __OPT_PARAM = () # where值 + + def __init__(self): + self.__DB_FILE = 'data/default.db' + + def __GetConn(self): + # 取数据库对象 + try: + if self.__DB_CONN == None: + self.__DB_CONN = sqlite3.connect(self.__DB_FILE) + except Exception, ex: + return "error: " + str(ex) + + def dbfile(self, name): + self.__DB_FILE = 'data/' + name + '.db' + return self + + def table(self, table): + # 设置表名 + self.__DB_TABLE = table + return self + + def where(self, where, param): + # WHERE条件 + if where: + self.__OPT_WHERE = " WHERE " + where + self.__OPT_PARAM = param + return self + + def order(self, order): + # ORDER条件 + if len(order): + self.__OPT_ORDER = " ORDER BY " + order + return self + + def limit(self, limit): + # LIMIT条件 + if len(limit): + self.__OPT_LIMIT = " LIMIT " + limit + return self + + def field(self, field): + # FIELD条件 + if len(field): + self.__OPT_FIELD = field + return self + + def select(self): + # 查询数据集 + self.__GetConn() + try: + sql = "SELECT " + self.__OPT_FIELD + " FROM " + self.__DB_TABLE + \ + self.__OPT_WHERE + self.__OPT_ORDER + self.__OPT_LIMIT + result = self.__DB_CONN.execute(sql, self.__OPT_PARAM) + data = result.fetchall() + # 构造字曲系列 + if self.__OPT_FIELD != "*": + field = self.__OPT_FIELD.split(',') + tmp = [] + for row in data: + i = 0 + tmp1 = {} + for key in field: + tmp1[key] = row[i] + i += 1 + tmp.append(tmp1) + del(tmp1) + data = tmp + del(tmp) + else: + # 将元组转换成列表 + tmp = map(list, data) + data = tmp + del(tmp) + self.__close() + return data + except Exception, ex: + return "error: " + str(ex) + + def getField(self, keyName): + # 取回指定字段 + result = self.field(keyName).select() + if len(result) == 1: + return result[0][keyName] + return result + + def setField(self, keyName, keyValue): + # 更新指定字段 + return self.save(keyName, (keyValue,)) + + def find(self): + # 取一行数据 + result = self.limit("1").select() + if len(result) == 1: + return result[0] + return result + + def count(self): + # 取行数 + key = "COUNT(*)" + data = self.field(key).select() + try: + return int(data[0][key]) + except: + return 0 + + def add(self, keys, param): + # 插入数据 + self.__GetConn() + self.__DB_CONN.text_factory = str + try: + values = "" + for key in keys.split(','): + values += "?," + values = self.checkInput(values[0:len(values) - 1]) + sql = "INSERT INTO " + self.__DB_TABLE + \ + "(" + keys + ") " + "VALUES(" + values + ")" + result = self.__DB_CONN.execute(sql, param) + id = result.lastrowid + self.__close() + self.__DB_CONN.commit() + return id + except Exception, ex: + return "error: " + str(ex) + + def checkInput(self, data): + if not data: + return data + if type(data) != str: + return data + checkList = [ + {'d': '<', 'r': '<'}, + {'d': '>', 'r': '>'}, + {'d': '\'', 'r': '‘'}, + {'d': '"', 'r': '“'}, + {'d': '&', 'r': '&'}, + {'d': '#', 'r': '#'}, + {'d': '<', 'r': '<'} + ] + for v in checkList: + data = data.replace(v['d'], v['r']) + return data + + def addAll(self, keys, param): + # 插入数据 + self.__GetConn() + self.__DB_CONN.text_factory = str + try: + values = "" + for key in keys.split(','): + values += "?," + values = values[0:len(values) - 1] + sql = "INSERT INTO " + self.__DB_TABLE + \ + "(" + keys + ") " + "VALUES(" + values + ")" + result = self.__DB_CONN.execute(sql, param) + return True + except Exception, ex: + return "error: " + str(ex) + + def commit(self): + self.__close() + self.__DB_CONN.commit() + + def save(self, keys, param): + # 更新数据 + self.__GetConn() + self.__DB_CONN.text_factory = str + try: + opt = "" + for key in keys.split(','): + opt += key + "=?," + opt = opt[0:len(opt) - 1] + sql = "UPDATE " + self.__DB_TABLE + " SET " + opt + self.__OPT_WHERE + + import public + public.writeFile('/tmp/test.pl', sql) + + # 处理拼接WHERE与UPDATE参数 + tmp = list(param) + for arg in self.__OPT_PARAM: + tmp.append(arg) + self.__OPT_PARAM = tuple(tmp) + result = self.__DB_CONN.execute(sql, self.__OPT_PARAM) + self.__close() + self.__DB_CONN.commit() + return result.rowcount + except Exception, ex: + return "error: " + str(ex) + + def delete(self, id=None): + # 删除数据 + self.__GetConn() + try: + if id: + self.__OPT_WHERE = " WHERE id=?" + self.__OPT_PARAM = (id,) + sql = "DELETE FROM " + self.__DB_TABLE + self.__OPT_WHERE + result = self.__DB_CONN.execute(sql, self.__OPT_PARAM) + self.__close() + self.__DB_CONN.commit() + return result.rowcount + except Exception, ex: + return "error: " + str(ex) + + def execute(self, sql, param): + # 执行SQL语句返回受影响行 + self.__GetConn() + try: + result = self.__DB_CONN.execute(sql, param) + self.__DB_CONN.commit() + return result.rowcount + except Exception, ex: + return "error: " + str(ex) + + def query(self, sql, param): + # 执行SQL语句返回数据集 + self.__GetConn() + try: + result = self.__DB_CONN.execute(sql, param) + # 将元组转换成列表 + data = map(list, result) + return data + except Exception, ex: + return "error: " + str(ex) + + def create(self, name): + # 创建数据表 + self.__GetConn() + import public + script = public.readFile('data/' + name + '.sql') + result = self.__DB_CONN.executescript(script) + self.__DB_CONN.commit() + return result.rowcount + + def fofile(self, filename): + # 执行脚本 + self.__GetConn() + import public + script = public.readFile(filename) + result = self.__DB_CONN.executescript(script) + self.__DB_CONN.commit() + return result.rowcount + + def __close(self): + # 清理条件属性 + self.__OPT_WHERE = "" + self.__OPT_FIELD = "*" + self.__OPT_ORDER = "" + self.__OPT_LIMIT = "" + self.__OPT_PARAM = () + + def close(self): + # 释放资源 + try: + self.__DB_CONN.close() + self.__DB_CONN = None + except: + pass diff --git a/class/core/page.py b/class/core/page.py new file mode 100755 index 000000000..d4bd24945 --- /dev/null +++ b/class/core/page.py @@ -0,0 +1,222 @@ +# coding: utf-8 + +import math +import string +import public + + +class Page(): + #-------------------------- + # 分页类 - JS回调版 + #-------------------------- + __PREV = '上一页' + __NEXT = '下一页' + __START = '首页' + __END = '尾页' + __COUNT_START = '共' + __COUNT_END = '条数据' + __FO = '从' + __LINE = '条' + __LIST_NUM = 4 + SHIFT = None # 偏移量 + ROW = None # 每页行数 + __C_PAGE = None # 当前页 + __COUNT_PAGE = None # 总页数 + __COUNT_ROW = None # 总行数 + __URI = None # URI + __RTURN_JS = False # 是否返回JS回调 + __START_NUM = None # 起始行 + __END_NUM = None # 结束行 + + def __init__(self): + tmp = public.getMsg('PAGE') + if tmp: + self.__PREV = tmp['PREV'] + self.__NEXT = tmp['NEXT'] + self.__START = tmp['START'] + self.__END = tmp['END'] + self.__COUNT_START = tmp['COUNT_START'] + self.__COUNT_END = tmp['COUNT_END'] + self.__FO = tmp['FO'] + self.__LINE = tmp['LINE'] + + def GetPage(self, pageInfo, limit='1,2,3,4,5,6,7,8'): + # 取分页信息 + # @param pageInfo 传入分页参数字典 + # @param limit 返回系列 + self.__RTURN_JS = pageInfo['return_js'] + self.__COUNT_ROW = pageInfo['count'] + self.ROW = pageInfo['row'] + self.__C_PAGE = self.__GetCpage(pageInfo['p']) + self.__START_NUM = self.__StartRow() + self.__END_NUM = self.__EndRow() + self.__COUNT_PAGE = self.__GetCountPage() + self.__URI = self.__SetUri(pageInfo['uri']) + self.SHIFT = self.__START_NUM - 1 + + keys = limit.split(',') + + pages = {} + # 起始页 + pages['1'] = self.__GetStart() + # 上一页 + pages['2'] = self.__GetPrev() + # 分页 + pages['3'] = self.__GetPages() + # 下一页 + pages['4'] = self.__GetNext() + # 尾页 + pages['5'] = self.__GetEnd() + + # 当前显示页与总页数 + pages['6'] = "" + \ + bytes(self.__C_PAGE) + "/" + bytes(self.__COUNT_PAGE) + "" + # 本页显示开始与结束行 + pages['7'] = "" + self.__FO + \ + bytes(self.__START_NUM) + "-" + \ + bytes(self.__END_NUM) + self.__LINE + "" + # 行数 + pages['8'] = "" + self.__COUNT_START + \ + bytes(self.__COUNT_ROW) + self.__COUNT_END + "" + + # 构造返回数据 + retuls = '
' + for value in keys: + retuls += pages[value] + retuls += '
' + + # 返回分页数据 + return retuls + + def __GetEnd(self): + # 构造尾页 + endStr = "" + if self.__C_PAGE >= self.__COUNT_PAGE: + endStr = '' + else: + if self.__RTURN_JS == "": + endStr = "" + self.__END + "" + else: + endStr = "" + self.__END + "" + return endStr + + def __GetNext(self): + # 构造下一页 + nextStr = "" + if self.__C_PAGE >= self.__COUNT_PAGE: + nextStr = '' + else: + if self.__RTURN_JS == "": + nextStr = "" + self.__NEXT + "" + else: + nextStr = "" + self.__NEXT + "" + + return nextStr + + def __GetPages(self): + # 构造分页 + pages = '' + num = 0 + # 当前页之前 + if (self.__COUNT_PAGE - self.__C_PAGE) < self.__LIST_NUM: + num = self.__LIST_NUM + \ + (self.__LIST_NUM - (self.__COUNT_PAGE - self.__C_PAGE)) + else: + num = self.__LIST_NUM + n = 0 + for i in range(num): + n = num - i + page = self.__C_PAGE - n + if page > 0: + if self.__RTURN_JS == "": + pages += "" + bytes(page) + "" + else: + pages += "" + bytes(page) + "" + + # 当前页 + if self.__C_PAGE > 0: + pages += "" + \ + bytes(self.__C_PAGE) + "" + + # 当前页之后 + if self.__C_PAGE <= self.__LIST_NUM: + num = self.__LIST_NUM + (self.__LIST_NUM - self.__C_PAGE) + 1 + else: + num = self.__LIST_NUM + for i in range(num): + if i == 0: + continue + page = self.__C_PAGE + i + if page > self.__COUNT_PAGE: + break + if self.__RTURN_JS == "": + pages += "" + bytes(page) + "" + else: + pages += "" + bytes(page) + "" + + return pages + + def __GetPrev(self): + # 构造上一页 + startStr = '' + if self.__C_PAGE == 1: + startStr = '' + else: + if self.__RTURN_JS == "": + startStr = "" + self.__PREV + "" + else: + startStr = "" + self.__PREV + "" + return startStr + + def __GetStart(self): + # 构造起始分页 + startStr = '' + if self.__C_PAGE == 1: + startStr = '' + else: + if self.__RTURN_JS == "": + startStr = "" + self.__START + "" + else: + startStr = "" + self.__START + "" + return startStr + + def __GetCpage(self, p): + # 取当前页 + if p: + return p + return 1 + + def __StartRow(self): + # 从多少行开始 + return (self.__C_PAGE - 1) * self.ROW + 1 + + def __EndRow(self): + # 从多少行结束 + if self.ROW > self.__COUNT_ROW: + return self.__COUNT_ROW + return self.__C_PAGE * self.ROW + + def __GetCountPage(self): + # 取总页数 + return int(math.ceil(self.__COUNT_ROW / float(self.ROW))) + + def __SetUri(self, input): + # 构造URI + uri = '?' + for key in input: + if key == 'p': + continue + uri += key + '=' + input[key] + '&' + return str(uri) diff --git a/class/core/public.py b/class/core/public.py new file mode 100755 index 000000000..bc46ff396 --- /dev/null +++ b/class/core/public.py @@ -0,0 +1,872 @@ +# coding: utf-8 + +import os +import sys +import time +import string +import json +import hashlib +import shlex +import datetime +import subprocess +import re +import hashlib + + +sys.path.append(os.getcwd() + "/class/") +import db + +from random import Random + + +def getRunDir(): + # 运行目录 + return os.getcwd() + + +def getBinDir(): + # 安装软件 + pass + + +def M(table): + sql = db.Sql() + return sql.table(table) + + +def getWebPage(data, args): + # 取分页 + import page + # 实例化分页类 + page = page.Page() + info = {} + info['count'] = len(data) + + info['row'] = 10 + if hasattr(args, 'row'): + info['row'] = args['row'] + + info['p'] = 1 + if hasattr(args, 'p'): + info['p'] = int(get['p']) + info['uri'] = {} + info['return_js'] = '' + if hasattr(args, 'tojs'): + info['return_js'] = args.tojs + + # 获取分页数据 + result = {} + result['page'] = page.GetPage(info) + return result + + +def md5(str): + # 生成MD5 + try: + m = hashlib.md5() + m.update(str) + return m.hexdigest() + except: + return False + + +def GetFileMd5(filename): + # 文件的MD5值 + if not os.path.isfile(filename): + return False + + myhash = hashlib.md5() + f = file(filename, 'rb') + while True: + b = f.read(8096) + if not b: + break + myhash.update(b) + f.close() + return myhash.hexdigest() + + +def GetRandomString(length): + # 取随机字符串 + str = '' + chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789' + chrlen = len(chars) - 1 + random = Random() + for i in range(length): + str += chars[random.randint(0, chrlen)] + return str + + +def getJson(data): + import json + return json.dumps(data) + + +def returnJson(status, msg, args=()): + # 取通用Json返回 + return getJson(returnMsg(status, msg, args)) + + +def returnMsg(status, msg, args=()): + # 取通用字曲返回 + logMessage = json.loads( + readFile('static/language/' + get_language() + '/public.json')) + keys = logMessage.keys() + if msg in keys: + msg = logMessage[msg] + for i in range(len(args)): + rep = '{' + str(i + 1) + '}' + msg = msg.replace(rep, args[i]) + return {'status': status, 'msg': msg} + + +def getMsg(key, args=()): + # 取提示消息 + try: + logMessage = json.loads( + readFile('static/language/' + get_language() + '/public.json')) + keys = logMessage.keys() + msg = None + if key in keys: + msg = logMessage[key] + for i in range(len(args)): + rep = '{' + str(i + 1) + '}' + msg = msg.replace(rep, args[i]) + return msg + except: + return key + + +def getLan(key): + # 取提示消息 + + logMessage = json.loads( + readFile('static/language/' + get_language() + '/template.json')) + keys = logMessage.keys() + msg = None + if key in keys: + msg = logMessage[key] + return msg + + +def readFile(filename): + # 读文件内容 + try: + fp = open(filename, 'r') + fBody = fp.read() + fp.close() + return fBody + except: + return False + + +def getDate(): + # 取格式时间 + import time + return time.strftime('%Y-%m-%d %X', time.localtime()) + + +def get_language(): + path = 'data/language.pl' + if not os.path.exists(path): + return 'Simplified_Chinese' + return readFile(path).strip() + + +def writeLog(type, logMsg, args=()): + # 写日志 + try: + import time + import db + import json + logMessage = json.loads( + readFile('static/language/' + get_language() + '/log.json')) + keys = logMessage.keys() + if logMsg in keys: + logMsg = logMessage[logMsg] + for i in range(len(args)): + rep = '{' + str(i + 1) + '}' + logMsg = logMsg.replace(rep, args[i]) + if type in keys: + type = logMessage[type] + sql = db.Sql() + mDate = time.strftime('%Y-%m-%d %X', time.localtime()) + data = (type, logMsg, mDate) + result = sql.table('logs').add('type,log,addtime', data) + except: + pass + + +def writeFile(filename, str): + # 写文件内容 + try: + fp = open(filename, 'w+') + fp.write(str) + fp.close() + return True + except: + return False + + +def httpGet(url, timeout=30): + # 发送GET请求 + try: + import urllib2 + import ssl + try: + ssl._create_default_https_context = ssl._create_unverified_context + except: + pass + response = urllib2.urlopen(url, timeout=timeout) + return response.read() + except Exception, ex: + # WriteLog('网络诊断',str(ex) + '['+url+']'); + return str(ex) + + +def httpPost(url, data, timeout=30): + # 发送POST请求 + try: + import urllib + import urllib2 + import ssl + try: + ssl._create_default_https_context = ssl._create_unverified_context + except: + pass + data = urllib.urlencode(data) + req = urllib2.Request(url, data) + response = urllib2.urlopen(req, timeout=timeout) + return response.read() + except Exception, ex: + # WriteLog('网络诊断',str(ex) + '['+url+']'); + return str(ex) + + +def writeSpeed(title, used, total, speed=0): + # 写进度 + if not title: + data = {'title': None, 'progress': 0, + 'total': 0, 'used': 0, 'speed': 0} + else: + progress = int((100.0 * used / total)) + data = {'title': title, 'progress': progress, + 'total': total, 'used': used, 'speed': speed} + writeFile('/tmp/panelSpeed.pl', json.dumps(data)) + return True + + +def getSpeed(): + # 取进度 + data = readFile('/tmp/panelSpeed.pl') + if not data: + data = json.dumps({'title': None, 'progress': 0, + 'total': 0, 'used': 0, 'speed': 0}) + writeFile('/tmp/panelSpeed.pl', data) + return json.loads(data) + + +def getLastLine(inputfile, lineNum): + # 读文件指定倒数行数 + try: + fp = open(inputfile, 'r') + lastLine = "" + + lines = fp.readlines() + count = len(lines) + if count > lineNum: + num = lineNum + else: + num = count + i = 1 + lastre = [] + for i in range(1, (num + 1)): + if lines: + n = -i + lastLine = lines[n].strip() + fp.close() + lastre.append(lastLine) + + result = '' + num -= 1 + while num >= 0: + result += lastre[num] + "\n" + num -= 1 + return result + except: + return getMsg('TASK_SLEEP') + + +def ExecShell(cmdstring, cwd=None, timeout=None, shell=True): + + if shell: + cmdstring_list = cmdstring + else: + cmdstring_list = shlex.split(cmdstring) + if timeout: + end_time = datetime.datetime.now() + datetime.timedelta(seconds=timeout) + + sub = subprocess.Popen(cmdstring_list, cwd=cwd, stdin=subprocess.PIPE, + shell=shell, bufsize=4096, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + while sub.poll() is None: + time.sleep(0.1) + if timeout: + if end_time <= datetime.datetime.now(): + raise Exception("Timeout:%s" % cmdstring) + + return sub.communicate() + + +def serviceReload(): + # 重载Web服务配置 + if os.path.exists('/www/server/nginx/sbin/nginx'): + result = ExecShell('/etc/init.d/nginx reload') + if result[1].find('nginx.pid') != -1: + ExecShell('pkill -9 nginx && sleep 1') + ExecShell('/etc/init.d/nginx start') + else: + result = ExecShell('/etc/init.d/httpd reload') + return result + + +def phpReload(version): + # 重载PHP配置 + import os + if os.path.exists('/www/server/php/' + version + '/libphp5.so'): + ExecShell('/etc/init.d/httpd reload') + else: + ExecShell('/etc/init.d/php-fpm-' + version + ' reload') + + +def downloadFile(url, filename): + import urllib + urllib.urlretrieve(url, filename=filename, reporthook=downloadHook) + + +def downloadHook(count, blockSize, totalSize): + speed = {'total': totalSize, 'block': blockSize, 'count': count} + print speed + print '%02d%%' % (100.0 * count * blockSize / totalSize) + + +def GetLocalIp(): + # 取本地外网IP + try: + import re + filename = 'data/iplist.txt' + ipaddress = readFile(filename) + if not ipaddress: + import urllib2 + url = 'http://pv.sohu.com/cityjson?ie=utf-8' + opener = urllib2.urlopen(url) + str = opener.read() + ipaddress = re.search('\d+.\d+.\d+.\d+', str).group(0) + writeFile(filename, ipaddress) + + ipaddress = re.search('\d+.\d+.\d+.\d+', ipaddress).group(0) + return ipaddress + except: + pass + # try: + # url = web.ctx.session.home + '/Api/getIpAddress' + # opener = urllib2.urlopen(url) + # return opener.read() + # except: + # return web.ctx.host.split(':')[0] + + +def inArray(arrays, searchStr): + # 搜索数据中是否存在 + for key in arrays: + if key == searchStr: + return True + + return False + + +def checkWebConfig(): + # 检查Web服务器配置文件是否有错误 + if get_webserver() == 'nginx': + result = ExecShell( + "ulimit -n 10240 && /www/server/nginx/sbin/nginx -t -c /www/server/nginx/conf/nginx.conf") + searchStr = 'successful' + else: + result = ExecShell( + "ulimit -n 10240 && /www/server/apache/bin/apachectl -t") + searchStr = 'Syntax OK' + + if result[1].find(searchStr) == -1: + WriteLog("TYPE_SOFT", 'CONF_CHECK_ERR', (result[1],)) + return result[1] + return True + + +def checkIp(ip): + # 检查是否为IPv4地址 + import re + p = re.compile( + '^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$') + if p.match(ip): + return True + else: + return False + + +def checkPort(port): + # 检查端口是否合法 + ports = ['21', '25', '443', '8080', '888', '8888', '8443'] + if port in ports: + return False + intport = int(port) + if intport < 1 or intport > 65535: + return False + return True + + +def getStrBetween(startStr, endStr, srcStr): + # 字符串取中间 + start = srcStr.find(startStr) + if start == -1: + return None + end = srcStr.find(endStr) + if end == -1: + return None + return srcStr[start + 1:end] + + +def getCpuType(): + # 取CPU类型 + cpuinfo = open('/proc/cpuinfo', 'r').read() + rep = "model\s+name\s+:\s+(.+)" + tmp = re.search(rep, cpuinfo) + cpuType = None + if tmp: + cpuType = tmp.groups()[0] + return cpuType + + +def IsRestart(): + # 检查是否允许重启 + num = M('tasks').where('status!=?', ('1',)).count() + if num > 0: + return False + return True + + +def hasPwd(password): + # 加密密码字符 + import crypt + return crypt.crypt(password, password) + + +def CheckMyCnf(): + # 处理MySQL配置文件 + import os + confFile = '/etc/my.cnf' + if os.path.exists(confFile): + conf = readFile(confFile) + if len(conf) > 100: + return True + versionFile = '/www/server/mysql/version.pl' + if not os.path.exists(versionFile): + return False + + versions = ['5.1', '5.5', '5.6', '5.7', 'AliSQL'] + version = readFile(versionFile) + for key in versions: + if key in version: + version = key + break + + shellStr = ''' +#!/bin/bash +PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin +export PATH + +CN='125.88.182.172' +HK='download.bt.cn' +HK2='103.224.251.67' +US='174.139.221.74' +sleep 0.5; +CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"` +HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"` +HK2_PING=`ping -c 1 -w 1 $HK2|grep time=|awk '{print $7}'|sed "s/time=//"` +US_PING=`ping -c 1 -w 1 $US|grep time=|awk '{print $7}'|sed "s/time=//"` + +echo "$HK_PING $HK" > ping.pl +echo "$HK2_PING $HK2" >> ping.pl +echo "$US_PING $US" >> ping.pl +echo "$CN_PING $CN" >> ping.pl +nodeAddr=`sort -V ping.pl|sed -n '1p'|awk '{print $2}'` +if [ "$nodeAddr" == "" ];then + nodeAddr=$HK +fi + +Download_Url=http://$nodeAddr:5880 + + +MySQL_Opt() +{ + MemTotal=`free -m | grep Mem | awk '{print $2}'` + if [[ ${MemTotal} -gt 1024 && ${MemTotal} -lt 2048 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 32M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 128#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 768K#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 768K#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 8M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 16#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 16M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 32M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 128M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 32M#" /etc/my.cnf + elif [[ ${MemTotal} -ge 2048 && ${MemTotal} -lt 4096 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 64M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 256#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 1M#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 1M#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 16M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 32#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 32M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 64M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 256M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 64M#" /etc/my.cnf + elif [[ ${MemTotal} -ge 4096 && ${MemTotal} -lt 8192 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 128M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 512#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 2M#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 2M#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 32M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 64#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 64M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 64M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 512M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 128M#" /etc/my.cnf + elif [[ ${MemTotal} -ge 8192 && ${MemTotal} -lt 16384 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 256M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 1024#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 4M#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 4M#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 64M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 128#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 128M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 128M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 1024M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 256M#" /etc/my.cnf + elif [[ ${MemTotal} -ge 16384 && ${MemTotal} -lt 32768 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 512M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 2048#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 8M#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 8M#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 128M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 256#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 256M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 256M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 2048M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 512M#" /etc/my.cnf + elif [[ ${MemTotal} -ge 32768 ]]; then + sed -i "s#^key_buffer_size.*#key_buffer_size = 1024M#" /etc/my.cnf + sed -i "s#^table_open_cache.*#table_open_cache = 4096#" /etc/my.cnf + sed -i "s#^sort_buffer_size.*#sort_buffer_size = 16M#" /etc/my.cnf + sed -i "s#^read_buffer_size.*#read_buffer_size = 16M#" /etc/my.cnf + sed -i "s#^myisam_sort_buffer_size.*#myisam_sort_buffer_size = 256M#" /etc/my.cnf + sed -i "s#^thread_cache_size.*#thread_cache_size = 512#" /etc/my.cnf + sed -i "s#^query_cache_size.*#query_cache_size = 512M#" /etc/my.cnf + sed -i "s#^tmp_table_size.*#tmp_table_size = 512M#" /etc/my.cnf + sed -i "s#^innodb_buffer_pool_size.*#innodb_buffer_pool_size = 4096M#" /etc/my.cnf + sed -i "s#^innodb_log_file_size.*#innodb_log_file_size = 1024M#" /etc/my.cnf + fi +} + +wget -O /etc/my.cnf $Download_Url/install/conf/mysql-%s.conf -T 5 +MySQL_Opt +''' % (version,) + # 判断是否迁移目录 + if os.path.exists('data/datadir.pl'): + newPath = public.readFile('data/datadir.pl') + mycnf = public.readFile('/etc/my.cnf') + mycnf = mycnf.replace('/www/server/data', newPath) + public.writeFile('/etc/my.cnf', mycnf) + + os.system(shellStr) + WriteLog('TYPE_SOFE', 'MYSQL_CHECK_ERR') + return True + + +def get_url(timeout=0.5): + import json + try: + nodeFile = '/www/server/panel/data/node.json' + node_list = json.loads(readFile(nodeFile)) + mnode = None + for node in node_list: + node['ping'] = get_timeout( + node['protocol'] + node['address'] + ':' + node['port'] + '/check.txt') + if not node['ping']: + continue + if not mnode: + mnode = node + if node['ping'] < mnode['ping']: + mnode = node + return mnode['protocol'] + mnode['address'] + ':' + mnode['port'] + except: + return 'http://download.bt.cn' + + +def get_timeout(url): + start = time.time() + result = httpGet(url) + if result != 'True': + return False + return int((time.time() - start) * 1000) + + +# 获取Token +def GetToken(): + try: + from json import loads + tokenFile = 'data/token.json' + if not os.path.exists(tokenFile): + return False + token = loads(public.readFile(tokenFile)) + return token + except: + return False + +# 解密数据 + + +def auth_decode(data): + token = GetToken() + # 是否有生成Token + if not token: + return returnMsg(False, 'REQUEST_ERR') + + # 校验access_key是否正确 + if token['access_key'] != data['btauth_key']: + return returnMsg(False, 'REQUEST_ERR') + + # 解码数据 + import binascii + import hashlib + import urllib + import hmac + import json + tdata = binascii.unhexlify(data['data']) + + # 校验signature是否正确 + signature = binascii.hexlify( + hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest()) + if signature != data['signature']: + return returnMsg(False, 'REQUEST_ERR') + + # 返回 + return json.loads(urllib.unquote(tdata)) + + +# 数据加密 +def auth_encode(data): + token = GetToken() + pdata = {} + + # 是否有生成Token + if not token: + return returnMsg(False, 'REQUEST_ERR') + + # 生成signature + import binascii + import hashlib + import urllib + import hmac + import json + tdata = urllib.quote(json.dumps(data)) + # 公式 hex(hmac_sha256(data)) + pdata['signature'] = binascii.hexlify( + hmac.new(token['secret_key'], tdata, digestmod=hashlib.sha256).digest()) + + # 加密数据 + pdata['btauth_key'] = token['access_key'] + pdata['data'] = binascii.hexlify(tdata) + pdata['timestamp'] = time.time() + + # 返回 + return pdata + +# 检查Token + + +def checkToken(get): + tempFile = 'data/tempToken.json' + if not os.path.exists(tempFile): + return False + import json + import time + tempToken = json.loads(readFile(tempFile)) + if time.time() > tempToken['timeout']: + return False + if get.token != tempToken['token']: + return False + return True + + +def get_webserver(): + # 获取Web服务器 + webserver = 'nginx' + if not os.path.exists('/www/server/nginx/sbin/nginx'): + webserver = 'apache' + return webserver + + +def checkInput(data): + # 过滤输入 + if not data: + return data + if type(data) != str: + return data + checkList = [ + {'d': '<', 'r': '<'}, + {'d': '>', 'r': '>'}, + {'d': '\'', 'r': '‘'}, + {'d': '"', 'r': '“'}, + {'d': '&', 'r': '&'}, + {'d': '#', 'r': '#'}, + {'d': '<', 'r': '<'} + ] + for v in checkList: + data = data.replace(v['d'], v['r']) + return data + + +def GetNumLines(path, num, p=1): + # 取文件指定尾行数 + try: + import cgi + if not os.path.exists(path): + return "" + start_line = (p - 1) * num + count = start_line + num + fp = open(path) + buf = "" + fp.seek(-1, 2) + if fp.read(1) == "\n": + fp.seek(-1, 2) + data = [] + b = True + n = 0 + for i in range(count): + while True: + newline_pos = string.rfind(buf, "\n") + pos = fp.tell() + if newline_pos != -1: + if n >= start_line: + line = buf[newline_pos + 1:] + try: + data.insert(0, cgi.escape(line)) + except: + pass + buf = buf[:newline_pos] + n += 1 + break + else: + if pos == 0: + b = False + break + to_read = min(4096, pos) + fp.seek(-to_read, 1) + buf = fp.read(to_read) + buf + fp.seek(-to_read, 1) + if pos - to_read == 0: + buf = "\n" + buf + if not b: + break + fp.close() + except: + data = [] + return "\n".join(data) + + +def CheckCert(certPath='ssl/certificate.pem'): + # 验证证书 + openssl = '/usr/local/openssl/bin/openssl' + if not os.path.exists(openssl): + openssl = 'openssl' + certPem = readFile(certPath) + s = "\n-----BEGIN CERTIFICATE-----" + tmp = certPem.strip().split(s) + for tmp1 in tmp: + if tmp1.find('-----BEGIN CERTIFICATE-----') == -1: + tmp1 = s + tmp1 + writeFile(certPath, tmp1) + result = ExecShell(openssl + " x509 -in " + + certPath + " -noout -subject") + if result[1].find('-bash:') != -1: + return True + if len(result[1]) > 2: + return False + if result[0].find('error:') != -1: + return False + return True + + # 获取面板地址 + + +# def getPanelAddr(): +# import web +# protocol = 'https://' if os.path.exists("data/ssl.pl") else 'http://' +# h = web.ctx.host.split(':') +# try: +# result = protocol + h[0] + ':' + h[1] +# except: +# result = protocol + h[0] + ':' + readFile('data/port.pl').strip() +# return result + + +def to_size(size): + # 字节单位转换 + d = ('b', 'KB', 'MB', 'GB', 'TB') + s = d[0] + for b in d: + if size < 1024: + return str(size) + ' ' + b + size = size / 1024 + s = b + return str(size) + ' ' + b + + +def get_string(t): + if t != -1: + max = 126 + m_types = [{'m': 122, 'n': 97}, {'m': 90, 'n': 65}, {'m': 57, 'n': 48}, { + 'm': 47, 'n': 32}, {'m': 64, 'n': 58}, {'m': 96, 'n': 91}, {'m': 125, 'n': 123}] + else: + max = 256 + t = 0 + m_types = [{'m': 255, 'n': 0}] + arr = [] + for i in range(max): + if i < m_types[t]['n'] or i > m_types[t]['m']: + continue + arr.append(chr(i)) + return arr + + +def get_string_find(t): + if type(t) != list: + t = [t] + return_str = '' + for s1 in t: + return_str += get_string(int(s1[0]))[int(s1[1:])] + return return_str + + +def get_string_arr(t): + s_arr = {} + t_arr = [] + for s1 in t: + for i in range(6): + if not i in s_arr: + s_arr[i] = get_string(i) + for j in range(len(s_arr[i])): + if s1 == s_arr[i][j]: + t_arr.append(str(i) + str(j)) + return t_arr diff --git a/class/core/system.py b/class/core/system.py new file mode 100755 index 000000000..e23330620 --- /dev/null +++ b/class/core/system.py @@ -0,0 +1,700 @@ +# coding: utf-8 + +import psutil +import time +import os +import public +import re + + +class system: + setupPath = None + pids = None + + def __init__(self): + self.setupPath = '/www/server' + + def GetConcifInfo(self, get=None): + # 取环境配置信息 + if not hasattr(web.ctx.session, 'config'): + web.ctx.session.config = public.M('config').where("id=?", ('1',)).field( + 'webserver,sites_path,backup_path,status,mysql_root').find() + if not hasattr(web.ctx.session.config, 'email'): + web.ctx.session.config['email'] = public.M( + 'users').where("id=?", ('1',)).getField('email') + data = {} + data = web.ctx.session.config + data['webserver'] = web.ctx.session.config['webserver'] + # PHP版本 + phpVersions = ('52', '53', '54', '55', '56', + '70', '71', '72', '73', '74') + + data['php'] = [] + + for version in phpVersions: + tmp = {} + tmp['setup'] = os.path.exists( + self.setupPath + '/php/' + version + '/bin/php') + if tmp['setup']: + phpConfig = self.GetPHPConfig(version) + tmp['version'] = version + tmp['max'] = phpConfig['max'] + tmp['maxTime'] = phpConfig['maxTime'] + tmp['pathinfo'] = phpConfig['pathinfo'] + tmp['status'] = os.path.exists( + '/tmp/php-cgi-' + version + '.sock') + data['php'].append(tmp) + + tmp = {} + data['webserver'] = '' + serviceName = 'nginx' + tmp['setup'] = False + phpversion = "54" + phpport = '888' + pstatus = False + pauth = False + if os.path.exists(self.setupPath + '/nginx'): + data['webserver'] = 'nginx' + serviceName = 'nginx' + tmp['setup'] = os.path.exists(self.setupPath + '/nginx/sbin/nginx') + configFile = self.setupPath + '/nginx/conf/nginx.conf' + try: + if os.path.exists(configFile): + conf = public.readFile(configFile) + rep = "listen\s+([0-9]+)\s*;" + rtmp = re.search(rep, conf) + if rtmp: + phpport = rtmp.groups()[0] + + if conf.find('AUTH_START') != -1: + pauth = True + if conf.find(self.setupPath + '/stop') == -1: + pstatus = True + configFile = self.setupPath + '/nginx/conf/enable-php.conf' + conf = public.readFile(configFile) + rep = "php-cgi-([0-9]+)\.sock" + rtmp = re.search(rep, conf) + if rtmp: + phpversion = rtmp.groups()[0] + except: + pass + + elif os.path.exists(self.setupPath + '/apache'): + data['webserver'] = 'apache' + serviceName = 'httpd' + tmp['setup'] = os.path.exists(self.setupPath + '/apache/bin/httpd') + configFile = self.setupPath + '/apache/conf/extra/httpd-vhosts.conf' + try: + if os.path.exists(configFile): + conf = public.readFile(configFile) + rep = "php-cgi-([0-9]+)\.sock" + rtmp = re.search(rep, conf) + if rtmp: + phpversion = rtmp.groups()[0] + rep = "Listen\s+([0-9]+)\s*\n" + rtmp = re.search(rep, conf) + if rtmp: + phpport = rtmp.groups()[0] + if conf.find('AUTH_START') != -1: + pauth = True + if conf.find(self.setupPath + '/stop') == -1: + pstatus = True + except: + pass + + tmp['type'] = data['webserver'] + tmp['version'] = public.readFile( + self.setupPath + '/' + data['webserver'] + '/version.pl') + tmp['status'] = False + result = public.ExecShell('/etc/init.d/' + serviceName + ' status') + if result[0].find('running') != -1: + tmp['status'] = True + data['web'] = tmp + + tmp = {} + vfile = self.setupPath + '/phpmyadmin/version.pl' + tmp['version'] = public.readFile(vfile) + tmp['setup'] = os.path.exists(vfile) + tmp['status'] = pstatus + tmp['phpversion'] = phpversion + tmp['port'] = phpport + tmp['auth'] = pauth + data['phpmyadmin'] = tmp + + tmp = {} + tmp['setup'] = os.path.exists('/etc/init.d/tomcat') + tmp['status'] = False + if tmp['setup']: + if os.path.exists('/www/server/tomcat/logs/catalina-daemon.pid'): + tmp['status'] = self.getPid('jsvc') + if not tmp['status']: + tmp['status'] = self.getPid('java') + tmp['version'] = public.readFile(self.setupPath + '/tomcat/version.pl') + data['tomcat'] = tmp + + tmp = {} + tmp['setup'] = os.path.exists(self.setupPath + '/mysql/bin/mysql') + tmp['version'] = public.readFile(self.setupPath + '/mysql/version.pl') + tmp['status'] = os.path.exists('/tmp/mysql.sock') + data['mysql'] = tmp + + tmp = {} + tmp['setup'] = os.path.exists(self.setupPath + '/redis/runtest') + tmp['status'] = os.path.exists('/var/run/redis_6379.pid') + data['redis'] = tmp + + tmp = {} + tmp['setup'] = os.path.exists('/usr/local/memcached/bin/memcached') + tmp['status'] = os.path.exists('/var/run/memcached.pid') + data['memcached'] = tmp + + tmp = {} + tmp['setup'] = os.path.exists( + self.setupPath + '/pure-ftpd/bin/pure-pw') + tmp['version'] = public.readFile( + self.setupPath + '/pure-ftpd/version.pl') + tmp['status'] = os.path.exists('/var/run/pure-ftpd.pid') + data['pure-ftpd'] = tmp + data['panel'] = self.GetPanelInfo() + data['systemdate'] = public.ExecShell( + 'date +"%Y-%m-%d %H:%M:%S %Z %z"')[0].strip() + + return data + + # 名取PID + def getPid(self, pname): + try: + if not self.pids: + self.pids = psutil.pids() + for pid in self.pids: + if psutil.Process(pid).name() == pname: + return True + return False + except: + return False + + # 检测指定进程是否存活 + def checkProcess(self, pid): + try: + if not self.pids: + self.pids = psutil.pids() + if int(pid) in self.pids: + return True + return False + except: + return False + + def GetPanelInfo(self, get=None): + # 取面板配置 + address = public.GetLocalIp() + try: + try: + port = web.ctx.host.split(':')[1] + except: + port = public.readFile('data/port.pl') + except: + port = '8888' + domain = '' + if os.path.exists('data/domain.conf'): + domain = public.readFile('data/domain.conf') + + autoUpdate = '' + if os.path.exists('data/autoUpdate.pl'): + autoUpdate = 'checked' + limitip = '' + if os.path.exists('data/limitip.conf'): + limitip = public.readFile('data/limitip.conf') + + templates = [] + for template in os.listdir('templates/'): + if os.path.isdir('templates/' + template): + templates.append(template) + template = public.readFile('data/templates.pl') + + check502 = '' + if os.path.exists('data/502Task.pl'): + check502 = 'checked' + return {'port': port, 'address': address, 'domain': domain, 'auto': autoUpdate, '502': check502, 'limitip': limitip, 'templates': templates, 'template': template} + + def GetPHPConfig(self, version): + # 取PHP配置 + file = self.setupPath + "/php/" + version + "/etc/php.ini" + phpini = public.readFile(file) + file = self.setupPath + "/php/" + version + "/etc/php-fpm.conf" + phpfpm = public.readFile(file) + data = {} + try: + rep = "upload_max_filesize\s*=\s*([0-9]+)M" + tmp = re.search(rep, phpini).groups() + data['max'] = tmp[0] + except: + data['max'] = '50' + try: + rep = "request_terminate_timeout\s*=\s*([0-9]+)\n" + tmp = re.search(rep, phpfpm).groups() + data['maxTime'] = tmp[0] + except: + data['maxTime'] = 0 + + try: + rep = ur"\n;*\s*cgi\.fix_pathinfo\s*=\s*([0-9]+)\s*\n" + tmp = re.search(rep, phpini).groups() + + if tmp[0] == '1': + data['pathinfo'] = True + else: + data['pathinfo'] = False + except: + data['pathinfo'] = False + + return data + + def GetSystemTotal(self, get, interval=1): + # 取系统统计信息 + data = self.GetMemInfo() + cpu = self.GetCpuInfo(interval) + data['cpuNum'] = cpu[1] + data['cpuRealUsed'] = cpu[0] + data['time'] = self.GetBootTime() + data['system'] = self.GetSystemVersion() + data['isuser'] = public.M('users').where( + 'username=?', ('admin',)).count() + data['version'] = web.ctx.session.version + return data + + def GetLoadAverage(self, get): + c = os.getloadavg() + data = {} + data['one'] = float(c[0]) + data['five'] = float(c[1]) + data['fifteen'] = float(c[2]) + data['max'] = psutil.cpu_count() * 2 + data['limit'] = data['max'] + data['safe'] = data['max'] * 0.75 + return data + + def GetAllInfo(self, get): + data = {} + data['load_average'] = self.GetLoadAverage(get) + data['title'] = self.GetTitle() + data['network'] = self.GetNetWorkApi(get) + data['panel_status'] = not os.path.exists( + '/www/server/panel/data/close.pl') + import firewalls + ssh_info = firewalls.firewalls().GetSshInfo(None) + data['enable_ssh_status'] = ssh_info['status'] + data['disable_ping_status'] = not ssh_info['ping'] + data['time'] = self.GetBootTime() + #data['system'] = self.GetSystemVersion(); + #data['mem'] = self.GetMemInfo(); + data['version'] = web.ctx.session.version + return data + + def GetTitle(self): + titlePl = 'data/title.pl' + title = '宝塔Linux面板' + if os.path.exists(titlePl): + title = public.readFile(titlePl).strip() + return title + + def GetSystemVersion(self): + # 取操作系统版本 + import public + version = public.readFile('/etc/redhat-release') + if not version: + version = public.readFile( + '/etc/issue').strip().split("\n")[0].replace('\\n', '').replace('\l', '').strip() + else: + version = version.replace('release ', '').strip() + return version + + def GetBootTime(self): + # 取系统启动时间 + import public + import math + conf = public.readFile('/proc/uptime').split() + tStr = float(conf[0]) + min = tStr / 60 + hours = min / 60 + days = math.floor(hours / 24) + hours = math.floor(hours - (days * 24)) + min = math.floor(min - (days * 60 * 24) - (hours * 60)) + return public.getMsg('SYS_BOOT_TIME', (str(int(days)), str(int(hours)), str(int(min)))) + + def GetCpuInfo(self, interval=1): + # 取CPU信息 + cpuCount = psutil.cpu_count() + used = psutil.cpu_percent(interval=interval) + return used, cpuCount + + def GetMemInfo(self, get=None): + # 取内存信息 + mem = psutil.virtual_memory() + memInfo = {'memTotal': mem.total / 1024 / 1024, 'memFree': mem.free / 1024 / 1024, + 'memBuffers': mem.buffers / 1024 / 1024, 'memCached': mem.cached / 1024 / 1024} + memInfo['memRealUsed'] = memInfo['memTotal'] - \ + memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached'] + return memInfo + + def GetDiskInfo(self, get=None): + return self.GetDiskInfo2() + # 取磁盘分区信息 + diskIo = psutil.disk_partitions() + diskInfo = [] + + for disk in diskIo: + if disk[1] == '/mnt/cdrom': + continue + if disk[1] == '/boot': + continue + tmp = {} + tmp['path'] = disk[1] + tmp['size'] = psutil.disk_usage(disk[1]) + diskInfo.append(tmp) + return diskInfo + + def GetDiskInfo2(self): + # 取磁盘分区信息 + temp = public.ExecShell("df -h -P|grep '/'|grep -v tmpfs")[0] + tempInodes = public.ExecShell("df -i -P|grep '/'|grep -v tmpfs")[0] + temp1 = temp.split('\n') + tempInodes1 = tempInodes.split('\n') + diskInfo = [] + n = 0 + cuts = ['/mnt/cdrom', '/boot', '/boot/efi', '/dev', + '/dev/shm', '/run/lock', '/run', '/run/shm', '/run/user'] + for tmp in temp1: + n += 1 + inodes = tempInodes1[n - 1].split() + disk = tmp.split() + if len(disk) < 5: + continue + if disk[1].find('M') != -1: + continue + if disk[1].find('K') != -1: + continue + if len(disk[5].split('/')) > 4: + continue + if disk[5] in cuts: + continue + arr = {} + arr['path'] = disk[5] + tmp1 = [disk[1], disk[2], disk[3], disk[4]] + arr['size'] = tmp1 + arr['inodes'] = [inodes[1], inodes[2], inodes[3], inodes[4]] + if disk[5] == '/': + bootLog = '/tmp/panelBoot.pl' + if disk[2].find('M') != -1: + if os.path.exists(bootLog): + os.system('rm -f ' + bootLog) + else: + if not os.path.exists(bootLog): + os.system('sleep 1 && /etc/init.d/bt reload &') + diskInfo.append(arr) + return diskInfo + + # 清理系统垃圾 + def ClearSystem(self, get): + count = total = 0 + tmp_total, tmp_count = self.ClearMail() + count += tmp_count + total += tmp_total + tmp_total, tmp_count = self.ClearOther() + count += tmp_count + total += tmp_total + return count, total + + # 清理邮件日志 + def ClearMail(self): + rpath = '/var/spool' + total = count = 0 + import shutil + con = ['cron', 'anacron', 'mail'] + for d in os.listdir(rpath): + if d in con: + continue + dpath = rpath + '/' + d + time.sleep(0.2) + num = size = 0 + for n in os.listdir(dpath): + filename = dpath + '/' + n + fsize = os.path.getsize(filename) + size += fsize + if os.path.isdir(filename): + shutil.rmtree(filename) + else: + os.remove(filename) + print '\t\033[1;32m[OK]\033[0m' + num += 1 + total += size + count += num + return total, count + + # 清理其它 + def ClearOther(self): + clearPath = [ + {'path': '/www/server/panel', 'find': 'testDisk_'}, + {'path': '/www/wwwlogs', 'find': 'log'}, + {'path': '/tmp', 'find': 'panelBoot.pl'}, + {'path': '/www/server/panel/install', 'find': '.rpm'} + ] + + total = count = 0 + for c in clearPath: + for d in os.listdir(c['path']): + if d.find(c['find']) == -1: + continue + filename = c['path'] + '/' + d + fsize = os.path.getsize(filename) + total += fsize + if os.path.isdir(filename): + shutil.rmtree(filename) + else: + os.remove(filename) + count += 1 + public.serviceReload() + os.system('echo > /tmp/panelBoot.pl') + return total, count + + def GetNetWork(self, get=None): + # return self.GetNetWorkApi(get); + # 取网络流量信息 + try: + networkIo = psutil.net_io_counters()[:4] + if not hasattr(web.ctx.session, 'otime'): + web.ctx.session.up = networkIo[0] + web.ctx.session.down = networkIo[1] + web.ctx.session.otime = time.time() + + ntime = time.time() + networkInfo = {} + networkInfo['upTotal'] = networkIo[0] + networkInfo['downTotal'] = networkIo[1] + networkInfo['up'] = round(float( + networkIo[0] - web.ctx.session.up) / 1024 / (ntime - web.ctx.session.otime), 2) + networkInfo['down'] = round(float( + networkIo[1] - web.ctx.session.down) / 1024 / (ntime - web.ctx.session.otime), 2) + networkInfo['downPackets'] = networkIo[3] + networkInfo['upPackets'] = networkIo[2] + + web.ctx.session.up = networkIo[0] + web.ctx.session.down = networkIo[1] + web.ctx.session.otime = ntime + + networkInfo['cpu'] = self.GetCpuInfo() + networkInfo['load'] = self.GetLoadAverage(get) + return networkInfo + except: + return None + + def GetNetWorkApi(self, get=None): + # 取网络流量信息 + try: + tmpfile = 'data/network.temp' + networkIo = psutil.net_io_counters()[:4] + + if not os.path.exists(tmpfile): + public.writeFile(tmpfile, str( + networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time()))) + + lastValue = public.readFile(tmpfile).split('|') + + ntime = time.time() + networkInfo = {} + networkInfo['upTotal'] = networkIo[0] + networkInfo['downTotal'] = networkIo[1] + networkInfo['up'] = round( + float(networkIo[0] - int(lastValue[0])) / 1024 / (ntime - int(lastValue[2])), 2) + networkInfo['down'] = round( + float(networkIo[1] - int(lastValue[1])) / 1024 / (ntime - int(lastValue[2])), 2) + networkInfo['downPackets'] = networkIo[3] + networkInfo['upPackets'] = networkIo[2] + + public.writeFile(tmpfile, str( + networkIo[0]) + '|' + str(networkIo[1]) + '|' + str(int(time.time()))) + + #networkInfo['cpu'] = self.GetCpuInfo(0.1) + return networkInfo + except: + return None + + def GetNetWorkOld(self): + # 取网络流量信息 + import time + pnet = public.readFile('/proc/net/dev') + rep = '([^\s]+):[\s]{0,}(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)' + pnetall = re.findall(rep, pnet) + networkInfo = {} + networkInfo['upTotal'] = networkInfo['downTotal'] = networkInfo['up'] = networkInfo[ + 'down'] = networkInfo['downPackets'] = networkInfo['upPackets'] = 0 + for pnetInfo in pnetall: + if pnetInfo[0] == 'io': + continue + networkInfo['downTotal'] += int(pnetInfo[1]) + networkInfo['downPackets'] += int(pnetInfo[2]) + networkInfo['upTotal'] += int(pnetInfo[9]) + networkInfo['upPackets'] += int(pnetInfo[10]) + + if not hasattr(web.ctx.session, 'otime'): + web.ctx.session.up = networkInfo['upTotal'] + web.ctx.session.down = networkInfo['downTotal'] + web.ctx.session.otime = time.time() + ntime = time.time() + tmpDown = networkInfo['downTotal'] - web.ctx.session.down + tmpUp = networkInfo['upTotal'] - web.ctx.session.up + networkInfo['down'] = str( + round(float(tmpDown) / 1024 / (ntime - web.ctx.session.otime), 2)) + networkInfo['up'] = str( + round(float(tmpUp) / 1024 / (ntime - web.ctx.session.otime), 2)) + if networkInfo['down'] < 0: + networkInfo['down'] = 0 + if networkInfo['up'] < 0: + networkInfo['up'] = 0 + + web.ctx.session.up = networkInfo['upTotal'] + web.ctx.session.down = networkInfo['downTotal'] + web.ctx.session.otime = ntime + networkInfo['cpu'] = self.GetCpuInfo() + return networkInfo + + def ServiceAdmin(self, get=None): + # 服务管理 + + if get.name == 'mysqld': + public.CheckMyCnf() + + if get.name == 'phpmyadmin': + import ajax + get.status = 'True' + ajax.ajax().setPHPMyAdmin(get) + return public.returnMsg(True, 'SYS_EXEC_SUCCESS') + + # 检查httpd配置文件 + if get.name == 'apache' or get.name == 'httpd': + get.name = 'httpd' + if not os.path.exists(self.setupPath + '/apache/bin/apachectl'): + return public.returnMsg(True, 'SYS_NOT_INSTALL_APACHE') + vhostPath = self.setupPath + '/panel/vhost/apache' + if not os.path.exists(vhostPath): + public.ExecShell('mkdir ' + vhostPath) + public.ExecShell('/etc/init.d/httpd start') + + if get.type == 'start': + public.ExecShell('/etc/init.d/httpd stop') + public.ExecShell('pkill -9 httpd') + + result = public.ExecShell( + 'ulimit -n 10240 && ' + self.setupPath + '/apache/bin/apachectl -t') + if result[1].find('Syntax OK') == -1: + public.WriteLog("TYPE_SOFT", 'SYS_EXEC_ERR', (str(result),)) + return public.returnMsg(False, 'SYS_CONF_APACHE_ERR', (result[1].replace("\n", '
'),)) + + if get.type == 'restart': + public.ExecShell('pkill -9 httpd') + public.ExecShell('/etc/init.d/httpd start') + + # 检查nginx配置文件 + elif get.name == 'nginx': + vhostPath = self.setupPath + '/panel/vhost/rewrite' + if not os.path.exists(vhostPath): + public.ExecShell('mkdir ' + vhostPath) + vhostPath = self.setupPath + '/panel/vhost/nginx' + if not os.path.exists(vhostPath): + public.ExecShell('mkdir ' + vhostPath) + public.ExecShell('/etc/init.d/nginx start') + + result = public.ExecShell( + 'ulimit -n 10240 && nginx -t -c ' + self.setupPath + '/nginx/conf/nginx.conf') + if result[1].find('perserver') != -1: + limit = self.setupPath + '/nginx/conf/nginx.conf' + nginxConf = public.readFile(limit) + limitConf = "limit_conn_zone $binary_remote_addr zone=perip:10m;\n\t\tlimit_conn_zone $server_name zone=perserver:10m;" + nginxConf = nginxConf.replace( + "#limit_conn_zone $binary_remote_addr zone=perip:10m;", limitConf) + public.writeFile(limit, nginxConf) + public.ExecShell('/etc/init.d/nginx start') + return public.returnMsg(True, 'SYS_CONF_NGINX_REP') + + if result[1].find('proxy') != -1: + import panelSite + panelSite.panelSite().CheckProxy(get) + public.ExecShell('/etc/init.d/nginx start') + return public.returnMsg(True, 'SYS_CONF_NGINX_REP') + + # return result + if result[1].find('successful') == -1: + public.WriteLog("TYPE_SOFT", 'SYS_EXEC_ERR', (str(result),)) + return public.returnMsg(False, 'SYS_CONF_NGINX_ERR', (result[1].replace("\n", '
'),)) + + # 执行 + execStr = "/etc/init.d/" + get.name + " " + get.type + if execStr == '/etc/init.d/pure-ftpd reload': + execStr = self.setupPath + '/pure-ftpd/bin/pure-pw mkdb ' + \ + self.setupPath + '/pure-ftpd/etc/pureftpd.pdb' + if execStr == '/etc/init.d/pure-ftpd start': + os.system('pkill -9 pure-ftpd') + if execStr == '/etc/init.d/tomcat reload': + execStr = '/etc/init.d/tomcat stop && /etc/init.d/tomcat start' + if execStr == '/etc/init.d/tomcat restart': + execStr = '/etc/init.d/tomcat stop && /etc/init.d/tomcat start' + + if get.name != 'mysqld': + result = public.ExecShell(execStr) + else: + os.system(execStr) + result = [] + result.append('') + result.append('') + + if result[1].find('nginx.pid') != -1: + public.ExecShell('pkill -9 nginx && sleep 1') + public.ExecShell('/etc/init.d/nginx start') + if get.type != 'test': + public.WriteLog("TYPE_SOFT", 'SYS_EXEC_SUCCESS', (execStr,)) + + if len(result[1]) > 1 and get.name != 'pure-ftpd': + return public.returnMsg(False, '

警告消息:

' + result[1].replace('\n', '
')) + return public.returnMsg(True, 'SYS_EXEC_SUCCESS') + + def RestartServer(self, get): + if not public.IsRestart(): + return public.returnMsg(False, 'EXEC_ERR_TASK') + public.ExecShell("sync && /etc/init.d/bt stop && init 6 &") + return public.returnMsg(True, 'SYS_REBOOT') + + # 释放内存 + def ReMemory(self, get): + os.system('sync') + scriptFile = 'script/rememory.sh' + if not os.path.exists(scriptFile): + public.downloadFile(web.ctx.session.home + + '/script/rememory.sh', scriptFile) + public.ExecShell("/bin/bash " + self.setupPath + + '/panel/' + scriptFile) + return self.GetMemInfo() + + # 重启面板 + def ReWeb(self, get): + # if not public.IsRestart(): return + # public.returnMsg(False,'EXEC_ERR_TASK'); + public.ExecShell('/etc/init.d/bt restart &') + return True + + # 修复面板 + def RepPanel(self, get): + vp = '' + if public.readFile('/www/server/panel/class/common.py').find('checkSafe') != -1: + vp = '_pro' + public.ExecShell("wget -O update.sh " + public.get_url() + + "/install/update" + vp + ".sh && bash update.sh") + if hasattr(web.ctx.session, 'getCloudPlugin'): + del(web.ctx.session['getCloudPlugin']) + return True + + # 升级到专业版 + def UpdatePro(self, get): + public.ExecShell("wget -O update.sh " + public.get_url() + + "/install/update_pro.sh && bash update.sh pro") + if hasattr(web.ctx.session, 'getCloudPlugin'): + del(web.ctx.session['getCloudPlugin']) + return True diff --git a/class/core/vilidate.py b/class/core/vilidate.py new file mode 100755 index 000000000..adb2141c6 --- /dev/null +++ b/class/core/vilidate.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python +# coding: utf-8 + + +import random +import math +from PIL import Image, ImageDraw, ImageFont, ImageFilter + + +class vieCode: + __fontSize = 20 # 字体大小 + __width = 120 # 画布宽度 + __heigth = 45 # 画布高度 + __length = 4 # 验证码长度 + __draw = None # 画布 + __img = None # 图片资源 + __code = None # 验证码字符 + __str = None # 自定义验证码字符集 + __inCurve = True # 是否画干扰线 + __inNoise = True # 是否画干扰点 + __type = 2 # 验证码类型 1、纯字母 2、数字字母混合 + __fontPatn = 'class/fonts/2.ttf' # 字体 + + def GetCodeImage(self, size=80, length=4): + '''获取验证码图片 + @param int size 验证码大小 + @param int length 验证码长度 + ''' + # 准备基础数据 + self.__length = length + self.__fontSize = size + self.__width = self.__fontSize * self.__length + self.__heigth = int(self.__fontSize * 1.5) + + # 生成验证码图片 + self.__createCode() + self.__createImage() + self.__createNoise() + self.__printString() + self.__cerateFilter() + + return self.__img, self.__code + + def __cerateFilter(self): + '''模糊处理''' + self.__img = self.__img.filter(ImageFilter.BLUR) + filter = ImageFilter.ModeFilter(8) + self.__img = self.__img.filter(filter) + + def __createCode(self): + '''创建验证码字符''' + # 是否自定义字符集合 + if not self.__str: + # 源文本 + number = "3456789" + srcLetter = "qwertyuipasdfghjkzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM" + srcUpper = srcLetter.upper() + if self.__type == 1: + self.__str = number + else: + self.__str = srcLetter + srcUpper + number + + # 构造验证码 + self.__code = random.sample(self.__str, self.__length) + + def __createImage(self): + '''创建画布''' + bgColor = (random.randint(200, 255), random.randint( + 200, 255), random.randint(200, 255)) + self.__img = Image.new('RGB', (self.__width, self.__heigth), bgColor) + self.__draw = ImageDraw.Draw(self.__img) + + def __createNoise(self): + '''画干扰点''' + if not self.__inNoise: + return + font = ImageFont.truetype(self.__fontPatn, int(self.__fontSize / 1.5)) + for i in xrange(5): + # 杂点颜色 + noiseColor = (random.randint(150, 200), random.randint( + 150, 200), random.randint(150, 200)) + putStr = random.sample(self.__str, 2) + for j in range(2): + # 绘杂点 + size = (random.randint(-10, self.__width), + random.randint(-10, self.__heigth)) + self.__draw.text(size, putStr[j], font=font, fill=noiseColor) + pass + + def __createCurve(self): + '''画干扰线''' + if not self.__inCurve: + return + x = y = 0 + + # 计算曲线系数 + a = random.uniform(1, self.__heigth / 2) + b = random.uniform(-self.__width / 4, self.__heigth / 4) + f = random.uniform(-self.__heigth / 4, self.__heigth / 4) + t = random.uniform(self.__heigth, self.__width * 2) + xend = random.randint(self.__width / 2, self.__width * 2) + w = (2 * math.pi) / t + + # 画曲线 + color = (random.randint(30, 150), random.randint( + 30, 150), random.randint(30, 150)) + for x in xrange(xend): + if w != 0: + for k in xrange(int(self.__heigth / 10)): + y = a * math.sin(w * x + f) + b + self.__heigth / 2 + i = int(self.__fontSize / 5) + while i > 0: + px = x + i + py = y + i + k + self.__draw.point((px, py), color) + i -= i + + def __printString(self): + '''打印验证码字符串''' + font = ImageFont.truetype(self.__fontPatn, self.__fontSize) + x = 0 + # 打印字符到画板 + for i in xrange(self.__length): + # 设置字体随机颜色 + color = (random.randint(30, 150), random.randint( + 30, 150), random.randint(30, 150)) + # 计算座标 + x = random.uniform(self.__fontSize * i * 0.95, + self.__fontSize * i * 1.1) + y = self.__fontSize * random.uniform(0.3, 0.5) + # 打印字符 + self.__draw.text((x, y), self.__code[i], font=font, fill=color) diff --git a/static/js/index.html b/class/os/README.md old mode 100755 new mode 100644 similarity index 100% rename from static/js/index.html rename to class/os/README.md diff --git a/class/os/win32/README.md b/class/os/win32/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/class/plugin/README.md b/class/plugin/README.md new file mode 100644 index 000000000..e69de29bb