def delete_student_photo(student_id: int): """ delete student photo """ if not student_id: current_app.logger.error("Empty url or empty student id") return post_request_empty() student = student_service.get_student_by_id(student_id) try: if not student: raise ThingahaCustomError("Invalid student id.") if student["photo"] is None: raise ThingahaCustomError( "Cannot delete photo that doesn't exist anymore.") result = student_service.delete_file( student["photo"]) and student_service.update_photo_path_by_id( student_id, "") if result: current_app.logger.info("Delete file for URL %s success", student["photo"]) return "", 200 else: current_app.logger.error("Delete file for URL %s fail", student["photo"]) return "", 400 except TypeError: current_app.logger.error("Student id must be integer") return custom_error("Student id must be integer") except SQLCustomError as error: current_app.logger.error("Error for student photo delete {}".format( error.__dict__)) return custom_error("Error updating student photo.")
def delete_s3_file(): """ delete S3 file """ data = request.get_json() url = data.get("url") student_id = data.get("student_id") if not url or not student_id: current_app.logger.error("Empty url or empty student id") return post_request_empty() try: if int(student_id) not in StudentService.get_all_student_ids(): raise ThingahaCustomError("Invalid student ID") result = student_service.delete_file( url) and student_service.update_photo_path_by_id(student_id, "") if result: current_app.logger.info("Delete file for URL %s success", url) return "", 200 else: current_app.logger.error("Delete file for URL %s fail", url) return "", 400 except TypeError: current_app.logger.error("Student id must be integer") return custom_error("Student id must be integer")
def get_all_addresses( self, page: int = 1, per_page: int = 20, address_type: str = None) -> (List[Dict[str, Any]], int): """ get all addresses :params page int :params per_page int :params address_type int :return: """ try: if address_type: addresses, address_records = self.__return_address_types( page, per_page, address_type) else: addresses = AddressModel.get_all_addresses(page, per_page) address_records = self.__get_all_address_records(addresses) if address_records is None: self.logger.error( "Address type should be school or user or student") raise ThingahaCustomError( "Address type should be school or user or student") return self.__return_addresses_with_format(addresses, address_records) except SQLAlchemyError: self.logger.error("Get all addresses fail. error %s", traceback.format_exc()) raise SQLCustomError(description="GET address SQL ERROR")
def custom_error(error_message: str, status_code: int = 400): """ helper function for custom error with status code return return :param error_message: :param status_code: :return: """ return jsonify({"errors": [ThingahaCustomError(error_message).__dict__]}), status_code
def change_password(self, user_id: int, data: Dict[str, str]) -> bool: """ change password by user :params user_id :params data """ if not self.input_validate.validate_json(data, password_change_schema): self.logger.error("Change password validation fail") raise ValidateFail("Change password validation fail") current_pwd = data.get("current_password") new_pwd = data.get("new_password") new_confirm_pwd = data.get("new_confirm_password") user = self.get_user_model_by_id(user_id) if not self.check_password(current_pwd, user): raise ThingahaCustomError("Current password is incorrect.") if new_pwd == new_confirm_pwd: return self.change_password_by_id(user_id, new_pwd) self.logger.error("Password and confirm password are different") raise ThingahaCustomError( "Password and confirm password are different")
def upload_s3_file(): """ Upload a file to an S3 bucket :return: True if file was uploaded, else False """ img = request.files.get("img") student_id = request.form.get("student_id") try: if student_id and int( student_id) not in StudentService.get_all_student_ids(): raise ThingahaCustomError("Invalid student ID") if student_id is None or not img or img.filename == "": return post_request_empty() file_extension = student_service.allowed_file(img.filename) if not file_extension: return custom_error( "File extension should be .png or .jpg or .jpeg") file_name = student_id + "." + file_extension result = student_service.upload_file(img, file_name) if result: url = get_s3_url().format(S3_BUCKET, file_name) if student_service.update_photo_path_by_id(student_id, url): return get_student_by_id(student_id), 200 else: current_app.logger.error( "Can't update student photo url for student id: {}".format( student_id)) return "", 400 except ThingahaCustomError as error: current_app.logger.error("Error for student photo upload {}".format( error.__dict__)) return jsonify({"errors": [error.__dict__]}), 400 except (ValueError, TypeError): current_app.logger.error( "Value error for student photo upload error: {}".format( traceback.format_exc())) return jsonify({ "errors": [ThingahaCustomError("Student ID must be integer").__dict__] }), 400
def create_student(): """ create student by post body :return: """ data, photo = get_student_data_from_request(request) if data is None: return post_request_empty() try: address_data = address_service.thingaha_helper.parse_address_data( data) if data.get('address[division]') else get_default_address() address_id = address_service.create_address( { "division": address_data.get("division"), "district": address_data.get("district"), "township": address_data.get("township"), "street_address": address_data.get("street_address"), "type": "student" }, True) if not address_id: raise ThingahaCustomError("Student address create fail") student_id = student_service.create_student({ "name": data.get("name"), "deactivated_at": None if data.get("active") else student_service.thingaha_helper.get_now(), "birth_date": student_service.thingaha_helper.standardize_str_to_date( data.get("birth_date")), "father_name": data.get("father_name"), "mother_name": data.get("mother_name"), "gender": data.get("gender"), "parents_occupation": data.get("parents_occupation"), "photo": photo, "address_id": address_id }) current_app.logger.info("Create student success. student_name %s", data.get("name")) return get_student_by_id(student_id), 200 except (RequestDataEmpty, SQLCustomError, ValidateFail, ThingahaCustomError, ValueError) as error: current_app.logger.error( f"Create student request fail.{traceback.format_exc()}") return jsonify({"errors": [error.__dict__]}), 400
def create_student(): """ create student by post body :return: """ data = request.get_json() if data is None: return post_request_empty() try: address_data = data.get("address") if data.get( "address") else get_default_address() address_id = address_service.create_address( { "division": address_data.get("division"), "district": address_data.get("district"), "township": address_data.get("township"), "street_address": address_data.get("street_address"), "type": "student" }, flush=True) if not address_id: raise ThingahaCustomError("Student address create fail") student_id = student_service.create_student({ "name": data.get("name"), "deactivated_at": None if data.get("active") else datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "birth_date": data.get("birth_date"), "father_name": data.get("father_name"), "mother_name": data.get("mother_name"), "parents_occupation": data.get("parents_occupation"), "photo": data.get("photo"), "address_id": address_id }) current_app.logger.info("Create student success. student_name %s", data.get("name")) return get_student_by_id(student_id), 200 except (RequestDataEmpty, SQLCustomError, ValidateFail, ThingahaCustomError) as error: current_app.logger.error("Create student request fail") return jsonify({"errors": [error.__dict__]}), 400
def create_user(): """ create user by post body :return: """ data = request.get_json() if data is None: return post_request_empty() try: address_data = data.get("address") if data.get( "address") else get_default_address() address_id = address_service.create_address( { "division": address_data.get("division"), "district": address_data.get("district"), "township": address_data.get("township"), "street_address": address_data.get("street_address"), "type": "user" }, flush=True) if not address_id: raise ThingahaCustomError("User address create fail") user_id = user_service.create_user({ "username": data.get("username"), "display_name": data.get("display_name"), "email": data.get("email"), "address_id": address_id, "password": data.get("password"), "role": data.get("role"), "country": data.get("country"), "donation_active": True if data.get("donation_active") else False }) current_app.logger.info("Create user success. user_name %s", data.get("username")) return get_user_by_id(user_id) except (RequestDataEmpty, SQLCustomError, ValidateFail) as error: current_app.logger.error("Create user fail. user_name %s, error: %s", data.get("username"), error.description) return jsonify({"errors": [error.__dict__]}), 400
def create_school(): """ create school by post body :return: """ data = request.get_json() if data is None: return post_request_empty() address_data = data.get("address") if data.get( "address") else get_default_address() try: address_id = address_service.create_address( { "division": address_data.get("division"), "district": address_data.get("district"), "township": address_data.get("township"), "street_address": address_data.get("street_address"), "type": "school" }, flush=True) current_app.logger.debug("create address id: %s", address_id) if not address_id: raise ThingahaCustomError("Address create fail for school") school_id = school_service.create_school({ "name": data.get("name"), "contact_info": data.get("contact_info"), "photo": data.get("photo"), "address_id": address_id }) current_app.logger.info("Create school success. name %s", data.get("name")) return get_school_by_id(school_id) except (RequestDataEmpty, SQLCustomError, ValidateFail, ThingahaCustomError) as error: current_app.logger.error("Create school request fail") return jsonify({"errors": [error.__dict__]}), 400
def get_donation_by_id(self, donation_id: int) -> Optional[Dict]: """ get donation info by id :param donation_id: :return: donation list of dict """ try: donation_record = DonationModel.get_donation_by_id(donation_id) if donation_record: donation, user, student = donation_record self.logger.info("Get donation info by donation_id:{}".format(donation_id)) return donation.donation_dict(user, student) else: self.logger.error("Fail to get donation info by donation_id:{}".format(donation_id)) raise ThingahaCustomError(description="No record for requested donation id: {}".format(donation_id)) except SQLAlchemyError as error: self.logger.error("Error: {}".format(error)) raise SQLCustomError(description="GET Donation by ID SQL ERROR")
def __return_addresses_with_format( addresses: Pagination, address_records: Dict) -> Dict[str, List]: """ prepare return format for address get all API :params addresses :params address_records """ try: return { "addresses": [{ "id": address.id, "addressable": { "id": address_records[address.type][address.id].id, "name": address_records[address.type][address.id].username if address.type == "user" else address_records[address.type][address.id].name, "type": address.type }, "division": address.division, "district": address.district, "township": address.township, "street_address": address.street_address, } for address in addresses.items], "total_count": addresses.total, "current_page": addresses.page, "next_page": addresses.next_num, "prev_page": addresses.prev_num, "pages": addresses.pages } except KeyError: raise ThingahaCustomError("Address key mismatch error")