hch
2018-09-21 904df7e20029fa64f9382bc32b52f12f46e37e5d
1 礼包卡以权限分应用
2个文件已修改
9个文件已添加
5894 ■■■■■ 已修改文件
Tool/WebCenter/Coupon/config.ini 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/Coupon/webapp.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/CouponDB.py 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/bottle.py 4403 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/CommFunc.py 371 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/DBController.py 516 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/ReadConfig.py 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/TimeRotatingPathFileHandler.py 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/__init__.py 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/lib/mylog.py 158 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/CouponCode/main.py 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tool/WebCenter/Coupon/config.ini
@@ -10,8 +10,10 @@
IsDebug = False
;下载卡批次地址,中心地址和端口
exporturl = http://mobiletest.173on.com
CenterPort = 53003
exporturl = http://mobiletest.173on.com:53003
CenterPort = 53002
CodePort = 53003
;发放礼包卡 通过邮件 失败通知通过 GMT_MediaCard,配置为同一个key
PushPort = 30001
Tool/WebCenter/Coupon/webapp.py
@@ -45,7 +45,7 @@
# 应用端口
CenterPort = ConfigIO.GetValue("Coupon", "CenterPort")
#mobiletest.173on.com:55000
Def_ExportUrl = ConfigIO.GetValue("Coupon", "exporturl") + ":" + CenterPort + "/Coupon/CouponLoad.php?couponid=%s&channel=%s"
Def_ExportUrl = ConfigIO.GetValue("Coupon", "exporturl") + "/Coupon/CouponLoad.php?couponid=%s&channel=%s"
# GM端口
PushPort = ConfigIO.GetValue("Coupon", "PushPort")
Tool/WebCenter/CouponCode/CouponDB.py
New file
@@ -0,0 +1,169 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package E:/GameSVN/TeamTool/PythonScribe/PyModule/Coupon/CouponDB.py
# @todo:
#
# @author: Alee
# @date 2017-6-2 下午05:21:48
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
#-------------------------------------------------------------------------------
#检查并更新索引
#-------------------------------------------------------------------------------
from lib import ReadConfig
from lib import DBController
from lib import mylog
import os
g_dbController = None
CouponBatchColName = "tagCouponBatch"
CouponCodeColName = "tagCouponCode"
ModuleName = "CouponDB"
Def_ConfigPath = os.getcwd() + "\\..\\Coupon\\config.ini"
def InitDB():
    global g_dbController
    if not g_dbController:
        IP = ReadConfig.ReadConfig(Def_ConfigPath).GetValue("MongoDB", "IP")
        Port = ReadConfig.ReadConfig(Def_ConfigPath).GetInt("MongoDB", "Port")
        User = ReadConfig.ReadConfig(Def_ConfigPath).GetValue("MongoDB", "User")
        Pwd = ReadConfig.ReadConfig(Def_ConfigPath).GetValue("MongoDB", "Pwd")
        DBName = ReadConfig.ReadConfig(Def_ConfigPath).GetValue("MongoDB", "DBName")
        g_dbController = DBController.DBController(IP, Port, DBName, User, Pwd, None)
        if g_dbController.connected:
            #只在链接DB检查一次
            result = CheckAndUpdateIndexOnDb(g_dbController.db)
            if not result:
                mylog.debug('索引有问题')
                return False
        mylog.debug('获取新的数据库链接')
    if not g_dbController.connected:
        mylog.debug('无法链接数据库')
        return False
    return True
def GetDBEventCon():
    global g_dbController
    if not InitDB():
        return None
    return g_dbController
def ReadIndexInfo():
    indexInfoDict = {
    CouponBatchColName:
    {
        'CouponBatch_1':
        {
            'unique':True,
            'key':[('couponid', 1)]    #索引的字典和递增(1)或递减(-1)
         }
     },
    }
    return indexInfoDict
def CompareIndex(curIndexDict, expectIndexDict):
    #比较unique
    curUnique = curIndexDict.get('unique', None)
    expectUnique = expectIndexDict.get('unique', None)
    if curUnique is None:
        if expectUnique is None:
            pass
        elif expectUnique:
#            print '#debug 1'
            return False
        else:
            pass
    else:
        if expectUnique is None:
            if (not curUnique):
                return True
#            print '#debug 2'
            return False
        if curUnique and (not expectUnique):
#            print '#debug 3'
            return False
        if (not curUnique) and expectUnique:
#            print '#debug 4'
            return False
    #比较keylist
    curKeyList = curIndexDict.get('key', None)
    expectKeyList = expectIndexDict.get('key', None)
    if curKeyList is None:
        if expectKeyList is None:
            pass
        else:
#            print '#debug 5'
            return False
    else:
        if expectKeyList is None:
#            print '#debug 6'
            return False
        else:
            for pair in curKeyList:
                if pair not in expectKeyList:
#                    print '#debug 7'
                    return False
            for pair in expectKeyList:
                if pair not in curKeyList:
#                    print '#debug 8'
                    return False
    return True
