def post(self): self.set_header("Content-Type", "application/json") uid = self.get_argument('uid', '') taking_time = self.get_argument('taking_time', 25) additional_time = self.get_argument('additional_time', 10) appointment_type = self.get_argument('appointment_type', 0) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) # convert appointment_type = int(appointment_type) have_pet = int(have_pet) taking_time = int(taking_time) additional_time = int(additional_time) taking_time_in_minutes = taking_time * 6 additional_time_in_minutes = additional_time * 6 total_taking_time_in_minutes = taking_time_in_minutes + additional_time_in_minutes master_gender = int(master_gender) # 0 dont care 1 women 2 men isdirty = int(isdirty) ret = {} print 'recommend schedule' print 'taking time :', taking_time_in_minutes mongo_logger = get_mongo_logger() mongo_logger.debug('%s request recommendation' % uid, extra={ 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty }) mix = get_mixpanel() try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() # request id to group each individual bookings request_id = str(uuid.uuid4()) # get user's address and cover address to gu code address, geohash5, geohash6 = userdao.get_user_address(uid) gu_id = addrdao.get_gu_id(address) start_time_range_begin = 8 start_time_range_end = 18 # 똥집인 경우 3시간 추가됨. if isdirty == 1: if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: total_taking_time_in_minutes += 120 #get available homemaster's time table day by day schedule_by_date_list = masterdao.get_recommended_schedule( gu_id, have_pet, master_gender, appointment_type, geohash6, dt.datetime.now().date()) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ None, \ start_time_range_begin, \ 0, start_time_range_end, \ 0, total_taking_time_in_minutes, \ geohash6, True) # if not successful if success != 'SUCCESS': print 'haha no recommendation.....' self.set_status(Response.RESULT_OK) ret['response'] = 'NoRecommendation' mongo_logger.error('have no recommendation', extra={'err': msg}) #add_err_message_to_response(ret, err_dict['err_hm_no_recommendation']) #self.write(json.dumps(ret)) return else: schedules = [] for row in result: s = {} s['date'] = row['date'] s['start_time'] = time_to_str(row['start_time']) s['end_time'] = time_to_str(row['end_time']) schedules.append(s) # 스케쥴이 이미 해당 날짜에 있다면, 있다고 표시하고 리턴함 num_schedules_on_dates = userdao.get_user_schedule_on_dates( uid, [ dt.datetime.strptime(str(s['date']), '%Y%m%d').date() for s in schedules ]) if num_schedules_on_dates > 0: print 'already have appointment on that days, no recommendation.....' holder.remove(store_key) for sk in search_keys: holder.remove(sk) self.set_status(Response.RESULT_OK) ret['response'] = 'NoRecommendation' mongo_logger.error( 'have no recommendation', extra={'err': 'already have cleaning on that day'}) #add_err_message_to_response(ret, err_dict['err_hm_no_recommendation']) #self.write(json.dumps(ret)) return mid = row['mid'] name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating( mid) search_keys_str = ','.join(search_keys) print 'search key string :', search_keys_str ret['response'] = { 'store_key': store_key, 'search_keys': search_keys_str, 'schedules': schedules, 'uid': uid, 'mid': row['mid'], 'name': name, 'img_url': img_url, 'avg_rating': str(float(avg_rating)) } mix.track(uid, 'recommend', { 'time': dt.datetime.now(), 'master_gender': master_gender }) mongo_logger.debug('%s got recommendation' % uid, extra={'user_id': uid}) self.set_status(Response.RESULT_OK) print uid, 'got recommendation ' self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() print_err_detail(e) self.set_status(Response.RESULT_SERVERERROR) add_err_message_to_response(ret, err_dict['err_mysql']) mongo_logger.error('error occurred when make recommendation', extra={'err': str(e)}) # if error occur, then remove all keys holder.remove(store_key) for sk in search_keys: holder.remove(sk)
def post(self): self.set_header("Content-Type", "application/json") self.set_header('Access-Control-Allow-Origin', '*') ret = {} uid = self.get_argument('uid', '') appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) additional_task = self.get_argument('additional_task', 0) date = self.get_argument('date', dt.datetime.strftime(dt.datetime.now(), '%Y%m%d')) time = self.get_argument('time', '08:00') taking_time = self.get_argument('taking_time', 25) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 10) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) master_ids = self.get_argument('master_ids', []) # convert parameters selected_date_str = date selected_date = dt.datetime.strptime(date, '%Y%m%d') master_ids = master_ids.split(',') appointment_type = int(appointment_type) additional_task = int(additional_task) taking_time = int(taking_time) first_added_time = int(first_added_time) additional_time = int(additional_time) have_pet = int(have_pet) master_gender = int(master_gender) # 0 dont care 1 women isdirty = int(isdirty) print additional_task, type(additional_task) if additional_task > 64: # ios typo bug temporary fix additional_task = str(additional_task) additional_task = int(additional_task, 2) if additional_task >= 64: additional_task -= 64 taking_time_in_minutes = taking_time first_added_time_in_minutes = first_added_time additional_time_in_minutes = additional_time total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes print '*' * 50 print additional_task print '*' * 50 if isdirty == 1: total_taking_time_in_minutes += 120 # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() try: booking_info = {} masterdao = MasterDAO() holder = IntermediateValueHolder() cal_appointment_type = appointment_type if cal_appointment_type == BC.ONE_TIME_BUT_CONSIDERING: cal_appointment_type = BC.ONE_TIME count_of_iteration = cal_appointment_type * 2 + 1 # 2 months date_list = [] if cal_appointment_type == BC.ONE_TIME: week_const = 0 else: week_const = 4 / cal_appointment_type for i in xrange(count_of_iteration): date = selected_date + dt.timedelta(weeks = week_const * i) date = dt.datetime.strftime(date, '%Y%m%d') date_list.append(date) booking_info['dates'] = date_list booking_info['time'] = time booking_info['appointment_type'] = appointment_type booking_info['additional_task'] = additional_task booking_info['have_pet'] = have_pet booking_info['master_gender'] = master_gender booking_info['isdirty'] = isdirty booking_info['user_id'] = uid booking_info['taking_time'] = taking_time_in_minutes booking_info['first_added_time'] = first_added_time_in_minutes booking_info['additional_time'] = additional_time_in_minutes booking_info['total_time'] = total_taking_time_in_minutes # 각 마스터별로 예약이 가능한지 메모리에서 다시 한번 확인. # 선택한 값을 메모리에 키로 저장하여 중복되는 예약 방지. # 선택 했으면 선택된 정보를 가지고 있어야 함 master_num = len(master_ids) i = 0 while i < master_num: # 랭킹이 높은 홈마스터별로 확인 mid = master_ids[i] master_date_keys = [] name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating(mid) booking_info['master_id'] = mid booking_info['name'] = name booking_info['img_url'] = img_url booking_info['avg_rating'] = avg_rating # 날짜별 키 생성 for date in date_list: key = '%s_%s' % (mid, date) master_date_keys.append(key) # 저장할 키 생성 booking_item_key = '%s_%s_%d' % (uid, master_date_keys[0], appointment_type) # 가능 일정을 미리 호출한 고객과, 그 바로 직후 휴무 신청을 한 홈마스터의 경우, 예약이 불가 하기 때문에 체크하도록 함 if holder.store_keys(master_date_keys) and not masterdao.is_master_off_date(mid, selected_date.date()): # 메모리에 키가 하나도 없을 때, 즉 예약이 가능할 때 holder.store(booking_item_key, booking_info) master_date_keys = ','.join(master_date_keys) booking_info['search_keys'] = master_date_keys booking_info['store_key'] = booking_item_key ret['response'] = booking_info self.set_status(Response.RESULT_OK) # log to mixpanel mix.track(uid, 'select schedule', {'time' : dt.datetime.now(), 'user_id' : uid, 'master_id' : mid, 'sel_date' : selected_date_str, 'sel_time' : time, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # log to mongo mongo_logger.debug('select schedule', extra = {'user_id' : uid, 'master_id' : mid, 'sel_date' : selected_date_str, 'sel_time' : time, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) return i += 1 # when not available # log to mixpanel mix.track(uid, 'cannot select schedule admin', {'time' : dt.datetime.now(), 'user_id' : uid, 'sel_date' : selected_date_str, 'sel_time' : time, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # log to mongo mongo_logger.debug('cannot select schedule admin', extra = {'log_time' : dt.datetime.now(), 'user_id' : uid, 'sel_date' : selected_date_str, 'sel_time' : time, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # other users preempt homemasters, so no homemaster available self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_homemaster_occupied']) return except Exception, e: add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error request select schedules', extra = {'user_id' : uid, 'err' : str(e)})
def post(self): self.set_header("Content-Type", "application/json") ret = {} uid = self.get_argument('uid', '') date = self.get_argument('date', dt.datetime.now()) start_time_range_begin = self.get_argument('range_begin', BC.START_TIME_RANGE_BEGIN) start_time_range_begin_min = self.get_argument('range_begin_min', 0) start_time_range_end = self.get_argument('range_end', BC.START_TIME_RANGE_END) start_time_range_end_min = self.get_argument('range_end_min', 0) appointment_type = self.get_argument('appointment_type', BC.ONE_TIME) taking_time = self.get_argument('taking_time', 25) first_added_time = self.get_argument('first_added_time', 0) additional_time = self.get_argument('additional_time', 10) have_pet = self.get_argument('have_pet', 0) master_gender = self.get_argument('master_gender', 0) isdirty = self.get_argument('isdirty', 0) # convert datetime date = dt.datetime.strptime(date, '%Y%m%d') start_time_range_begin = int(start_time_range_begin) start_time_range_begin_min = int(start_time_range_begin_min) start_time_range_end = int(start_time_range_end) start_time_range_end_min = int(start_time_range_end_min) appointment_type = int(appointment_type) taking_time = int(taking_time) first_added_time = int(first_added_time) additional_time = int(additional_time) taking_time_in_minutes = taking_time * 6 first_added_time_in_minutes = first_added_time * 6 additional_time_in_minutes = additional_time * 6 total_taking_time_in_minutes = taking_time_in_minutes + first_added_time_in_minutes + additional_time_in_minutes have_pet = int(have_pet) master_gender = int(master_gender) # 0 dont care 1 women 2 men isdirty = int(isdirty) print 'request schedule' print 'taking time :', taking_time_in_minutes mongo_logger = get_mongo_logger() mongo_logger.debug('%s request schedule' % uid, extra={ 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_end': start_time_range_end, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty }) mix = get_mixpanel() try: session = Session() userdao = UserDAO() addrdao = AddressDAO() masterdao = MasterDAO() holder = IntermediateValueHolder() # request id to group each individual bookings request_id = str(uuid.uuid4()) # get user's address and cover address to gu code address, geohash5, geohash6 = userdao.get_user_address(uid) gu_id = addrdao.get_gu_id(address) # four consecutive appointment days to make booking if regular , otherwise just one day dates = [int(dt.datetime.strftime(date, '%Y%m%d'))] if appointment_type == BC.ONE_TIME_A_MONTH or appointment_type == BC.TWO_TIME_A_MONTH or appointment_type == BC.FOUR_TIME_A_MONTH: dates = [ int( dt.datetime.strftime( date + dt.timedelta(days=i * BC.DAYS_IN_A_WEEK * (4 / appointment_type)), '%Y%m%d')) for i in xrange(4) ] # 크리스마스 및 새해 임시로 막음. if date.date() == dt.date(2016, 2, 7) or date.date() == dt.date( 2016, 2, 8) or date.date() == dt.date( 2016, 2, 9) or date.date() == dt.date(2016, 2, 10): self.set_status(Response.RESULT_OK) add_err_ko_message_to_response(ret, '설날 연휴동안은, 예약이 불가능합니다.') self.write(json.dumps(ret)) return # 스케쥴이 이미 해당 날짜에 있다면, 있다고 표시하고 리턴함 num_schedules_on_dates = userdao.get_user_schedule_on_dates( uid, [dt.datetime.strptime(str(d), '%Y%m%d').date() for d in dates]) if num_schedules_on_dates > 0: self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_schedules_on_dates']) self.write(json.dumps(ret)) return # 똥집인 경우 3시간 추가됨. if isdirty == 1: if appointment_type == BC.ONE_TIME or appointment_type == BC.ONE_TIME_BUT_CONSIDERING: total_taking_time_in_minutes += 120 print 'gu_id', gu_id, have_pet, master_gender, dates #get available homemaster's time table day by day schedule_by_date_list = masterdao.get_master_schedule_by_dates( gu_id, have_pet, master_gender, dates) success, msg, store_key, search_keys, result = masterdao.find_master_by_score(schedule_by_date_list, \ gu_id, \ uid, \ appointment_type, \ dates, \ start_time_range_begin, \ start_time_range_begin_min, \ start_time_range_end, \ start_time_range_end_min, \ total_taking_time_in_minutes, \ geohash6) # if not successful if success != 'SUCCESS': self.set_status(Response.RESULT_OK) add_err_message_to_response(ret, err_dict['err_no_hm_at_that_time']) mix.track( uid, 'request schedule', { 'time': dt.datetime.now(), 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_begin_min': start_time_range_begin_min, 'start_time_range_end': start_time_range_end, 'start_time_range_end_min': start_time_range_end_min, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty, 'status': 'no homemaster' }) print uid, 'was not able to find any homemasters....' else: schedules = [] for row in result: s = {} s['date'] = row['date'] s['start_time'] = time_to_str(row['start_time']) s['end_time'] = time_to_str(row['end_time']) schedules.append(s) mid = row['mid'] name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating( mid) search_keys_str = ','.join(search_keys) ret['response'] = { 'store_key': store_key, 'search_keys': search_keys_str, 'schedules': schedules, 'uid': uid, 'mid': row['mid'], 'name': name, 'img_url': img_url, 'avg_rating': str(float(avg_rating)) } print uid, 'successfully made booking requests...' mix.track( uid, 'request schedule', { 'time': dt.datetime.now(), 'date': dt.datetime.strftime(date, '%Y%m%d'), 'start_time_range_begin': start_time_range_begin, 'start_time_range_begin_min': start_time_range_begin_min, 'start_time_range_end': start_time_range_end, 'start_time_range_end_min': start_time_range_end_min, 'taking_time': taking_time, 'additional_time': additional_time, 'appointment_type': appointment_type, 'have_pet': have_pet, 'master_gender': master_gender, 'isdirty': isdirty, 'status': 'find homemaster' }) mongo_logger.debug('%s made booking requests' % uid, extra={'user_id': uid}) self.set_status(Response.RESULT_OK) except Exception, e: session.rollback() add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error occurred when request schedule', extra={'err': str(e)}) # if error occur, then remove all keys holder.remove(store_key) for sk in search_keys: holder.remove(sk)
def post(self): self.set_header("Content-Type", "application/json") ret = {} date = self.get_argument('date', dt.datetime.strftime(dt.datetime.now(), '%Y%m%d')) time = self.get_argument('start_time', '08:00') master_ids = self.get_argument('master_ids', []) comb_key = self.get_argument('comb_key', '') # convert parameters selected_date_str = date selected_date = dt.datetime.strptime(date, '%Y%m%d') master_ids = master_ids.split(',') keys = comb_key.split('_') # logging part mix = get_mixpanel() mongo_logger = get_mongo_logger() try: booking_info = {} masterdao = MasterDAO() holder = IntermediateValueHolder() print comb_key appointment_type = int(comb_key.split('_')[2]) date_list = [] if appointment_type == BC.ONE_TIME: count_of_iteration = 1 week_const = 0 else: count_of_iteration = appointment_type * 2 # 2 months week_const = 4 / appointment_type for i in xrange(count_of_iteration): date = selected_date + dt.timedelta(weeks = week_const * i) date = dt.datetime.strftime(date, '%Y%m%d') date_list.append(date) booking_info['dates'] = date_list booking_info['time'] = time booking_info['comb_key'] = comb_key house_type = comb_key.split('_')[0] if house_type == 'officetel': house_type = 0 elif house_type == 'rowhouse': house_type = 1 else: house_type = 2 house_type = int(house_type) house_size = int(comb_key.split('_')[1]) additional_task = int(comb_key.split('_')[3]) print comb_key print appointment_type, house_type, house_size _, cleaning_duration, _, _ = get_time_price(appointment_type, house_type, house_size) booking_info['cleaning_duration'] = cleaning_duration task_time, _ = get_additional_task_time_price(additional_task, house_type, house_size) booking_info['additional_time'] = task_time print task_time # 각 마스터별로 예약이 가능한지 메모리에서 다시 한번 확인. # 선택한 값을 메모리에 키로 저장하여 중복되는 예약 방지. # 선택 했으면 선택된 정보를 가지고 있어야 함 master_num = len(master_ids) i = 0 while i < master_num: # 랭킹이 높은 홈마스터별로 확인 mid = master_ids[i] master_date_keys = [] name, img_url, avg_rating = masterdao.get_master_name_img_and_average_rating(mid) booking_info['master_id'] = mid booking_info['name'] = name booking_info['img_url'] = img_url booking_info['avg_rating'] = avg_rating now = dt.datetime.strftime(dt.datetime.now(), '%Y%m%d%H%M%S') hashids = Hashids(min_length = 16, salt = now + comb_key) booking_id = hashids.encode(int(date + time.replace(':', ''))) booking_info['id'] = booking_id # 날짜별 키 생성 for date in date_list: key = '%s_%s' % (mid, date) master_date_keys.append(key) # 저장할 키 생성 #booking_item_key = '%s_%s' % (comb_key, master_date_keys[0]) if holder.store_keys(master_date_keys, source = '11st') and not masterdao.is_master_off_date(mid, selected_date.date()): # 메모리에 키가 하나도 없을 때, 즉 예약이 가능할 때 master_date_keys = ','.join(master_date_keys) booking_info['search_keys'] = master_date_keys booking_info['store_key'] = booking_id # 11번가의 경우는, 미리 생성한 아이디 키로 한다. holder.store(booking_id, booking_info, source = '11st') # for 11st response ret['response'] = {'booking_available' : 'Y', 'booking_id' : booking_id} self.set_status(Response.RESULT_OK) # log to mixpanel #mix.track(uid, '11 select schedule', {'time' : dt.datetime.now(), 'user_id' : uid, 'master_id' : mid, 'sel_date' : selected_date_str, 'sel_time' : time, 'taking_time' : taking_time, 'additional_time' : additional_time, 'appointment_type' : appointment_type, 'have_pet' : have_pet, 'master_gender' : master_gender,'isdirty' : isdirty}) # log to mongo mongo_logger.debug('11 select schedule', extra = {'master_id' : mid, 'sel_date' : selected_date_str, 'sel_time' : time, 'comb_key' : comb_key}) return i += 1 # when not available # log to mongo mongo_logger.debug('11 cannot select schedule', extra = {'sel_date' : selected_date_str, 'sel_time' : time, 'comb_key' : comb_key}) # other users preempt homemasters, so no homemaster available self.set_status(Response.RESULT_OK) ret['response'] = {'booking_available' : 'N'} return except Exception, e: add_err_message_to_response(ret, err_dict['err_mysql']) self.set_status(Response.RESULT_SERVERERROR) print_err_detail(e) mongo_logger.error('error 11 request select schedules', extra = {'err' : str(e)})