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
#!/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