def CheckIndexes(db, colName, expectIndexInfo):
    col = db[colName]
    '''检查表中是否有多余的索引'''
    indexDict = col.index_information()
    for k, v in indexDict.items():
        if k == '_id_':
            continue
        if k not in expectIndexInfo:
            return False
        if not CompareIndex(v, expectIndexInfo[k]):
            return False
    return True
def AddIndexes(db, colName, expectIndexes):
    '''添加索引'''
    col = db[colName]
    '''给表添加索引'''
    curIndexesDict = col.index_information()
    for k, v in expectIndexes.items():
        if k not in curIndexesDict:
            expectIndexInfo = expectIndexes[k]
            isUnique = expectIndexInfo.get('unique', False)
            try:
                col.create_index(expectIndexInfo['key'], name = k, unique = isUnique)
            except Exception, e:
                return False
    return True
def CheckAndUpdateIndexOnDb(db):
    '''对于索引文件中的每个表,数据库中该表有的索引信息,索引文件中必须有并且匹配unique和(key, direction)list'''
    indexInfoDict = ReadIndexInfo()
    for k, v in indexInfoDict.items():
        colName = k
        colIndexDict = v
        if not CheckIndexes(db, colName, colIndexDict):
            return False
        if not AddIndexes(db, colName, colIndexDict):
            return False
    return True
Tool/WebCenter/CouponCode/bottle.py
New file
Diff too large
Tool/WebCenter/CouponCode/lib/CommFunc.py
New file
@@ -0,0 +1,371 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo:
#
# @author: Alee
# @date 2018-7-18 上午11:22:43
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
import struct
import string
import datetime
import os
import binascii
import socket
import sys
#python的读取/写入库
#要进行反转高低位的话,可使用!符号,如struct.unpack_from('!B', buf, pos)
#------------------------读取
def ReadBYTE(buf, pos):
    curValue = struct.unpack_from('b', buf, pos)
    pos += 1
    return curValue[0], pos
def ReadWORD(buf, pos):
    curValue = struct.unpack_from('H', buf, pos)
    pos += 2
    return curValue[0], pos
def ReadDWORD(buf, pos):
    curValue = struct.unpack_from('i', buf, pos)
    pos += 4
    return curValue[0], pos
def ReadFloat(buf, pos):
    curValue = struct.unpack_from('f', buf, pos)
    pos += 4
    return curValue[0], pos
def ReadDouble(buf, pos):
    curValue = struct.unpack_from('d', buf, pos)
    pos += 8
    return curValue[0], pos
def ReadString(buf, pos, _len):
    curValue = struct.unpack_from('%ds'%_len, buf, pos)
    pos += _len
    return curValue[0], pos
#----------------------写入
def WriteBYTE(buf, value):
    buf += struct.pack('b', value)
    return buf
def WriteWORD(buf, value):
    buf += struct.pack('H', value)
    return buf
def WriteDWORD(buf, value):
    buf += struct.pack('i', value)
    return buf
def WriteFloat(buf, value):
    buf += struct.pack('f', value)
    return buf
def WriteDouble(buf, value):
    buf += struct.pack('d', value)
    return buf
def WriteString(buf, len, value):
    buf += struct.pack('%ds'%len, value)
    return buf
#获得当前系统时间
def GetCurrentDataTimeStr():
    curTime = datetime.datetime.today()
    curTimeStr = str(curTime)
    curTimeStr = curTimeStr.split(".")[0]
    return curTimeStr
#获得系统时间(参数 -> 时间列表)
def GetDateTimeByStr(timeStr):
    timeStr = timeStr.split(".")[0]
    return  datetime.datetime.strptime(timeStr, "%Y-%m-%d %H:%M:%S")
#字符串转换为整型, 如果不能转换, 返回默认值
def ToIntDef(input, defValue = 0):
    try:
        result = int(input)
        return result
    except ValueError:
        return defValue
#字符串转换为整型, 如果不能转换, 返回False,原值
def StrToInt(input):
    try:
        result = int(input)
        return True,result
    except ValueError:
        return False,input
#16进制颜色转换
#"#FFFFFF"--"255,255,255"
def HcToSc(h):
    h="0x"+h[1:7]
    red=string.atoi(h[:2]+h[2:4], base=16)
    green=string.atoi(h[:2]+h[4:6], base=16)
    blue=string.atoi(h[:2]+h[6:8], base=16)
    cStr=str(red)+","+str(green)+","+str(blue)
    return cStr
#"255,255,255"--"#FFFFFF"
def ScToHc(s):
    red=hex(string.atoi(s.split(",")[0]))[2:]
    green=hex(string.atoi(s.split(",")[1]))[2:]
    blue=hex(string.atoi(s.split(",")[2]))[2:]
    hStr="#"+str(red+green+blue)
    return hStr
#16进制转换
#"0xFFFFFF"--"255,255,255"
def HdToSd(h):
    red=string.atoi(h[0:2]+h[2:4], base=16)
    green=string.atoi(h[0:2]+h[4:6], base=16)
    blue=string.atoi(h[0:2]+h[6:8], base=16)
    cStr=str(red)+","+str(green)+","+str(blue)
    return cStr
