hxp
2024-10-31 402ed2e6a90a785d2fce3eca23cd324f350d54c5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
#!/usr/bin/python
# -*- coding: utf-8 -*-
#-------------------------------------------------------------------------------
 
import sys
import datetime
import traceback
import urllib2
import urllib
import json
import os
import logging
import gettext
import sys
import ConfigParser
 
Encoding = "utf-8"
 
FinalDataSign = "_FinalData"
 
def encode(s):
    if isinstance(s, unicode):
        return s.encode(Encoding)
    elif isinstance(s, int) or isinstance(s, long):
        return s
    elif not isinstance(s, str):
        return str(s)
    return s
 
def toGBK(s):
    return s.decode(Encoding).encode("gbk")
 
def encodePych(pyChStr):
    ## 转化py中文
    return unicode(pyChStr, Encoding).encode(Encoding)
 
def setdefaultencoding(encoding=None):
    reload(sys)
    sys.setdefaultencoding(encoding if encoding else Encoding)
    return
 
def parse_args():
    ## 解析运行参数
    #print "sys.argv: ", len(sys.argv), sys.argv
    argvDict = {}
    for argvInfo in sys.argv[1:]:
        kvList = argvInfo.split("=")
        if not kvList:
            continue
        value = kvList[1] if len(kvList) > 1 else ""
        # 中文参数超过4个字会有问题,但是用符号包起来就没问题,暂未知原因,先这样处理,参数固定用[]包起来
        if value.startswith("[") and value.endswith("]"):
            value = value[1:-1]
        argvDict[kvList[0]] = value
    #print "parse_args: ", argvDict
    return argvDict
 
def toInt(inputValue, defValue=0):
    try:
        result = int(inputValue)
        return result
    except:
        return defValue
    
def checkDate(startDate, endDate, checkDate):
    ## 检查对应日期是否在指定日期范围内,参数都是 datetime 类型
    
    if not checkDate:
        return False
    
    if startDate and checkDate < startDate:
        return False
    
    if endDate and checkDate > endDate:
        return False
    
    return True
    
def strToDatetime(timeStr, strFormat="%Y-%m-%d"):
    try:
        return datetime.datetime.strptime(timeStr, strFormat)
    except:
        return
    
def getDiffDaysDate(diffDays, dateObj=None):
    ## 日期加减运算
    if dateObj == None:
        dateObj = datetime.datetime.today()
    return dateObj + datetime.timedelta(days=diffDays)
 
def getCurrentTime():
    return datetime.datetime.today()
 
def getCurrentDateStr():
    curTime = datetime.datetime.today()
    return "%d-%02d-%02d" % (curTime.year, curTime.month, curTime.day)
 
def getServerID(accID):
    infoList = accID.split("@")
    return 0 if len(infoList) < 3 else int(infoList[-1][1:])
 
def coinToY(coinValue, rate=100):
    ## coin转为元
    toValue = coinValue / float(rate)
    if str(toValue).endswith(".0"):
        toValue = int(toValue)
    return toValue
 
def getCoinRate(cfg, spid):
    ## 获取coin的转化比例,默认100
    if cfg.has_option("ExChange", "ExChangeScale_%s" % spid):
        return int(cfg.get("ExChange", "ExChangeScale_%s" % spid))
    if cfg.has_option("ExChange", "ExChangeScale"):
        return int(cfg.get("ExChange", "ExChangeScale"))
    return 100
 
def roundInt(value, ndigits=2):
    ## 保留x位小数,如果刚好x.0则取整
    value = round(value, ndigits)
    if str(value).endswith(".0"):
        value = int(value)
    return value
 
