示例#1
0
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
示例#2
0
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
示例#3
0
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()
示例#4
0
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
示例#5
0
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
示例#6
0
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
示例#7
0
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)))
示例#9
0
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
示例#10
0
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
示例#11
0
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
示例#12
0
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
示例#13
0
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)
示例#14
0
 def __init__(self):
     self.notification = Notification()
     self.notification.created_at = current_millis()
示例#15
0
    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')))