#"255,255,255"--"0xFFFFFF"
def SdToHd(s):
    red=hex(string.atoi(s.split(",")[0]))[2:]
    green=hex(string.atoi(s.split(",")[1]))[2:]
    blue=hex(string.atoi(s.split(",")[2]))[2:]
    hStr="0x"+str(red+green+blue)
    return hStr
def GetPercent(value1, value2):
    if value2 == 0:
        return 0
    return int(float(value1) / float(value2) * 100)
def OpenFileForWrite(fileName):
    dirName = os.path.dirname(fileName)
    if not os.path.isdir(dirName):
        os.makedirs(dirName)
    if os.path.isfile(fileName):
        return open(fileName, 'w')
    return  open(fileName, 'a')
#函数调用
def ParseNameGetObj(curCallObj, callName):
    callList = callName.split(".")
    if len(callList) <= 1:
        return None
    for curCallName in callList:
        if hasattr(curCallObj, curCallName) != True:
            #无此属性
            return None
        curCallObj = getattr(curCallObj, curCallName)
    return curCallObj
#获得执行函数
def GetExecFunc(curCallObj, callName):
    curCallObj = ParseNameGetObj(curCallObj, callName)
    if curCallObj == None:
        return None
    if callable(curCallObj) != True:
        #不可调用
        return None
    return curCallObj
#字符串异或处理
def str_xor(astring, xornum=150):
    a=[]
    for x in astring:
        a.append(chr(ord(x)^xornum))
    return ''.join(a)
#解析封包
def ParseBuff(buff):
    result=''
    for i in  range(len(buff)):
        if i%2==0 and i!=0:
            result=result + ' ' + buff[i]
        else:
            result = result + buff[i]
    return result
def b2a_hex(data):
    return ParseBuff(binascii.b2a_hex(data))
def GetHostName():
    return socket.gethostname()
def GetHostIP():
    return socket.gethostbyname(GetHostName())
def compact_traceback():
    t, v, tb = sys.exc_info()
    tbinfo = []
    if not tb: # Must have a traceback
        raise AssertionError("traceback does not exist")
    while tb:
        tbinfo.append((
            tb.tb_frame.f_code.co_filename,
            tb.tb_frame.f_code.co_name,
            str(tb.tb_lineno)
            ))
        tb = tb.tb_next
    # just to be safe
    del tb
    info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo])
    return t, v, info
import base64
import urllib
import urllib2
#---------------------------------------------------------------------
## 加密算法需要的定义
Def_NumEncodeCnt = 3  # 加密的次数
Def_NumXorKey = 151  # 异或的key
## 公司内部解密算法
def GetDecodePwd(strPwd):
    strResult = strPwd
    for index in xrange(Def_NumEncodeCnt):
        strResult = base64.b64decode(strResult)
    tempResult = ""
    for index in xrange(len(strResult)):
        tempResult += chr(ord(strResult[index])^Def_NumXorKey)
    return tempResult
## 公司内部加密算法
def GetEncodePwd(strPwd):
    strResult = ""
    for index in xrange(len(strPwd)):
        strResult += chr(ord(strPwd[index])^Def_NumXorKey)
    for index in xrange(Def_NumEncodeCnt):
        strResult = base64.b64encode(strResult)
    return strResult
#---------------------------------------------------------------------
## UTF-8 <==> GBK
def gbk2utf8(content):
    if type( content ) is not str:
        content = str(content)
    try:
        return content.decode('gbk').encode('utf-8')
    except:
        return content
def utf82gbk(content):
    if type( content ) is not str:
        content = str(content)
    try:
        return content.decode('utf-8').encode('gbk')
    except:
        return content
## GET请求
def DoGet(url, data=None, headers={}):
    if data:
        request = urllib2.Request(url + "?" + urllib.urlencode(data), None, headers)
    else:
        request = urllib2.Request(url, None, headers)
    response = urllib2.urlopen(request, timeout=5)
    content = response.read()
    response.close()
    return content
## POST请求
def DoPost(url, data, headers={}):
    try:
        data = urllib.urlencode(data)
    except:
        pass
    request = urllib2.Request(url, data, headers)
    try:
        response = urllib2.urlopen(request, timeout=30)
        content = response.read()
        response.close()
    except:
        content = "error timeout"
    return content
FileTypeDict = {
'.txt':'text/html',
'.html':'text/html',
'.htm':'text/html',
'.bmp':'application/x-bmp',
'.ico':'image/x-icon',
'.jpe':'image/jpeg',
'.jpeg':'image/jpeg',
'.jpg':'application/x-jpg',
'.png':'application/x-png',
'.gif':'image/gif',
'.bin':'application/octet-stream',
'.*':'application/octet-stream'
}
def GetHttpContentType(strType):
    return FileTypeDict[strType]
## 编码
#  @param srcEncoding 编码格式
#  @param input 字符串
#  @return None
def EncodingToUnicode(srcEncoding, msg):
    try:
        result = unicode(msg, srcEncoding)    #translate to utf-8
    except:
        return "EncodingToUnicode error"
    return result
## 编码
#  @param srcEncoding 编码格式
#  @param input 字符串
#  @return None
def UnicodeToEncoding(dstEncoding, msg):
    try:
        result = msg.encode(dstEncoding)
    except:
        return "UnicodeToEncoding error"
    return result