def matchDr(drDict, matchSet={}, filterSet={}):
    ''' 检查流向数据是否是需要满足匹配条件的数据
    @param matchSet: 匹配设定 {匹配key:[匹配值列表], ...}, 即只会匹配对应key为指定值列表的内容
    @param filterSet: 过滤设定, {过滤key:[过滤值列表], ...}, 即会过滤掉对应key为某些值的内容 
    @return: 是否是需要统计的流向数据
    '''
    # 优先检查被过滤掉的
    for filterKey, filterList in filterSet.items():
        if filterKey not in drDict:
            continue
        if drDict[filterKey] in filterList:
            return False
        
    # 检查精确匹配的
    for matchKey, matchList in matchSet.items():
        if matchKey not in drDict:
            return False
        if drDict[matchKey] not in matchList:
            return False
        
    return True
 
def parseMixServerIDInfo(mixServerIDInfo, useAllIDList=False):
    ## 解析合服服务器ID组合信息  支持范围: 服务器ID~服务器ID 或  单服:服务器ID;  多组
    ''' 解析合服服务器ID组合信息
            支持格式:
                    范围: 服务器ID~服务器ID
                    单服:服务器ID
            
            组合格式:按支持的格式使用英文逗号分割,如  1~10,20,30  代表 1至10服 及 20服 及 30服
    '''
    serverIDList = []
    if not mixServerIDInfo:
        return serverIDList
    splitList = mixServerIDInfo.replace(" ", "").split(",")
    for idInfo in splitList:
        if idInfo.isdigit():
            serverIDList.append(int(idInfo))
        elif "~" in idInfo:
            rangeIDList = idInfo.split("~")
            if useAllIDList:
                serverIDList.extend(range(int(rangeIDList[0]), int(rangeIDList[1]) + 1))
            else:
                serverIDList.append([int(rangeIDList[0]), int(rangeIDList[1])])
    return serverIDList
 
def checkIsBackupServerFolder(queryServerIDList, checkServerInfo):
    ''' 检查是否满足需要查询的区服备份
    @param queryServerIDList: 需要查询的目标服务器组合列表,由 parseMixServerIDInfo 解析得到
    @param checkServerInfo: 需要检查是否满足条件的区分ID信息串,可由 parseMixServerIDInfo 解析的格式
    @return: 是否满足
    '''
    checkServerIDList = parseMixServerIDInfo(checkServerInfo)
    if not checkServerIDList:
        return False
    
    for checkServerIDInfo in checkServerIDList:
        if isinstance(checkServerIDInfo, int):
            checkID = checkServerIDInfo
            if checkID in queryServerIDList:
                return True
            for queryServerIDInfo in queryServerIDList:
                if isinstance(queryServerIDInfo, int):
                    continue
                queryIDMin, queryIDMax = queryServerIDInfo
                if queryIDMin <= checkID <= queryIDMax:
                    return True
        else:
            checkIDMin, checkIDMax = checkServerIDInfo
            for queryServerIDInfo in queryServerIDList:
                if isinstance(queryServerIDInfo, int):
                    if checkIDMin <= queryServerIDInfo <= checkIDMax:
                        return True
                else:
                    queryIDMin, queryIDMax = queryServerIDInfo
                    if checkIDMin <= queryIDMin <= checkIDMax or checkIDMin <= queryIDMax <= checkIDMax \
                        or queryIDMin <= checkIDMin <= queryIDMax or queryIDMin <= checkIDMin <= queryIDMax:
                        return True
                    
    return False
 
def queryBackupCenterDR(cfg, postData={}):
    ## 查询中心合服备份流向数据
    # @return: 中心返回数据,None代表失败,需用None判断,因为可能实际数据就是空的列表
    url = cfg.get("ServerInfo", "EventDataBackupToolUrl")
    postData["queryCenterbak"] = 1
    req = urllib2.Request(url=url, data=urllib.urlencode(postData))
    res_data = urllib2.urlopen(req, timeout=120)
    resMsg = res_data.read()
    if not resMsg:
        print "error: query backup center's eventdata no message return!<br/>"
        return
    
    if resMsg.startswith("error:") or "Traceback" in resMsg:
        print resMsg
        return
    
    return json.loads(resMsg)
 
def queryBackupCenterError(errorMsg):
    print "error: %s" % errorMsg
    return
 
