# -*- coding: utf-8 -*- # !/usr/bin/env python """ ..2017/12/19 更改以dotenv来适应不同环境的环境变量,解决分机部署问题 每小时汇总总的线下投币数量 cd .. && python collect_coins_for_dealers.py 技术要点: #REVIEW0: 1、没有注册的设备,不要进行汇总。 2、建议访问内存,不要访问数据库。先得到所有的经销商,然后内存获取经销商所有的地址组,然后得到组内所有设备,然后汇总。 3、变量名称建议采用驼峰方式命令; 4、从memcache中获取值的时候,如果能够批量,尽量用批量,因为批量的效率远高于单个获取; 5、给组或者经销商的汇总的时候,汇总完毕一次set 6、隔天跨小时的时候,需要特殊处理 判断 7、make_rpt_into_db,最好等这个脚本干完后,在执行。通过硬配置解决这个。 """ import datetime import sys import re from base import init_env, get_logger init_env(interactive = False) logger = get_logger(__name__) from apps.web.device.models import Group, Device, OfflineReportDealers from apps import reportCache def check_offline_coins(dealersWithGroupIds, partnerGroupIds, stringDate, update = True): from apps.web.core.accounting import devCoinTmpl, ownerCoinTmpl, groupCoinTmpl mc = reportCache dealerCoinDict = {} groupCoinDict = {} for ownerId, groupIds in dealersWithGroupIds.items(): ownerCoins = 0 for groupId in list(set(groupIds)): devNos = Device.get_devNos_by_group([groupId]) keys = [devCoinTmpl(devNo, stringDate) for devNo in devNos] valueDict = mc.get_multi(keys) listCoins = [int(coins) for coins in valueDict.values()] allDevCoinsByGroup = sum(listCoins) oldValue = mc.get(groupCoinTmpl(groupId, stringDate)) if not oldValue: oldValue = 0 else: oldValue = int(oldValue) if oldValue != allDevCoinsByGroup: logger.info( 'not equal. ownerId=%s,groupId=%s,oldValue=%s,nowValue=%s' % ( ownerId, groupId, oldValue, allDevCoinsByGroup)) else: logger.info( 'ownerId=%s,groupId=%s,oldValue=%s,nowValue=%s' % ( ownerId, groupId, oldValue, allDevCoinsByGroup)) groupCoinDict[groupCoinTmpl(groupId, stringDate)] = allDevCoinsByGroup if update: mc.set(groupCoinTmpl(groupId, stringDate), str(int(allDevCoinsByGroup))) ownerCoins = ownerCoins + int(allDevCoinsByGroup) dealerCoinDict[ownerCoinTmpl(ownerId, stringDate)] = ownerCoins for partnerId, groupIds in partnerGroupIds.items(): partnerCoinsByGroup = 0 for groupId in list(set(groupIds)): if groupCoinTmpl(groupId, stringDate) in groupCoinDict: groupCoin = groupCoinDict[groupCoinTmpl(groupId, stringDate)] else: groupCoin = 0 logger.info( 'allocated as partner. partnerId = %s; groupId = %s; coin = %s' % (partnerId, groupId, groupCoin)) partnerCoinsByGroup = partnerCoinsByGroup + int(groupCoin) if ownerCoinTmpl(partnerId, stringDate) in dealerCoinDict: dealerCoinDict[ownerCoinTmpl(partnerId, stringDate)] = dealerCoinDict[ ownerCoinTmpl(partnerId, stringDate)] + partnerCoinsByGroup else: dealerCoinDict[ownerCoinTmpl(partnerId, stringDate)] = partnerCoinsByGroup for dealerKey, coin in dealerCoinDict.items(): oldValue = mc.get(dealerKey) if not oldValue: oldValue = 0 else: oldValue = int(oldValue) if oldValue != coin: logger.info( 'not equal. ownerKey=%s,oldValue=%s,nowValue=%s' % ( dealerKey, oldValue, coin)) else: logger.info( 'ownerKey=%s,nowValue=%s' % ( dealerKey, coin)) if update: mc.set(dealerKey, str(int(coin))) def main(dateFmtStr): dealerId = None if len(sys.argv) >= 2: dealerId = str(sys.argv[1]) if dateFmtStr: reportDate = datetime.datetime.strptime(dateFmtStr, "%Y-%m-%d") else: reportDate = datetime.datetime.now() - datetime.timedelta(days = 1) if dealerId: dealer_id_list = [dealerId] else: dealer_id_list = OfflineReportDealers.get_rpt_dealIds(reportDate.strftime("%Y-%m-%d")) # if dealerId: # dealers = Dealer.get_collection().find({'_id': ObjectId(dealerId)}) # else: # dealers = Dealer.get_collection().find({}) # # dealers = [dealer for dealer in dealers] dealersWithGroupIds = {} partnerGroupIds = {} for _dealerId in dealer_id_list: dealersWithGroupIds[_dealerId] = Group.get_group_ids_of_dealer(_dealerId) partnerGroupIds[_dealerId] = Group.get_group_ids_of_partner(_dealerId) check_offline_coins(dealersWithGroupIds, partnerGroupIds, reportDate.strftime("%Y-%m-%d")) logger.info('Over!') if __name__ == '__main__': dateFmtStr = None index = 1 regex = re.compile(r'\d{4}-\d{2}-\d{2}') for arg in sys.argv[1:]: m = regex.search(arg) if m and m.group(): dateFmtStr = arg sys.argv.pop(index) break index += 1 main(dateFmtStr)