Tool/WebCenter/CouponCode/lib/DBController.py
New file
@@ -0,0 +1,516 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
#
import pymongo
from pymongo.son_manipulator import SONManipulator
import base64
from functools import wraps
from time import (sleep)
import CommFunc
#模拟SQL的IDENT
def seq(db, collectionName, fieldName, feed, increment):
    try:
        result = 0
        collection = db['%s_seq'%collectionName]
        resultObj = collection.find_and_modify(query={'_id':fieldName}, update={'$inc':{'seq':increment}}, new=True)
        if resultObj:
            result = resultObj['seq']
        else:
            resultObj = collection.find_and_modify(query={'_id':fieldName}, update={'$set':{'seq':feed}}, new=True,
                                                   upsert=True)
            if resultObj:
                result = resultObj['seq']
            else:
                return False, None
    except Exception, e:
        return False, None
    return True, result
class ObjectIdRemover(SONManipulator):
    def transform_outgoing(self, son, collection):
        if '_id' in son:
            del son['_id']
        return son
class EncodeStringManipulator(SONManipulator):
    def __init__(self, encoding):
        self.encoding = encoding
    def transform_incoming(self, son, collection):
        def transform_value(value):
            if isinstance(value, dict):
                return transform_dict(value)
            elif isinstance(value, list):
                return [transform_value(v) for v in value]
            elif isinstance(value, basestring):
                result, value = CommFunc.EncodingToUnicode(self.encoding, value)
                return value
            return value
        def transform_dict(object):
            for (key, value) in object.items():
                object[key] = transform_value(value)
            return object
        def transform_list(container):
            for item in container:
                transform_dict(item)
            return container
        if isinstance(son, dict):
            return transform_dict(son)
        elif isinstance(son, list):
            return transform_list(son)
        return son
    def transform_outgoing(self, son, collection):
        def transform_value(value):
            if isinstance(value, dict):
                return transform_dict(value)
            elif isinstance(value, list):
                return [transform_value(v) for v in value]
            elif isinstance(value, basestring):
                result, value =CommFunc.UnicodeToEncoding(self.encoding, value)
                return value
            return value
        def transform_dict(object):
            for (key, value) in object.items():
                object[key] = transform_value(value)
            return object
        def transform_list(container):
            for item in container:
                transform_dict(item)
            return container
        if isinstance(son, dict):
            return transform_dict(son)
        elif isinstance(son, list):
            return transform_list(son)
        return son
class Base64StringManipulator(SONManipulator):
    def transform_incoming(self, son, collection):
        def transform_value(value):
            if isinstance(value, dict):
                return transform_dict(value)
            elif isinstance(value, list):
                return [transform_value(v) for v in value]
            elif isinstance(value, basestring):
                return base64.b64encode(value)
            return value
        def transform_dict(object):
            for (key, value) in object.items():
                object[key] = transform_value(value)
            return object
        def transform_list(container):
            for item in container:
                transform_dict(item)
            return container
        if isinstance(son, dict):
            return transform_dict(son)
        elif isinstance(son, list):
            return transform_list(son)
        return son
    def transform_outgoing(self, son, collection):
        def transform_value(value):
            if isinstance(value, dict):
                return transform_dict(value)
            elif isinstance(value, list):
                return [transform_value(v) for v in value]
            elif isinstance(value, basestring):
                return base64.b64decode(value)
            return value
        def transform_dict(object):
            for (key, value) in object.items():
                object[key] = transform_value(value)
            return object
        def transform_list(container):
            for item in container:
                transform_dict(item)
            return container
        if isinstance(son, dict):
            return transform_dict(son)
        elif isinstance(son, list):
            return transform_list(son)
        return son
#用于修饰DBController的数据库操作函数
#断线自动重试
def reconnect_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwds):
        MAX_RECONNECT = 10
        RECONNECT_INTERVAL = 0.1
        failCnt = 0
        while True:
            try:
                #去掉self
                return func(*args, **kwds)
            except pymongo.errors.AutoReconnect, e:
                failCnt += 1
                sleep(RECONNECT_INTERVAL)
                if failCnt > MAX_RECONNECT:
                    raise e
    return wrapper
class DBController:
    def __init__(self, host, port, dbName, user, pwd, encoding):
        self.host = host
        self.port = port
        self.dbName = dbName
        self.user = user
        self.pwd = pwd
        self.connected = False
        self.con = None
        self.db = None
        self.lastError = None
        self.translator = None
        #===========================================================================================
        # if encoding == 'base64':
        #    self.translator = Base64StringManipulator()
        # else:
        #    self.translator = EncodeStringManipulator(encoding)
        #===========================================================================================
        self.initialize()
    def initialize(self):
        if not self.connected:
            if not self.doConnect(self.host, self.port):
                return False
            authResult = self.doAuthentication(self.dbName, self.user, self.pwd)
            if self.db:
                self.db.add_son_manipulator(ObjectIdRemover())
            return authResult
        return True
    def doConnect(self, ip, port):
        try:
            self.con = pymongo.Connection(ip, port)
        except TypeError, typeError:
            raise
        except pymongo.errors.ConnectionFailure, failure:
            self.lastError = failure
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        self.connected = True
        return True
    def doAuthentication(self, dbName, user, pwd):
        if not self.connected or not self.con:
            self.lastError = 'Not connected yet!'
            return False
        self.db = self.con[dbName]
        authDB = self.con['admin']
        try:
            return authDB.authenticate(user, pwd)