def queryBackupCenterOK(retData):
    ## 成功默认返回json格式数据,支持普通kv字典,或类实例转化json
    #logging.info("retData:%s", retData)
    print json.dumps(retData, ensure_ascii=False, default=lambda obj: obj.__dict__)
    return
 
def printExceptionError():
    ## 显示报错等异常信息
    error = traceback.format_exc()
    error = error.replace("<", "&lt;").replace(">", "&gt;").replace("\r", "<br/>").replace("\n", "<br/>")
    print "error:<br/>:", error
    
def loopMainServerDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc, parseLineFunc, *parseArgs, **kv):
    ''' 循环遍历游戏主服流向信息,并解析满足时间范围流向
    @param cfg: InterfaceConfig.php 配置对象
    @param startDate: 起始日期
    @param endDate: 结束日期
    @param argvDict: post到中心的参数
    @param checkDrFileNeedParseFunc: 额外检查流向文件是否需要解析的函数,传入参数(流向文件名 drFileName, *parseArgs, **kv),返回自定义信息提供  parseLineFunc 用
    @param parseLineFunc: 解析流向每行内容的逻辑函数,传入参数(流向名drName, 所属dateStr, checkDrFileNeedParseFunc 返回的结果信息 checkNeedParseRetInfo, 流向行内容line, *parseArgs, **kv)
    @param *parseArgs: 自定义参数
    
    @return: needQueryCenterbak 是否需要查询中心备份流向数据
    '''
    
    startDatetime = strToDatetime(startDate)
    endDatetime = strToDatetime(endDate)
    minDatetime = None
    logging.info("loopMainServerDR %s" % str(argvDict))
    # 流向路径
    FolderPath = os.path.join(cfg.get("ServerInfo", "ServerPath"), "EventServer\EventData")
    for parent, _, fileList in os.walk(FolderPath):
        parentList = parent.split("\\")
        lastStr = parentList[-1]
        fileDatetime = strToDatetime(lastStr)
        
        if fileDatetime and (not minDatetime or fileDatetime < minDatetime):
            minDatetime = fileDatetime
            
        if not checkDate(startDatetime, endDatetime, fileDatetime):
            continue
        
        # 指定遍历流向文件及顺序
        if "drNameList" in kv:
            loopFileList = ["%s_%s.txt" % (drName, lastStr) for drName in kv["drNameList"]]
        else:
            loopFileList = fileList
            
        for drFileName in loopFileList:
            fullPath = os.path.join(parent, drFileName)
            
            if not os.path.isfile(fullPath):
                continue
            
            dateStr = lastStr # 流向日期
            
            isNeed, checkNeedParseRetInfo = checkDrFileNeedParseFunc(drFileName, *parseArgs, **kv)
            if not isNeed:
                continue
            
            # 以下为已经确定需要处理的流向文件逻辑,可进行open、readlines、eval等操作
            drName = drFileName[:drFileName.rindex("_")] # 流向名
            f = open(fullPath, "r")
            lines = f.readlines()
            f.close()
            for line in lines:
                parseLineFunc(drName, dateStr, checkNeedParseRetInfo, line, *parseArgs, **kv)
                
    ## 查询所有数据(含备份在中心服务器的本次合服前的数据)
    needQueryCenterbak = argvDict.get("queryAllData") and (not startDatetime or not minDatetime or startDatetime <= minDatetime)
    if needQueryCenterbak:
        argvDict["queryCenterbak"] = 1 # 设置查询中心备份数据  与  isQueryCenterbak 对应
    logging.info("End")
    return needQueryCenterbak
 
def isQueryCenterbak(argvDict):
    ## 是否查询中心备份的
    return argvDict.get("queryCenterbak") != None
 
