def handle(self) -> None: print("Handling request from handler.") socket = self.request transceiver = Transceiver(socket) msg_bytes = transceiver.receive() try: request = Message.from_bytes(msg_bytes) request_data = request.data() print("Client address: {}.".format(socket.getpeername())) print("Request data:\n{}.".format(request_data)) if request_data["type"] == RequestType.LOGIN: reply = self.handle_login(request, socket.getpeername()[0]) else: if self.check_client_id(request, socket.getpeername()[0]): request_type = request_data["type"] reply = self.server.router[request_type](self, request) else: reply = self.__get_reply_message(False, "Access denied.") except: reply = self.__get_reply_message(False, "Invalid request.") transceiver.send(reply.to_bytes())
def handle_list_booked_appointments(self, request: Message) -> Message: client_id = request.data()["client_id"] provider_filter = lambda a: True ts_filter = lambda slot_info: (slot_info.owner == client_id and slot_info.state == TimeSlotState. RESERVED) return self._filter_appointments(provider_filter, ts_filter)
def handle_list_available_appointments(self, request: Message): provider = request.data()["service_provider"] if provider: provider_filter = lambda p: p.name() == provider else: provider_filter = lambda a: True ts_filter = lambda slot_info: slot_info.state == TimeSlotState.AVAILABLE return self._filter_appointments(provider_filter, ts_filter)
def handle_add_appointment_to_basket(self, request: Message) -> Message: request_data = request.data() client_id = request_data["client_id"] appointment = request_data["appointment"] ts_info = self._find_ts_info_for_appointment(appointment) if isinstance(ts_info, Message): return ts_info if ts_info.state == TimeSlotState.AVAILABLE: ts_info.state = TimeSlotState.IN_BASKET ts_info.owner = client_id return self.__get_reply_message(True, "OK.") return self.__get_reply_message(False, "Time slot not available.")
def handle_login(self, request: Message, ip_address: str) -> Message: request_data = request.data() username = request_data["username"] password = request_data["password"] user_list = list( filter(lambda user: user.username == username, self.server.server_state.users)) if user_list and user_list[0].password == password: user = user_list[0] self.server.server_state.connected_users[user.user_id] = ip_address reply = self.__get_reply_message(True, "Login successful.") reply.data()["client_id"] = user.user_id else: reply = self.__get_reply_message(False, "Invalid username or password.") return reply
def _handle_remove_or_cancel_appointment( self, request: Message, expected_state: TimeSlotState) -> Message: request_data = request.data() client_id = request_data["client_id"] appointment = request_data["appointment"] ts_info = self._find_ts_info_for_appointment(appointment) if isinstance(ts_info, Message): return ts_info if ts_info.state != expected_state or ts_info.owner != client_id: error_msg = ("Appointment not reserved by you" if expected_state == TimeSlotState.RESERVED else "Appointment not in your basket.") return self.__get_reply_message(False, error_msg) ts_info.state = TimeSlotState.AVAILABLE return self.__get_reply_message(True, "OK.")
def handle_confirm_booking(self, request: Message): request_data = request.data() client_id = request_data["client_id"] provider_predicate = lambda a: True ts_predicate = lambda ts_info: ts_info.owner == client_id and ts_info.state == TimeSlotState.IN_BASKET appointments = self._filter_appointments_list(provider_predicate, ts_predicate) if not appointments: return self.__get_reply_message(False, "No appointments in basket.") for appointment in appointments: ts_info = self._find_ts_info_for_appointment(appointment) if isinstance(ts_info, Message): return ts_info ts_info.state = TimeSlotState.RESERVED return self.__get_reply_message(True, "OK.")
def check_client_id(self, request: Message, ip_address: str) -> bool: client_id = request.data()["client_id"] stored_ip = self.server.server_state.connected_users.get(client_id) return stored_ip == ip_address
def __get_reply_message(ok: bool, text: str) -> Message: msg_dict = {"OK": ok, "text": text} return Message(msg_dict)