#            return self.db.authenticate(user, pwd)
        except TypeError, typeError:
            self.lastError = typeError
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
    def find_one(self, colName, spec, filter = None):
        result, recList = self.find(colName, spec, filter, 1)
        if not result:
            return False, None
        for rec in recList:
            return True, rec
        return True, None
    @reconnect_decorator
    def find(self, colName, spec = None, filter = None, maxCnt = 0, sortBy = None):
        if not self.connected:
            if not self.initialize():
                return False, []
        result = False
        resultDictList = []
        col = self.db[colName]
        if self.translator:
            spec = self.translator.transform_incoming(spec, None)
        try:
            resultCollection = col.find(spec, filter, limit = maxCnt, sort = sortBy)
            if self.translator:
                resultDictList = self.translator.transform_outgoing(list(resultCollection), None)
            else:
                resultDictList = list(resultCollection)
            return True, resultDictList
        except TypeError, typeError:
            self.lastError = typeError
            return result, resultDictList
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return result, resultDictList
        except Exception, e:
            self.lastError = e
            return result, resultDictList
        except:
            self.lastError = 'Unknown exception occur!'
            return result, resultDictList
    @reconnect_decorator
    def insert(self, colName, doc_or_docs, isSafe = True):
        if not self.connected:
            if not self.initialize():
                return False
        col = self.db[colName]
        if self.translator:
            doc_or_docs = self.translator.transform_incoming(doc_or_docs, None)
        try:
            col.insert(doc_or_docs, safe = isSafe)
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        return True
    @reconnect_decorator
    def update(self, colName, spec, doc, isUpsert = False, isSafe = True, isMulti = False):
        if not self.connected:
            if not self.initialize():
                return False
        col = self.db[colName]
        #需要先对doc进行处理,但由不能开启collection.update的manipulate,因为那会应用所有处理
        if self.translator:
            spec = self.translator.transform_incoming(spec, None)
            doc = self.translator.transform_incoming(doc, None)
        try:
            col.update(spec, doc, upsert = isUpsert, safe = isSafe, multi = isMulti)
        except TypeError, typeError:
            self.lastError = typeError
            return False
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        return True
    @reconnect_decorator
    def save(self, colName, doc, isSafe = True):
        if not self.connected:
            if not self.initialize():
                return False
        col = self.db[colName]
        if self.translator:
            doc = self.translator.transform_incoming(doc, None)
        try:
            col.save(doc, safe = isSafe)
        except TypeError, typeError:
            self.lastError = typeError
            return False
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        return True
    @reconnect_decorator
    def remove(self, colName, spec = None, isSafe = True):
        if not self.connected:
            if not self.initialize():
                return False
        col = self.db[colName]
        if self.translator:
            spec = self.translator.transform_incoming(spec, None)
        try:
            col.remove(spec, safe = isSafe)
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        return True
    @reconnect_decorator
    def drop(self, colName):
        if not self.connected:
            if not self.initialize():
                return False
        col = self.db[colName]
        try:
            col.drop()
        except TypeError, typeError:
            self.lastError = typeError
            return False
        except Exception, e:
            self.lastError = e
            return False
        except:
            self.lastError = 'Unknown exception occur!'
            return False
        return True
    @reconnect_decorator
    def count(self, colName):
        if not self.connected:
            if not self.initialize():
                return False, 0
        col = self.db[colName]
        try:
            cnt = col.count()
        except pymongo.errors.OperationFailure, err:
            self.lastError = err
            return False, 0
        except Exception, e:
            self.lastError = e
            return False, 0
        except:
            self.lastError = 'Unknown exception occur!'
            return False, 0
        return True, cnt
def test_seq():
    con = pymongo.Connection()
    db = con.admin
    if not db.authenticate('sa', 'sa'):
        print 'auth failed!'
        return
    colName = 'tagSeqTest'
    fieldName = 'ID'
    db = con['test']
    db.drop_collection(colName)
    db.drop_collection('%s_seq'%colName)
    result, ID = seq(db, colName, fieldName, 1, 1)
    assert (result and ID == 1)
    result, ID = seq(db, colName, fieldName, 1, 1)
    assert (result and ID == 2)
def test_StringManipulator():
    translator = Base64StringManipulator()
    son = []
    result = translator.transform_incoming(son, None)
    assert (son == result)
    result = translator.transform_outgoing(son, None)
    assert (son == result)
    son = [{'a':1}]
    result = translator.transform_incoming(son, None)
    assert (son == result)
    result = translator.transform_outgoing(son, None)
    assert (son == result)
    son = [{'a':'a'}]
    result = translator.transform_incoming(son, None)
    assert (result and result == [{'a':base64.b64encode('a')}])
    result = translator.transform_outgoing(result, None)
    assert (result and result == son)
    son = [{'a':[{'b':'b'}, {'c':'c'}]}]
    result = translator.transform_incoming(son, None)
    assert (result and result == [{'a':[{'b':base64.b64encode('b')}, {'c':base64.b64encode('c')}]}])
    result = translator.transform_outgoing(result, None)
    assert (result and result == son)