def loopCenterbakRarDR(cfg, startDate, endDate, argvDict, checkDrFileNeedParseFunc, parseLineFunc, *parseArgs, **kv):
    ''' 循环遍历中心服务器备份流向信息,并解析满足时间范围及区服条件的流向
    @note: Rar专用
    @param cfg: InterfaceConfig.php 配置对象
    @param argvDict: post到中心的参数
    @param checkDrFileNeedParseFunc: 额外检查流向文件是否需要解析的函数,传入参数(流向文件名 drFileName, *parseArgs, **kv),返回自定义信息提供  parseLineFunc 用
    @param parseLineFunc: 解析流向每行内容的逻辑函数,传入参数(流向名drName, 所属dateStr, checkDrFileNeedParseFunc 返回的结果信息 checkNeedParseRetInfo, 流向行内容line, *parseArgs, **kv)
    @param *parseArgs: 解析函数所需的参数
    
    @return: 是否成功
    '''
    logging.info("loopCenterbakRarDR %s" % str(argvDict))
    allServer = argvDict.get("allServer", 0)
    mixServerIDInfo = argvDict.get("mixServerIDInfo", "")
    if not allServer and not mixServerIDInfo:
        queryBackupCenterError("can not found mixServerIDInfo!")
        return
    
    spID = argvDict.get("spID", "")
    backupPath = os.path.join(cfg.get("ServerInfo", "EventDataBackupPath"), spID, "EventData")
    isUseRar = cfg.getint("ServerInfo", "EventDataBackupUseRar") == 1 # 是否使用压缩包
    logging.info("isUseRar=%s,spID=%s,backupPath=%s" % (isUseRar, spID, backupPath))
    if not os.path.exists(backupPath):
        queryBackupCenterError("can not found backup path: %s" % backupPath)
        return
    
    startDatetime = strToDatetime(startDate)
    endDatetime = strToDatetime(endDate)
    OnlyServerID = int(argvDict.get("OnlyServerID", 0))
    serverIDList = [OnlyServerID] if OnlyServerID else parseMixServerIDInfo(mixServerIDInfo)
    spfileFormat = "Event_%s-s" % spID
    
    logging.info("allServer=%s,serverIDList=%s,spfileFormat=%s" % (allServer, serverIDList, spfileFormat))
    # 备份日期文件夹
    for backupDateFile in os.listdir(backupPath):
        backupDateStr = backupDateFile[len("Event_"):]
        backupDatetime = strToDatetime(backupDateStr)
        if not checkDate(startDatetime, "", backupDatetime):
            continue
        
        if not isUseRar:
            # 备份分区文件夹
            for backupServer in os.listdir(os.path.join(backupPath, backupDateFile)):
                if backupServer.endswith(".rar"):
                    # rar文件的不处理
                    continue
                if not backupServer.startswith(spfileFormat):
                    continue
                serverInfo = backupServer[len(spfileFormat):]
                if not allServer and not checkIsBackupServerFolder(serverIDList, serverInfo):
                    continue
                
                logging.info("loop %s" % os.path.join(backupPath, backupDateFile, backupServer))
                for parent, _, fileList in os.walk(os.path.join(backupPath, backupDateFile, backupServer)):
                    if not fileList:
                        continue
                    
                    parentList = parent.split("\\")
                    lastStr = parentList[-1]
                    fileDatetime = strToDatetime(lastStr)
                    
                    if not checkDate(startDatetime, endDatetime, fileDatetime):
                        continue
                    
                    # 指定遍历流向文件及顺序
                    if "drNameList" in kv:
                        loopFileList = ["%s_%s.txt" % (drName, lastStr) for drName in kv["drNameList"]]
                    else:
                        loopFileList = fileList
                        
                    for drFileName in loopFileList:
                        fullPath = os.path.join(parent, drFileName)
                        if not os.path.isfile(fullPath):
                            continue
                        
                        dateStr = lastStr # 流向日期
                        
                        checkNeedParseRetInfo = []
                        if checkDrFileNeedParseFunc:
                            isNeed, checkNeedParseRetInfo = checkDrFileNeedParseFunc(drFileName, *parseArgs, **kv)
                            if not isNeed:
                                continue
                            
                        # 以下为已经确定需要处理的流向文件逻辑,可进行open、readlines、eval等操作
                        drName = drFileName[:drFileName.rindex("_")] # 流向名
                        
                        f = open(fullPath, "r")
                        lines = f.readlines()
                        f.close()
                        for line in lines:
                            parseLineFunc(drName, dateStr, checkNeedParseRetInfo, line, *parseArgs, **kv)
                        
        else:
            from unrar import rarfile # 放在函数内,子服用不到此模块,这样就不需要安装此依赖了
            # 备份分区文件夹
            for backupServer in os.listdir(os.path.join(backupPath, backupDateFile)):
                if not backupServer.endswith(".rar"):
                    # 非rar文件的不处理
                    continue
                if not backupServer.startswith(spfileFormat):
                    continue
                serverInfo = backupServer[len(spfileFormat):-4]
                if not allServer and not checkIsBackupServerFolder(serverIDList, serverInfo):
                    continue
                #logging.info("backupServer:%s" % backupServer)
                #rarfile.namelist() # 列表,rar文件中所有子文件的path(相对于rar文件包而言的)
                #rar解析只能遍历rar内所有文件,无法直接定位,会相对文件夹遍历慢
                # drPath is like: server\EventServer\EventData\Group_0\Server_0\2021-01-04\OpenPackCount_2021-01-04.txt
                drRarFile = rarfile.RarFile(os.path.join(backupPath, backupDateFile, backupServer))
                drFileNameList = drRarFile.namelist()
                loopFileList = []
                if "drNameList" in kv:
                    loopDateInfo = {}
                    for drPath in drFileNameList[::-1]:
                        if "." in drPath:
                            continue
                        rspList = drPath.split("\\")
                        dateStr = rspList[-1] # 日期字符串
                        fileDatetime = strToDatetime(dateStr)
                        if not fileDatetime:
                            continue
                        if not checkDate(startDatetime, endDatetime, fileDatetime):
                            continue
                        drDatePath = drPath
                        loopDateInfo[dateStr] = drDatePath
                        
                    loopDateList = loopDateInfo.keys()
                    loopDateList.sort()
                    
                    # 需要遍历的日期文件夹路径列表
                    for dateStr in loopDateList:
                        drDatePath = loopDateInfo[dateStr]
                        for drName in kv["drNameList"]:
                            loopDrPath = os.path.join(drDatePath, "%s_%s.txt" % (drName, dateStr))
                            if loopDrPath in drFileNameList:
                                loopFileList.append(os.path.join(drDatePath, "%s_%s.txt" % (drName, dateStr)))
                                
                else:
                    loopFileList = drFileNameList
                    
                for drPath in loopFileList:
                    if "." not in drPath:
                        continue
                    #logging.info("loop: %s", str(drPath))
                    rspList = drPath.split("\\")
                    if len(rspList) < 2:
                        continue
                    dateStr = rspList[-2] # 日期字符串
                    fileDatetime = strToDatetime(dateStr)
                    if not checkDate(startDatetime, endDatetime, fileDatetime):
                        continue
                    
                    drFileName = rspList[-1] # 流向文件名  xxxx_日期.txt
                    
                    checkNeedParseRetInfo = []
                    if checkDrFileNeedParseFunc:
                        isNeed, checkNeedParseRetInfo = checkDrFileNeedParseFunc(drFileName, *parseArgs, **kv)
                        if not isNeed:
                            continue
                        
                    drName = drFileName[:drFileName.rindex("_")] # 流向名
                    
                    rarOpenObj = drRarFile.open(drPath)
                    for line in rarOpenObj.readlines():
                        parseLineFunc(drName, dateStr, checkNeedParseRetInfo, line, *parseArgs, **kv)
                        
    logging.info("loopEnd")
    return True
 
