| #!/usr/bin/python  | 
| # -*- coding: utf-8 -*-  | 
| #  | 
| ##@package  | 
| #  | 
| # @todo: 受理HTTP请求  | 
| #  | 
| # @author: xdh  | 
| # @date 2018-6-8 17:10:51  | 
| # @version 1.0  | 
| #  | 
| # @note: 中文必须传utf8,收到的为urlencode内容  .decode('gbk').encode('utf8')  | 
| #  | 
| #---------------------------------------------------------------------  | 
|   | 
| from bottle import Bottle, request  | 
| import logging  | 
| import requests  | 
| import urllib  | 
| import shelve  | 
| import time  | 
| from lib import ConfigIniReader  | 
| import threading  | 
|   | 
| requests.packages.urllib3.disable_warnings()  | 
|   | 
| # get: request.query.username request.GET.get('username','')  | 
| # post: request.forms.get('username')  request.POST.get('username')  | 
| #===============================================================================  | 
| # @myapp.route('/cool/kk/:name3/:count#\\d+#')  | 
| # def maybe(name3, count):  | 
| #===============================================================================  | 
|   | 
| myapp = Bottle()  | 
|   | 
| voiceInfoDict = shelve.open('voice.db', writeback=False)  | 
| g_lastCheckTick = 0  | 
| delCD = int(ConfigIniReader.GetConfig().GetValue('delCD'))  | 
| outTime = int(ConfigIniReader.GetConfig().GetValue('outTime'))  | 
|   | 
| #存储内容 {'playerID_语音唯一ID':[time,Content],..}  | 
| #post内容 playerID=玩家ID voiceID=语音唯一ID  content=语音内容  appid  | 
| #dotype  upload、download  | 
|   | 
| @myapp.route('/voice/:dotype', method=['POST'])  | 
| def VoiceSave(dotype):  | 
|     global voiceInfoDict  | 
|   | 
|     getDict = request.POST  | 
|       | 
|     #logging.info("request.POST=%s"%(str(dict(getDict))))  | 
|      | 
|     playerID = getDict.get("playerID",'')  | 
|     voiceID = getDict.get("voiceID",'')  | 
|     content = getDict.get("content","")  | 
|     #content = urllib.unquote(getDict.get("content",""))  | 
|       | 
|     if not playerID or not voiceID:  | 
|         logging.error("POST未找到参数 playerID=%s,voiceID=%s"%(playerID, voiceID))  | 
|         return  | 
|       | 
|     keyStr = '%s_%s'%(playerID, voiceID)  | 
|     curTime = int(time.time())  | 
|       | 
|     if dotype == 'upload': #存储  | 
|         saveData = [curTime, content]  | 
|         voiceInfoDict[keyStr] = saveData  | 
|         voiceInfoDict.sync()  | 
|           | 
|         #logging.info("upload %s-%s-%s"%(playerID, voiceID, saveData))  | 
|         returnVoiceData= None  | 
|           | 
|     elif dotype == 'download':#下载  | 
|         voiceData=voiceInfoDict.get(keyStr, [])  | 
|         if not voiceData:  | 
|             logging.info("download not find voice %s-%s-%s"%(playerID, voiceID, voiceData))  | 
|             returnVoiceData = {"playerID":playerID, "voiceID":voiceID}  | 
|         else:  | 
|             #logging.info("download %s-%s-%s"%(playerID, voiceID, voiceData))  | 
|             returnVoiceData = {"playerID":playerID, "voiceID":voiceID, "content":voiceData[1]}  | 
|           | 
|     else:  | 
|         logging.error("dotype not in [download, upload] %s-%s-%s"%(playerID, voiceID, dotype))  | 
|         return  | 
|       | 
|     #voiceInfoDict.close()  | 
|     #触发一次处理旧数据(放最后)  | 
|     DelOldVoice(curTime)  | 
|     return returnVoiceData  | 
| t1 = None  | 
| def DelOldVoice(tick):  | 
|     #处理旧数据  | 
|     global g_lastCheckTick  | 
|     global t1  | 
|     if g_lastCheckTick and tick - g_lastCheckTick < delCD:  | 
|         #半小时处理一次  | 
|         return  | 
|     g_lastCheckTick = tick  | 
|     #新开线程处理删除逻辑,防止数据过大导致回复慢  | 
|     if t1 and t1.isAlive():  | 
|         return  | 
|     #print threading.activeCount()  | 
|     t1 = threading.Thread(target=__DelOldVoice)  | 
|     t1.start()  | 
|     return  | 
|   | 
| def __DelOldVoice():  | 
|     global voiceInfoDict  | 
|       | 
|     tick = int(time.time())  | 
|     for voiceKey, voiceData in voiceInfoDict.items():  | 
|         saveTime = voiceData[0]  | 
|         if tick - saveTime > outTime: #删除超过半小时的数据  | 
|             if voiceInfoDict.pop(voiceKey, 0):  | 
|                 voiceInfoDict.sync()  | 
|                 #logging.info("del old record voiceKey=%s"%voiceKey)  | 
|     #voiceInfoDict.close()  | 
|       | 
|     return |