def test_DBController():
    testColName = 'tagTestController'
    dbController = DBController('localhost', 27017, 'test', 'test', '1')
    result = dbController.drop(testColName)
    assert result
    result, cnt = dbController.count(testColName)
    assert (result and cnt == 0)
    doc = {'a':1}
    result = dbController.insert(testColName, doc)
    assert result
    result, recs = dbController.find(testColName)
    assert (result and len(recs) == 1)
    rec = recs[0]
#    del rec['_id']
#    print 'rec = %s\r\ndoc = %s'%(rec, doc)
    assert (rec == doc)
    spec = {'a':1}
    updateDoc = {'a':2}
    updateDocWithModifier = {'$set':updateDoc}
    result = dbController.update(testColName, spec, updateDocWithModifier)
    assert result
    result, recs = dbController.find(testColName)
    assert (result and len(recs) == 1)
    rec = recs[0]
    del rec['_id']
#    print 'rec = %s\r\nupdateDoc = %s'%(rec, updateDoc)
    assert (rec == updateDoc)
    result = dbController.remove(testColName)
    assert result
    result, recs = dbController.find(testColName)
    assert (result and recs == [])
    saveDoc = {'b':3}
    result = dbController.save(testColName, saveDoc)
    assert result
    result, recs = dbController.find(testColName)
    assert (result and len(recs) == 1)
    rec = recs[0]
#    del rec['_id']
    assert (rec == saveDoc)
def test():
    test_seq()
    test_StringManipulator()
    test_DBController()
    print 'test ok!'
if __name__ == '__main__':
    test()
Tool/WebCenter/CouponCode/lib/ReadConfig.py
New file
@@ -0,0 +1,74 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo:
#
# @author: Alee
# @date 2018-6-5 下午08:20:53
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
import ConfigParser
class ReadConfig():
    def __init__(self, filePath):
        self.__config = ConfigParser.ConfigParser()
        self.__config.read(filePath)
    def GetValue(self, section, option, default=None, isThrowException=False):
        try:
            return self.__config.get(section, option);
        except Exception, err:
            if not isThrowException:
                return default;
            raise Exception, "Error:配置问题,%s"%err;
    get = GetValue;
    def GetInt(self, section, option, default = 0, isThrowException=False):
        try:
            return self.__config.getint(section, option);
        except Exception, err:
            if not isThrowException:
                return default;
            raise Exception, "Error:配置问题,%s"%err;
    getint = GetInt;
    def GetBoolean(self, section, option, default = False):
        try:
            return self.__config.getboolean(section, option);
        except ValueError:
            default = str(default).lower();
            if default not in self.__config._boolean_states:
                return False;
            else:
                return self.__config._boolean_states[default];
    getboolean = GetBoolean;
    def HasSection(self, section):
        return self.__config.has_section(section)
    def HasOption(self, section, option):
        return self.__config.has_option(section, option)
#===============================================================================
# ## 读取Eval的值
# def GetEvalConfig(path):
#    with open(path, "r") as file:
#        content = file.read()
#        try:
#            value = eval(content)
#        except:
#            value = None
#
#    return value
#===============================================================================
Tool/WebCenter/CouponCode/lib/TimeRotatingPathFileHandler.py
New file
@@ -0,0 +1,155 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo:
#
# @author: Alee
# @date 2018-7-18 上午11:40:53
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------
#根据时间切换目录和文件的文件处理器
from logging.handlers import *
class TimeRotatingPathFileHandler(TimedRotatingFileHandler):
    def __init__(self, root, filename, when = 'h', interval = 1, backupCount = 0, encoding = None, delay = False, utc = False):
        #创建输出目录数
        t = int(time.time())
        if utc:
            timeTup = time.gmtime(t)
        else:
            timeTup = time.localtime(t)
        year = timeTup[0]
        month = timeTup[1]
        day = timeTup[2]
        self.root = root
        self.filename = filename
        self.baseFilename = self.getBaseFileName(self.root, year, month, day, self.filename)
        #print 'baseFileName = %s'%self.baseFilename
        filepath = os.path.dirname(self.baseFilename)
        self.ensurePath(filepath)
        #改变当前工作目录
        #if not (os.getcwd() == filepath):
        #    os.chdir(filepath)
        TimedRotatingFileHandler.__init__(self, self.baseFilename, when, interval, backupCount, encoding, delay, utc)
        #self.suffix = ''#不指定后缀
    def getBaseFileName(self, root, year, month, day, filename):
        filenameWithoutExt = filename.split('.')[0]
        return os.path.join(root, '%04d-%02d\\%s\\%02d\\%s'%(year, month, filenameWithoutExt, day, filename))
    def ensurePath(self, filepath):
        if not os.path.exists(filepath):
            os.makedirs(filepath)
    def doRollover(self):
        lastRolloverTime = self.rolloverAt
        #TimedRotatingFileHandler.doRollover(self)
        if self.stream:
            self.stream.close()
            self.stream = None
        #获取上一次切换的时间
        t = self.rolloverAt - self.interval
        if self.utc:
            timeTuple = time.gmtime(t)
        else:
            timeTuple = time.localtime(t)
        filenameTuple = self.filename.split('.')
        filename = ''
        if len(filenameTuple) == 1:
            filename = '%s-%s'%(filenameTuple[0], time.strftime(self.suffix, timeTuple))
        else:
            filename = '%s-%s.%s'%(filenameTuple[0], time.strftime(self.suffix, timeTuple), filenameTuple[len(filenameTuple) - 1])
        dfn = os.path.join(self.root, '%04d-%02d\\%s\\%02d\\%s'%(timeTuple[0], timeTuple[1], filenameTuple[0], timeTuple[2], filename))
        #dfn = self.baseFilename + "." + time.strftime(self.suffix, timeTuple)
        if os.path.exists(dfn):
            os.remove(dfn)