def editTableHtml(dataList, tdList, rowNumTitle="", styleInfo={}, printCount=True):
    ''' 编辑表格html
    @param dataList: 数据列表,元素支持 类实例 或 字典
    @param tdList: 表格属性字段key顺序列表
    @param rowNumTitle: 行编号标题,如果空表示不显示行编号,非空则传入行编号标题名,行编号默认为 index + 1
    @param styleInfo: 属性字段样式信息
    '''
    tablHtml = ""
    if printCount:
        tablHtml += _(u"数据条数") + ": %s<br/>" % len(dataList)
    tablHtml += "<table id=\"tt\" class=\"border-table\">"
    
    # 标题行
    tablHtml += "<tr>"
    if rowNumTitle:
        tablHtml += "<td align='center'>%s</td>" % (rowNumTitle)
    for tdKey in tdList:
        style = styleInfo.get(tdKey, {})
        tablHtml += "<td align='center'>%s</td>" % (style.get("title", tdKey))
    tablHtml += "</tr>"
    
    # 内容
    for i, dataObj in enumerate(dataList):
        tablHtml += "<tr>"
        if rowNumTitle:
            tablHtml += "<td align='center'>%s</td>" % (i + 1)
            
        for tdKey in tdList:
            # 仅支持字典及类
            tdValue = ""
            if isinstance(dataObj, dict):
                tdValue = dataObj.get(tdKey, "")
            elif hasattr(dataObj, tdKey):
                tdValue = getattr(dataObj, tdKey)
                
            if isinstance(tdValue, unicode):
                tdValue = tdValue.encode(Encoding)
            elif not isinstance(tdValue, str):
                tdValue = str(tdValue)
            style = styleInfo.get(tdKey, {})
            tablHtml += "<td align='%s'>%s</td>" % (style.get("align", "center"), tdValue)
            
        tablHtml += "</tr>"
        
    tablHtml += "</table>"
    return tablHtml
 
