def voice_order_handler(orders): """ save voice-call and voice-order """ order_groups = defaultdict(list) for order in orders: order_groups[order.restaurant_id].append(order) for restaurant_id, orders in order_groups.items(): orders = _validate_order(orders) if not orders: continue with thrift_client('ers') as ers: restaurant = ers.get(restaurant_id) restaurant_phone = get_rst_takeout_phone(restaurant) if not restaurant_phone: continue voice_call = VoiceCall.add(restaurant_id=restaurant_id, call_status=VoiceCall.STATUS_NOT_DIAL, created_at=datetime.now(), phone=restaurant_phone, flush=True) for order in orders: VoiceOrder.add(order_id=order.id, status_code=order.status_code, sequence_number=order.restaurant_number, created_at=datetime.fromtimestamp(order.created_at), call_id=voice_call.id) log.info('voice order received with restaurant_id [{}], call_id [{}]'. format(restaurant_id, voice_call.id))
def voice_call_handler(call_id): """ handle only one call each time. """ STATUS_PROCESSING = thirdparty_svc.eos.ORDER_STATUS.STATUS_PROCESSING voice_call = VoiceCall.get(call_id) if not voice_call: raise_user_exc(VOICE_CALL_NOT_FOUND, call_id=call_id) voice_orders = VoiceOrder.get_by_call_id(voice_call.id) # recheck with thrift_client('eos') as eos_client: order_ids = [order.order_id for order in voice_orders] t_orders = eos_client.mget(order_ids) t_orders = filter(lambda _o: _o.status_code == STATUS_PROCESSING, t_orders) t_order_ids = [order.id for order in t_orders] voice_orders = [ v_order for v_order in voice_orders if v_order.order_id in t_order_ids ] if not voice_orders: return call_params = _generate_call_params(voice_call, voice_orders) call_status = _send_call(call_params) voice_call.call_status = call_status
def voice_call_handler(call_id): """ handle only one call each time. """ STATUS_PROCESSING = thirdparty_svc.eos.ORDER_STATUS.STATUS_PROCESSING voice_call = VoiceCall.get(call_id) if not voice_call: raise_user_exc(VOICE_CALL_NOT_FOUND, call_id=call_id) voice_orders = VoiceOrder.get_by_call_id(voice_call.id) # recheck with thrift_client('eos') as eos_client: order_ids = [order.order_id for order in voice_orders] t_orders = eos_client.mget(order_ids) t_orders = filter( lambda _o: _o.status_code == STATUS_PROCESSING, t_orders) t_order_ids = [order.id for order in t_orders] voice_orders = [v_order for v_order in voice_orders if v_order.order_id in t_order_ids] if not voice_orders: return call_params = _generate_call_params(voice_call, voice_orders) call_status = _send_call(call_params) voice_call.call_status = call_status
def voice_order_handler(orders): """ save voice-call and voice-order """ order_groups = defaultdict(list) for order in orders: order_groups[order.restaurant_id].append(order) for restaurant_id, orders in order_groups.items(): orders = _validate_order(orders) if not orders: continue with thrift_client('ers') as ers: restaurant = ers.get(restaurant_id) restaurant_phone = get_rst_takeout_phone(restaurant) if not restaurant_phone: continue voice_call = VoiceCall.add(restaurant_id=restaurant_id, call_status=VoiceCall.STATUS_NOT_DIAL, created_at=datetime.now(), phone=restaurant_phone, flush=True) for order in orders: VoiceOrder.add(order_id=order.id, status_code=order.status_code, sequence_number=order.restaurant_number, created_at=datetime.fromtimestamp(order.created_at), call_id=voice_call.id) log.info('voice order received with restaurant_id [{}], call_id [{}]'. format(restaurant_id, voice_call.id))
def update_keysback(): """ Get back voice call's keys which restaurant inputs """ ElemeOrderConst = thirdparty_svc.eos.ElemeOrderConst OrderRecordConst = thirdparty_svc.eos.OrderRecordConst args = request.args if request.method == 'GET' else request.form log.info('Keysback args: %s' % args.items()) order_id = to_int(args.get('orderId')) key_pressed = to_int(args.get('press')) call_id = to_int(args.get('userField'), silence=False) voice_order = VoiceOrder.get_by_order_id(order_id) if key_pressed == KEY_AFFIRM: status_to = ElemeOrderConst.STATUS_PROCESSED_AND_VALID with thrift_client('eos') as eos: eos.eleme_process_order(order_id, status_to, OrderRecordConst.PROCESSED_BY_MACHINE, OrderRecordConst.PROCESS_GROUP_ADMIN, '', 0) voice_order.status_code = status_to log.info('update eleme order to status: %d.' % status_to) elif key_pressed == KEY_BAN_TODAY: restaurant_id = VoiceCall.get(call_id).restaurant_id VoicecallBan.add(restaurant_id, VoicecallBan.BAN_TYPE_TODAY) log.info('add voice call ban for restaurant {}'.format(restaurant_id)) voice_order.key_pressed = key_pressed return {'result': 'success'}
def update_keysback(): """ Get back voice call's keys which restaurant inputs """ ElemeOrderConst = thirdparty_svc.eos.ElemeOrderConst OrderRecordConst = thirdparty_svc.eos.OrderRecordConst args = request.args if request.method == 'GET' else request.form log.info('Keysback args: %s' % args.items()) order_id = to_int(args.get('orderId')) key_pressed = to_int(args.get('press')) call_id = to_int(args.get('userField'), silence=False) voice_order = VoiceOrder.get_by_order_id(order_id) if key_pressed == KEY_AFFIRM: status_to = ElemeOrderConst.STATUS_PROCESSED_AND_VALID with thrift_client('eos') as eos: eos.eleme_process_order( order_id, status_to, OrderRecordConst.PROCESSED_BY_MACHINE, OrderRecordConst.PROCESS_GROUP_ADMIN, '', 0) voice_order.status_code = status_to log.info('update eleme order to status: %d.' % status_to) elif key_pressed == KEY_BAN_TODAY: restaurant_id = VoiceCall.get(call_id).restaurant_id VoicecallBan.add(restaurant_id, VoicecallBan.BAN_TYPE_TODAY) log.info('add voice call ban for restaurant {}'.format( restaurant_id)) voice_order.key_pressed = key_pressed return {'result': 'success'}
def update_status(): """ Get voice call's result asynchronously """ args = request.args if request.method == 'GET' else request.form log.info('Async results args: %s' % args.items()) call_id = int(args.get('userField')) result = int(args.get('result')) voice_call = VoiceCall.get(call_id) voice_call.call_status = RESULT_STATUS_MAP[result] # unlock restaurant if voice_call.call_status == VoiceCall.STATUS_FAILED: restaurant_id = VoiceCall.get(call_id).restaurant_id unlock(get_rst_lock_key(restaurant_id)) return {'result': 'success'}
def update_status(): """ Get voice call's result asynchronously """ args = request.args if request.method == 'GET' else request.form log.info('Async results args: %s' % args.items()) call_id = int(args.get('userField')) result = int(args.get('result')) voice_call = VoiceCall.get(call_id) voice_call.call_status = RESULT_STATUS_MAP[result] # unlock restaurant if voice_call.call_status == VoiceCall.STATUS_FAILED: restaurant_id = VoiceCall.get(call_id).restaurant_id unlock(get_rst_lock_key(restaurant_id)) return {'result': 'success'}
def voicecall_job(): """ get calls from database, and send call request """ not_dialed_calls = VoiceCall.get_by_status(VoiceCall.STATUS_NOT_DIAL) if not not_dialed_calls: return calls = _filter_calls(not_dialed_calls) if not calls: return for call in calls: # lock voice call if not lock(get_call_lock_key(call.id), time_out=30): continue # lock restaurant's line if lock(get_rst_lock_key(call.restaurant_id)): enqueue(BSTALK_TUBES['tube_vo'], voice_call_handler, call.id) else: unlock(get_call_lock_key(call.id))
def voicecall_job(): """ get calls from database, and send call request """ not_dialed_calls = VoiceCall.get_by_status(VoiceCall.STATUS_NOT_DIAL) if not not_dialed_calls: return calls = _filter_calls(not_dialed_calls) if not calls: return for call in calls: # lock voice call if not lock(get_call_lock_key(call.id), time_out=30): continue # lock restaurant's line if lock(get_rst_lock_key(call.restaurant_id)): enqueue(BSTALK_TUBES['tube_vo'], voice_call_handler, call.id) else: unlock(get_call_lock_key(call.id))
restaurant_id = VoiceCall.get(call_id).restaurant_id VoicecallBan.add(restaurant_id, VoicecallBan.BAN_TYPE_TODAY) log.info('add voice call ban for restaurant {}'.format(restaurant_id)) voice_order.key_pressed = key_pressed return {'result': 'success'} def call_end_handler(): """ get call end signal """ args = request.args if request.method == 'GET' else request.form try: call_id = int(args.get('userField')) except TypeError, e: log.error(e) return {'result': 'Error! Arguments is not correctly provided.'} log.info('voicecall end_call args is {}'.format(args.items())) voice_call = VoiceCall.get(call_id) restaurant_id = voice_call.restaurant_id lock_key = get_rst_lock_key(restaurant_id) result = unlock(lock_key) if not result: log.warn('Voice call to restaurant [id: {}] may be timed out'.format( restaurant_id)) return {'result': 'success'}
VoicecallBan.add(restaurant_id, VoicecallBan.BAN_TYPE_TODAY) log.info('add voice call ban for restaurant {}'.format( restaurant_id)) voice_order.key_pressed = key_pressed return {'result': 'success'} def call_end_handler(): """ get call end signal """ args = request.args if request.method == 'GET' else request.form try: call_id = int(args.get('userField')) except TypeError, e: log.error(e) return {'result': 'Error! Arguments is not correctly provided.'} log.info('voicecall end_call args is {}'.format(args.items())) voice_call = VoiceCall.get(call_id) restaurant_id = voice_call.restaurant_id lock_key = get_rst_lock_key(restaurant_id) result = unlock(lock_key) if not result: log.warn('Voice call to restaurant [id: {}] may be timed out'. format(restaurant_id)) return {'result': 'success'}