#        print 'dfn = %s baseFilename = %s'%(dfn, self.baseFilename)
        #可能由于改系统时间或其他人为原因造成文件找不到
        if os.path.exists(self.baseFilename):
            os.rename(self.baseFilename, dfn)
        if self.backupCount > 0:
            # find the oldest log file and delete it
            #s = glob.glob(self.baseFilename + ".20*")
            #if len(s) > self.backupCount:
            #    s.sort()
            #    os.remove(s[0])
            for s in self.getFilesToDelete():
                os.remove(s)
        currentTime = int(time.time())
        newRolloverAt = self.computeRollover(currentTime)
        while newRolloverAt <= currentTime:
            newRolloverAt = newRolloverAt + self.interval
        #If DST changes and midnight or weekly rollover, adjust for this.
        if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
            dstNow = time.localtime(currentTime)[-1]
            dstAtRollover = time.localtime(newRolloverAt)[-1]
            if dstNow != dstAtRollover:
                if not dstNow:  # DST kicks in before next rollover, so we need to deduct an hour
                    newRolloverAt = newRolloverAt - 3600
                else:           # DST bows out before next rollover, so we need to add an hour
                    newRolloverAt = newRolloverAt + 3600
        self.rolloverAt = newRolloverAt
        #判断是否需要切换文件夹
        nextRolloverTime = self.rolloverAt
        if self.utc:
            lastRolloverTimeTup = time.gmtime(lastRolloverTime)
            nextRolloverTimeTup = time.gmtime(nextRolloverTime)
        else:
            lastRolloverTimeTup = time.localtime(lastRolloverTime)
            nextRolloverTimeTup = time.localtime(nextRolloverTime)
        lastRolloverYear = lastRolloverTimeTup[0]
        lastRolloverMonth = lastRolloverTimeTup[1]
        lastRolloverDay = lastRolloverTimeTup[2]
        nextRolloverYear = nextRolloverTimeTup[0]
        nextRolloverMonth = nextRolloverTimeTup[1]
        nextRolloverDay = nextRolloverTimeTup[2]
        if lastRolloverYear != nextRolloverYear or lastRolloverMonth != nextRolloverMonth or lastRolloverDay != nextRolloverDay:
            #年或月改变,更换文件夹
            self.baseFilename = self.getBaseFileName(self.root, nextRolloverYear, nextRolloverMonth, nextRolloverDay, self.filename)
#            print 'need to rollove path:%s-%s -> %s-%s'%(lastRolloverYear, lastRolloverMonth,
#                                                         nextRolloverYear, nextRolloverMonth)
            filepath = os.path.dirname(self.baseFilename)
            self.ensurePath(filepath)
        else:
            pass
        self.mode = 'w'
        self.stream = self._open()
def test():
    import logging
    mylogger = logging.getLogger('test')
    mylogger.setLevel(logging.DEBUG)
    hdlr = TimeRotatingPathFileHandler('d:\\ServerLog\\', 'AD.txt')
    fs = '%(asctime)s\t%(levelname)-8s\t%(message)s'
    dfs = '%Y-%m-%dT%H:%M:%S'
    fmt = logging.Formatter(fs, dfs)
    hdlr.setLevel(logging.DEBUG)
    hdlr.setFormatter(fmt)
    mylogger.addHandler(hdlr)
#    mylogger.info('test')
#    os.system('pause')
    exit = False
    cnt = 0
    lastTime = time.time()
    while not exit:
        curTime = time.time()
        if curTime - lastTime >= 60:
            lastTime = curTime
            mylogger.info('test')
if __name__ == "__main__":
    test()