def getCfgKeyNameDict(cfgName, argvDict):
    ## 根据游戏配置母表字段id及name文件名获取对应的id对应name字典,用于转化ID名称用
    txtFileDir = "../../Common/config/%s/%s/%s.txt" % (argvDict.get("spID", ""), argvDict.get("lang", ""), cfgName)
    if not os.path.exists(txtFileDir):
        txtFileDir = "../../Common/config/%s/%s.txt" % (argvDict.get("spID", ""), cfgName)
        if not os.path.exists(txtFileDir):
            return {}
    kvDict = {}
    f = open(txtFileDir, "r")
    lines = f.readlines()
    for line in lines:
        if not line:
            continue
        spList = line.split("\t")
        if len(spList) != 2:
            continue
        kvDict[spList[0]] = spList[1].replace("\r", "").replace("\n", "")
    return kvDict
 
def getSPConfig(argvDict, section, option, defaultValue=None):
    '''获取sp运营项目对应专属配置
    @param section 配置节点
    @param option 配置项
    '''
    iniFileDir = "../../Common/config/%s/config.ini" % argvDict.get("spID", "")
    if not os.path.exists(iniFileDir):
        return defaultValue
    cfg = ConfigParser.ConfigParser()
    cfg.read(iniFileDir)
    if not cfg.has_option(section, option):
        return defaultValue
    return cfg.get(section, option)
 
def transformNum(num):
    if num < 10000:
        fpStr = str(num)
    elif num < 1000000:
        fpStr = "%.2f%s" % (num / 10000.0, _(u"万"))
    elif num < 100000000:
        fpStr = "%.1f%s" % (num / 10000.0, _(u"万"))
    else:
        fpStr = "%.3f%s" % (num / 100000000.0, _(u"亿"))
    return fpStr
 
def gettextInstall(languages=None):
    ## 初始化翻译 gettext
    if not languages:
        languages = "zh_CN"
    if type(languages) == str:
        languages = [languages]
    gt = gettext.translation("eventDataPy", "../../language", languages)
    gt.install()
    return
 
def getPayOrderTypeName(payOrderType):
    PayOrderTypeName = {1:_(u"人民币"), 2:_(u"美元"), 3:_(u"越南盾"), 4:_(u"soha币"), 5:_(u"金票点券"), 6:_(u"代币")}
    return PayOrderTypeName.get(payOrderType, "%s[%s]" % (_(u"未知订单类型"), payOrderType))
 
def getPayOrderCoinRate(payOrderType):
    rateDict = {3:1, 6:1}
    return rateDict.get(payOrderType, 100)