def select_teacher(lesson_id, owner_id, user_id): lesson = Lesson.query.get(lesson_id) if lesson.status == LessonStatus.BIDDING \ or lesson.status == LessonStatus.FINISHED: raise BadRequestError(cause=ErrorCause.EXPIRED_LESSON_DEALING, extra_message='Lesson status is not dealing.') owner = lesson.owner if owner.id != owner_id: raise InsufficientPermissionError() selected_user = User.query.get(user_id) if selected_user is None: raise NoSuchElementError( extra_message='The selected User does not exist.') lesson_bidding = LessonBidding.query \ .filter(LessonBidding.lesson_id == lesson_id) \ .filter(LessonBidding.user_id == user_id).first() if lesson_bidding is None: raise NoSuchElementError(extra_message='User does not bid.') # 학생의 coin 값 차감 #subtract_coins(owner_id, # max(int((lesson.preferred_price - lesson_bidding.price) * 3), # CoinValueOfTransactionType.MIN_SELECT_USER), # TransactionType.SELECT_TEACHER) subtract_coins(owner_id, CoinValueOfTransactionType.MIN_SELECT_USER, TransactionType.SELECT_TEACHER) lesson.status = LessonStatus.FINISHED lesson.selected_user_id = selected_user.id lesson_bidding.is_selected = True if not is_checked_phone_number(owner_id, user_id): check = CheckPhoneNumber() check.user_id = owner_id check.checked_user_id = user_id check.created_at = current_millis() db.session.add(check) if not is_checked_phone_number(user_id, owner_id): check = CheckPhoneNumber() check.user_id = user_id check.checked_user_id = owner_id check.created_at = current_millis() db.session.add(check) db.session.commit() # 선택되지 않은 teacher들 coin 값 반환 unselected_biddings = LessonBidding.query \ .filter(LessonBidding.lesson_id == lesson_id) \ .filter(LessonBidding.user_id != user_id).all() for bidding in unselected_biddings: add_coins(bidding.user_id, CoinValueOfTransactionType.BIDDING, TransactionType.REFUND_FOR_UNSELECTED) add_notification(NotificationRequest().to( selected_user.id).on_user_selected(selected_user.id, lesson.id)) return selected_user
def request_auth_number(phone_number): """ 전화번호 인증을 위해 임의의 번호를 생성해 해당 전화번호로 문자를 보낸다. :param phone_number: :return: """ if phone_number is None: raise InvalidArgumentError(extra_message='Phone number must not be null.') auth_number = randint(1000, 9999) # sql event scheduler 를 통해 expire 한다. certificate = CertificatePhoneNumber() certificate.phone_number = phone_number certificate.auth_number = auth_number certificate.created_at = current_millis() certificate.created_time = datetime.utcnow() db.session.add(certificate) # send SMS sms_options = sms.SMSOptions() sms_options.key = current_app.config['COOL_SMS_KEY'] sms_options.secret = current_app.config['COOL_SMS_SECRET'] sms_options.message = '매칭튜터 인증번호는 {0} 입니다.'.format(auth_number) sms_options.to = phone_number.replace('-', '') sms_options.sender = current_app.config['COOL_SMS_SENDER'] status = sms.send_sms(sms_options) if not status: raise TemporarilyUnavailable() db.session.commit() return certificate
def add_coins(user_id, coins, transaction_type): user = User.query.get(user_id) if user is None: raise InvalidArgumentError(extra_message='User does not exist.') c_transaction = CoinTransaction() c_transaction.user_id = user.id c_transaction.transaction_type = transaction_type c_transaction.value = coins c_transaction.created_at = current_millis() user.coins = user.coins + coins db.session.add(c_transaction) db.session.commit()
def create_lesson(user_id): if user_id is None: raise InvalidTokenError() user = User.query.get(user_id) if user.type != UserType.STUDENT: raise InvalidArgumentError( extra_message='It can be available only by student.') lesson = Lesson.query \ .filter((Lesson.status == LessonStatus.BIDDING) | (Lesson.status == LessonStatus.DEALING)) \ .filter(Lesson.owner_id == user_id).first() if lesson is not None: raise ElementAlreadyExists(extra_message='Student already has lesson.') student = user.student lesson = Lesson() lesson.owner_id = user.id lesson.status = LessonStatus.BIDDING current_time = current_millis() lesson.created_at = current_time lesson.created_time = datetime.utcnow() lesson.email = user.email lesson.name = user.name lesson.gender = user.gender lesson.phone_number = user.phone_number lesson.birth_year = user.birth_year lesson.zip_code = user.zip_code lesson.address = user.address lesson.sido = user.sido lesson.sigungu = user.sigungu lesson.bname = user.bname lesson.latitude = user.latitude lesson.longitude = user.longitude lesson.student_status = student.student_status lesson.grade = student.grade lesson.department = student.department lesson.level = student.level lesson.class_available_count = student.class_available_count lesson.class_time = student.class_time lesson.class_type = student.class_type lesson.preferred_gender = student.preferred_gender lesson.preferred_price = student.preferred_price lesson.description = student.description lesson.available_subjects = [] for subject in student.available_subjects: lesson.available_subjects.append(subject) lesson.available_days_of_week = [] for day_of_week in student.available_days_of_week: lesson.available_days_of_week.append(day_of_week) db.session.add(lesson) db.session.commit() add_notification(NotificationRequest().to(user_id).on_start_bidding( lesson.id)) return lesson
def add_gcm(user_id, key): if key is None: raise InvalidArgumentError(extra_message='GCM key must not be null.') gcm = UserGCM.query\ .filter(UserGCM.user_id == user_id)\ .filter(UserGCM.key == key).first() if gcm is not None: return gcm gcm = UserGCM() gcm.user_id = user_id gcm.key = key gcm.created_at = current_millis() db.session.add(gcm) db.session.commit() return gcm
def add_favorite(from_user_id, to_user_id): favorite = get_favorite(from_user_id, to_user_id) if favorite is not None: raise ElementAlreadyExists(extra_message='Already favorites.') if User.query.get(from_user_id) is None or User.query.get( to_user_id) is None: raise NoSuchElementError(extra_message='User does not exist.') favorite = UserFavorite() favorite.from_user_id = from_user_id favorite.to_user_id = to_user_id favorite.created_at = current_millis() db.session.add(favorite) add_notification(NotificationRequest().to(to_user_id).on_user_favorited( to_user_id, from_user_id)) db.session.commit() return favorite
def add_lesson_favorite(lesson_id, user_id): lesson_favorite = LessonFavorite.query \ .filter(LessonFavorite.lesson_id == lesson_id) \ .filter(LessonFavorite.user_id == user_id).first() if lesson_favorite is not None: raise ElementAlreadyExists( extra_message='Lesson Favorite already exists.') lesson = Lesson.query.get(lesson_id) lesson_favorite = LessonFavorite() lesson_favorite.lesson_id = lesson_id lesson_favorite.user_id = user_id lesson_favorite.created_at = current_millis() db.session.add(lesson_favorite) add_notification(NotificationRequest().to( lesson.owner_id).on_lesson_favorited(lesson_id, user_id)) db.session.commit() return lesson_favorite
def send_push(notification): user_gcms = UserGCM.query.filter( UserGCM.user_id == notification.user_id).all() api_key = current_app.config['GCM_API_KEY'] data_dto = GCMDataDTO(user_id=notification.user_id, message=get_message(notification.type, notification.words), deep_link=None, icon_url=None, created_at=current_millis()) notification_dto = GCMNotificationDTO(title=None, text=get_message( notification.type, notification.words)) for user_gcm in user_gcms: gcm_dto = GCMDTO(to=user_gcm.key, data=data_dto) internal_send_push( gcm_service.GCMOptions(api_key=api_key, data=vars(gcm_dto)))
def check_phone_number(user_id, checked_user_id): user = User.query.get(user_id) checked_user = User.query.get(checked_user_id) if user is None or checked_user is None: raise NoSuchElementError(extra_message='User does not exist.') check = get_check_phone_number(user_id, checked_user_id) if check is not None: return checked_user # 전화번호를 확인하면 coin을 차감한다. subtract_coins(user_id, CoinValueOfTransactionType.CHECK_USER_PHONE_NUMBER, TransactionType.CHECK_USER_PHONE_NUMBER) check = CheckPhoneNumber() check.user_id = user_id check.checked_user_id = checked_user_id check.created_at = current_millis() db.session.add(check) db.session.commit() return checked_user
def coin_purchase(): """ :return: :error WRONG_RECEIPT ELEMENT_ALREADY_EXISTS """ try: user_data = auth_service.check_permission() coin_service.charge_coins(user_data.get('id'), Receipt(request_json=request.get_json())) logger.debug( LogItem(who=WhoLogItem(request=request), what=WhatLogItem(object_type=ObjectType.PAYMENT), when=WhenLogItem(millis=current_millis()), how=HowLogItem(action='COIN_PURCHASE')).__dict__) except: logger.error(traceback.format_exc()) raise return True, None
def add_lesson_bidding(lesson_id, user_id, bidding_request): lesson = Lesson.query.get(lesson_id) if lesson is None: raise NoSuchElementError(extra_message='Lesson is not existed.') if lesson.status != LessonStatus.BIDDING: raise BadRequestError(cause=ErrorCause.EXPIRED_LESSON_BIDDING, message='Lesson is expired.') user = User.query.get(user_id) if user.type != UserType.TEACHER: raise InvalidArgumentError( extra_message='It can be available only by teacher.') bidding = LessonBidding.query \ .filter(LessonBidding.lesson_id == lesson_id) \ .filter(LessonBidding.user_id == user.id).first() if bidding is not None: raise ElementAlreadyExists(extra_message='Already bidding.') bidding = LessonBidding() bidding.lesson_id = lesson.id bidding.user_id = user.id if bidding_request is None: raise InvalidArgumentError( extra_message='Bidding price must not be null.') price = StringUtils.to_int(bidding_request.price) if price is None: raise InvalidArgumentError(extra_message='Price is wrong.') bidding.price = price bidding.created_at = current_millis() db.session.add(bidding) db.session.commit() # 선생님은 입찰할 때마다 coin을 차감시킨다. subtract_coins(user_id, CoinValueOfTransactionType.BIDDING, TransactionType.BIDDING) add_notification(NotificationRequest().to( lesson.owner.id).on_bidding_lesson(user_id, lesson.id)) return bidding
def certify_auth_number(phone_number, auth_number): """ 전화번호 인증을 위해 임의의 번호를 할당했는지 인증하는 과정 :param phone_number: :param auth_number: :return: """ if phone_number is None or auth_number is None: raise InvalidArgumentError(extra_message='Phone number or auth number must not be null.') certificate = CertificatePhoneNumber.query \ .filter(CertificatePhoneNumber.phone_number == phone_number) \ .filter(CertificatePhoneNumber.auth_number == auth_number).first() if certificate is None: raise BadRequestError(cause=ErrorCause.INVALID_CERTIFICATION, message='It is wrong certification.') if certificate.created_at + current_app.config['CERTIFY_PHONE_NUMBER_EXPIRES_IN'] < current_millis(): raise BadRequestError(cause=ErrorCause.INVALID_CERTIFICATION, message='Certification is expired.') db.session.delete(certificate) db.session.commit() return
def sign_up(sign_up_request): user_type = sign_up_request.user_type if user_type is None or not (user_type == UserType.STUDENT or user_type == UserType.TEACHER): raise InvalidArgumentError(extra_message='User type is wrong.') email_credential = sign_up_request.email_credential student_basic_information = sign_up_request.student_basic_information student_lesson_information = sign_up_request.student_lesson_information teacher_basic_information = sign_up_request.teacher_basic_information teacher_lesson_information = sign_up_request.teacher_lesson_information if email_credential is None or not email_credential.is_valid_form(): raise InvalidArgumentError(extra_message='Email credential is wrong.') user = User.query.filter_by(email=email_credential.email).first() if user is not None: raise ElementAlreadyExists(extra_message='Email is already existed.') user = User() user.email = email_credential.email user.password = email_credential.password user.profile_photos = sign_up_request.default_profile_photos current_time = current_millis() try: if user_type == UserType.STUDENT: if student_basic_information is None or not student_basic_information.is_valid_form(): raise InvalidArgumentError(extra_message='Student basic information is wrong.') if student_lesson_information is None or not student_lesson_information.is_valid_form(): raise InvalidArgumentError(extra_message='Student lesson information is wrong.') user.type = UserType.STUDENT user.name = student_basic_information.name user.gender = student_basic_information.gender user.phone_number = student_basic_information.phone_number user.birth_year = student_basic_information.birth_year location = student_basic_information.location user.zip_code = location.zip_code user.address = location.address user.sido = location.sido user.sigungu = location.sigungu user.bname = location.bname user.latitude = location.latitude user.longitude = location.longitude db.session.add(user) db.session.flush() student = Student() student.user_id = user.id student.student_status = student_basic_information.student_status student.grade = student_basic_information.grade student.department = student_basic_information.department student.available_subjects = [] for subject_id in student_lesson_information.subjects: saved_subject = Subject.query.get(subject_id) if saved_subject is not None: student.available_subjects.append(saved_subject) student.available_days_of_week = [] for day_of_week in student_lesson_information.days_of_week: saved_day_of_week = DayOfWeek.query.filter_by(name=day_of_week).first() if saved_day_of_week is not None: student.available_days_of_week.append(saved_day_of_week) student.class_available_count = student_lesson_information.class_available_count student.class_time = student_lesson_information.class_time student.preferred_gender = student_lesson_information.preferred_gender student.preferred_price = student_lesson_information.preferred_price student.class_type = student_lesson_information.class_type student.level = student_lesson_information.level student.description = student_lesson_information.description student.created_at = current_time db.session.add(student) elif user_type == UserType.TEACHER: if teacher_basic_information is None or not teacher_basic_information.is_valid_form(): raise InvalidArgumentError(extra_message='Teacher basic information is wrong.') if teacher_lesson_information is None or not teacher_lesson_information.is_valid_form(): raise InvalidArgumentError(extra_message='Teacher lesson information is wrong.') user.type = UserType.TEACHER user.name = teacher_basic_information.name user.gender = teacher_basic_information.gender user.phone_number = teacher_basic_information.phone_number user.birth_year = teacher_basic_information.birth_year location = teacher_basic_information.location user.zip_code = location.zip_code user.address = location.address user.sido = location.sido user.sigungu = location.sigungu user.bname = location.bname user.latitude = location.latitude user.longitude = location.longitude db.session.add(user) db.session.flush() teacher = Teacher() teacher.user_id = user.id teacher.university = teacher_basic_information.university teacher.university_rank = teacher_basic_information.university_rank teacher.university_status = teacher_basic_information.university_status teacher.major = teacher_basic_information.major teacher.available_subjects = [] for subject_id in teacher_lesson_information.subjects: saved_subject = Subject.query.get(subject_id) if saved_subject is not None: teacher.available_subjects.append(saved_subject) teacher.available_days_of_week = [] for day_of_week in teacher_lesson_information.days_of_week: saved_day_of_week = DayOfWeek.query.filter_by(name=day_of_week).first() if saved_day_of_week is not None: teacher.available_days_of_week.append(saved_day_of_week) teacher.class_available_count = teacher_lesson_information.class_available_count teacher.class_time = teacher_lesson_information.class_time teacher.preferred_gender = teacher_lesson_information.preferred_gender teacher.preferred_price = teacher_lesson_information.preferred_price teacher.career = teacher_lesson_information.career teacher.description = teacher_lesson_information.description teacher.created_at = current_time db.session.add(teacher) except Exception as error: db.session.rollback() raise error user.created_at = current_time user.coins = 10 db.session.commit() token = user.generate_auth_token(current_app.config['AUTH_TOKEN_EXPIRES_IN']) return SignUpResult(user=user, token=token)
def __init__(self): self.notification = Notification() self.notification.created_at = current_millis()
def __init__(self, lesson, **kwargs): self.id = lesson.id self.status = lesson.status self.created_at = lesson.created_at self.expires_in = 0 self.expired_at = 0 if lesson.status == LessonStatus.BIDDING: self.expires_in = lesson.created_at \ + current_app.config['LESSON_BIDDING_EXPIRES_IN'] \ - current_millis() self.expired_at = lesson.created_at \ + current_app.config['LESSON_BIDDING_EXPIRES_IN'] elif lesson.status == LessonStatus.DEALING: self.expires_in = lesson.created_at \ + current_app.config['LESSON_BIDDING_EXPIRES_IN'] \ + current_app.config['LESSON_DEALING_EXPIRES_IN'] \ - current_millis() self.expired_at = lesson.created_at \ + current_app.config['LESSON_BIDDING_EXPIRES_IN'] \ + current_app.config['LESSON_DEALING_EXPIRES_IN'] # 프로필 사진만 현재 유저의 사진을 내려준다. owner = lesson.owner self.profile_photos = owner.profile_photos self.email = lesson.email self.name = lesson.name self.gender = lesson.gender self.phone_number = lesson.phone_number self.birth_year = lesson.birth_year self.location = vars( Location({ 'address': lesson.address, 'zip_code': lesson.zip_code, 'sido': lesson.sido, 'sigungu': lesson.sigungu, 'bname': lesson.bname, 'latitude': lesson.latitude, 'longitude': lesson.longitude })) self.student_status = lesson.student_status self.grade = lesson.grade self.department = lesson.department self.level = lesson.level self.class_available_count = lesson.class_available_count self.class_time = lesson.class_time self.class_type = lesson.class_type self.preferred_gender = lesson.preferred_gender self.preferred_price = lesson.preferred_price self.description = lesson.description self.available_subjects = [] for subject in lesson.available_subjects: self.available_subjects.append(vars(SubjectDTO(subject))) self.available_days_of_week = [] for day_of_week in sorted_days_of_week_dto( lesson.available_days_of_week): self.available_days_of_week.append(day_of_week.name) self.is_favorited = False if kwargs.get('is_favorited') is not None and kwargs.get( 'is_favorited'): self.is_favorited = True self.is_bid = False if kwargs.get('is_bid') is not None and kwargs.get('is_bid'): self.is_bid = True if kwargs.get('users_bidding') is not None: self.bidding = vars( LessonBiddingDTO(kwargs.get('users_bidding'))) self.biddings_count = kwargs.get('biddings_count') self.owner = vars( UserDTO(owner, is_checked_phone_number=kwargs.get( 'is_checked_owner_phone_number'))) selected_user = lesson.selected_user if selected_user is not None: self.selected_user = vars( UserDTO(lesson.selected_user, is_checked_phone_number=kwargs.get( 'is_checked_selected_user_phone_number')))