Tool/WebCenter/CouponCode/lib/__init__.py
Tool/WebCenter/CouponCode/lib/mylog.py
New file
@@ -0,0 +1,158 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo:
#
# @author: Alee
# @date 2018-7-18 上午11:40:23
# @version 1.0
#
# @note:
#
#---------------------------------------------------------------------\
import logging
from time import localtime
import TimeRotatingPathFileHandler
import CommFunc
__gLogger = None
def InitLog( LogPath, LogName, printToConsole = True, isDebug = True, mode = 'H' ):
    global __gLogger
    logLevel = logging.INFO
    if isDebug:
        logLevel = logging.DEBUG
    #设置日志的过滤等级
    __gLogger = logging.getLogger(LogName)
    __gLogger.setLevel(logLevel)
    hdlr = TimeRotatingPathFileHandler.TimeRotatingPathFileHandler(LogPath, LogName, mode)
    fs = '%(asctime)s\t%(levelname)-8s\t%(message)s'
    dfs = '%Y-%m-%dT%H:%M:%S'
    fmt = logging.Formatter(fs, dfs)
    hdlr.suffix = "%Y-%m-%d_%H-%M-%S"
    hdlr.setLevel(logLevel)
    hdlr.setFormatter(fmt)
    __gLogger.addHandler(hdlr)
    if printToConsole:
        console = logging.StreamHandler()
        console.setFormatter(fmt)
        __gLogger.addHandler(console)
        console.setLevel(logLevel)
__WARN_COUNT = 0
__ERR_COUNT = 0
__FATAL_COUNT = 0
__LastWarnInfo = ""
__LastWarnTime = ""
__LastErrInfo = ""
__LastErrTime = ""
__LastFatalInfo = ""
__LastFatalTime = ""
def GetLastWarnInfo():
    global __LastWarnInfo
    return __LastWarnInfo
def GetLastWarnTime():
    global __LastWarnTime
    return __LastWarnTime
def GetLastErrInfo():
    global __LastErrInfo
    return __LastErrInfo
def GetLastErrTime():
    global __LastErrTime
    return __LastErrTime
def GetLastFatalInfo():
    global __LastFatalInfo
    return __LastFatalInfo
def GetLastFatalTime():
    global __LastFatalTime
    return __LastFatalTime
def Get_Warn_Count():
    global __WARN_COUNT
    return __WARN_COUNT
def Get_Err_Count():
    global __ERR_COUNT
    return __ERR_COUNT
def Get_Fatal_Count():
    global __FATAL_COUNT
    return __FATAL_COUNT
def debug(msg):
    global __gLogger
    __gLogger.debug(msg)
def info(msg):
    global __gLogger
    __gLogger.info(msg)
def warn(msg):
    global __WARN_COUNT
    global __LastWarnInfo
    global __LastWarnTime
    global __gLogger
    __WARN_COUNT += 1
    __LastWarnInfo = msg
    __LastWarnTime = CommFunc.GetCurrentDataTimeStr()
    __gLogger.warning(msg)
__ErrInfoList = []
__OnErr = None
def OnErr(onErr):
    global __OnErr
    __OnErr = onErr
def error(msg):
    global __ERR_COUNT
    global __LastErrInfo
    global __LastErrTime
    global __gLogger
    global __ErrInfoList
    global __OnErr
    __ERR_COUNT += 1
    __LastErrInfo = msg
    __LastErrTime = CommFunc.GetCurrentDataTimeStr()
    if msg not in __ErrInfoList:
        __ErrInfoList.append(msg)
        if __OnErr:
            errInfo = ""
            for info in __ErrInfoList:
                errInfo += "%s\r\n"%info
            __OnErr(errInfo[:-2])
    __gLogger.error(msg)
def fatal(msg):
    global __FATAL_COUNT
    global __LastFatalInfo
    global __LastFatalTime
    global __gLogger
    __FATAL_COUNT += 1
    __LastFatalInfo = msg
    __LastFatalTime = CommFunc.GetCurrentDataTimeStr()
    __gLogger.critical(msg)
def test():
    import os
    InitLog(os.getcwd(), "AD")
    info('test')
if __name__ == '__main__':
    test()
Tool/WebCenter/CouponCode/main.py
New file
@@ -0,0 +1,40 @@
#!/usr/bin/python
# -*- coding: GBK -*-
#
##@package
#
# @todo: 礼包卡对外开放的下载和 礼包领取
#
# @author: Alee
# @date 2018-6-5 下午04:18:14
# @version 1.0
#
#
#需要安装第三方库
#waitress-1.1.0.tar.gz
#requests-2.18.4.tar.gz
#---------------------------------------------------------------------
import webapp
from bottle import run
from lib import mylog
import time
import os
import datetime
from lib import ReadConfig
Def_Debug = ReadConfig.ReadConfig(os.getcwd() + "\\..\\Coupon\\config.ini").GetValue("Coupon", "IsDebug")
#center.secondworld.net.cn
def main():
    time.sleep(1)
    os.system("title Coupon-%s"%datetime.datetime.today())
    mylog.InitLog(r"D:/ServerLog", "CouponCode.txt", False, Def_Debug)
    CenterPort = int(ReadConfig.ReadConfig(os.getcwd() + "\\..\\Coupon\\config.ini").GetValue("Coupon", "CodePort", 53003))
    run(host='0.0.0.0', port=CenterPort, app=webapp.myapp, server='waitress')
    return
if __name__ == '__main__':
    main()