コード例 #1
0
async def RequestTeacher(request, token: Token, chat_id):
    user = token.jwt_identity

    # chat_id로 question_id 구할 수 있음
    chat = await request.app.db.chats.find_one({'_id': ObjectId(chat_id)})
    if not chat:
        abort(404)

    question = await request.app.db.questions.find_one(
        {'_id': ObjectId(chat['question_id'])})
    if not question:
        abort(500, message='question을 찾을 수 없음')

    mentor = await request.app.db.users.find_one(
        {'_id': ObjectId(question['user_id'])})
    if not mentor:
        abort(500, message='mentor를 찾을 수 없음')

    req = {
        'question_id': chat['question_id'],
        'chat_id': chat_id,
        'school': mentor['school'],
        'message': request.json['message'],
        'timestamp': int(time.time())
    }
    res = await request.app.db.teachers.insert_one(req)
    if not res.acknowledged:
        abort(500)
    return res_json({})
コード例 #2
0
async def RequestOffline(request, token: Token, chat_id):
    user = token.jwt_identity
    # chat_id로 question_id 구할 수 있음
    chat = await request.app.db.chats.find_one({'_id': ObjectId(chat_id)})
    if not chat:
        abort(404)

    question = await request.app.db.questions.find_one(
        {'_id': ObjectId(chat['question_id'])})
    if not question:
        abort(500, message='question을 찾을 수 없음')
    if question['user_id'] == user['id']:
        # user is mentee
        sender = 'mentee'
    else:
        sender = 'mentor'

    # user_id로 sender 구하고, text 타입의 chat 만들어 저장
    chat = {
        'type': 'offline',
        'question_id': question['id'],
        'sender': sender,
        'message': request.json['message'],
        'timestamp': int(time.time()),
        'offline': {
            'time': request.json['time'],
            'place': request.json['place']
        }
    }
    res = await request.app.db.chats.insert_one(chat)
    if not res.acknowledged:
        abort(500)

    await sio.emit('update', {}, room=question['id'])
    return res_json({})
コード例 #3
0
async def QuestionView(request, token: Token, question_id):
    user = token.jwt_identity
    question = await request.app.db.questions.find_one({
        '_id': ObjectId(question_id)
    }, {'_id':False})
    if not question:
        abort(404)
    if question['user_id'] == user['id']:
        question['mine'] = True
    question['id'] = question_id
    question['user'] = await request.app.db.users.find_one({
            '_id': ObjectId(question['user_id'])
        }, {'_id': False})
    cursor = request.app.db.requests.find({
        'question_id': question_id
    })
    question['requests'] = await cursor.to_list(length=50)
    for idx, req in enumerate(question['requests']):
        question['requests'][idx]['id'] = str(req['_id'])
        del question['requests'][idx]['_id']
        question['requests'][idx]['user'] = await request.app.db.users.find_one({
            '_id': ObjectId(question['user_id'])
        }, {'_id': False})
    # TODO: fix this
    return res_json(question)
コード例 #4
0
async def ChatFeedback(request, token: Token, question_id):
    user = token.jwt_identity
    question = await request.app.db.questions.find_one(
        {'_id': ObjectId(question_id)})
    if not question:
        abort(500, message='question을 찾을 수 없음')
    if question['user_id'] == user['id']:
        # user is mentee
        sender = 'mentee'
    else:
        sender = 'mentor'

    # 같은 question_id의 feedback 찾고 있으면 question의 status를 C로 바꿈
    if await request.app.db.feedbacks.find_one({'question_id': question_id}):
        res = await request.app.db.questions.update_one(
            {'_id': ObjectId(question_id)}, {'$set': {
                'status': 'C'
            }})
        if not res.acknowledged:
            abort(500)

    feedback = {
        'question_id': question_id,
        'sender': sender,
        'user_id': user['id'],
        'message': request.json['message'],
        'timestamp': int(time.time())
    }
    res = await request.app.db.feedbacks.insert_one(feedback)
    if not res.acknowledged:
        abort(500)

    return res_json({'id': str(res.inserted_id)})
コード例 #5
0
async def write_comments(request, identity: dict, post_id):
    post = await request.app.db.posts.find_one(ObjectId(post_id))
    if not post:
        abort(404)

    if any(comment['author_id'] == identity['id']
           for comment in post['comments']):
        abort(400)

    comment = {
        'content': request.json['content'],
        'timestamp': int(time.time()),
        'author': '{} {}'.format(identity['student']['serial'],
                                 identity['name']),
        'author_id': identity['id'],
    }

    res = await request.app.db.posts.update_one(
        {'_id': ObjectId(post_id)}, {'$push': {
            'comments': comment
        }})
    if not res.acknowledged:
        abort(500)

    return res_json({})
コード例 #6
0
async def QuestionList(request, token: Token):
    page = request.args.get('page') or 1
    per_page = request.args.get('per_page') or 10
    query = {
        'status': request.args.get('status') or 'P',
        'category': request.args.get('category')
    }
    if not query['category']:
        del query['category']
    cursor = request.app.db.questions.find({
    }).sort(
        'timestamp', pymongo.ASCENDING
    ).skip(
        (page - 1) * per_page
    ).limit(per_page)
    questions = await cursor.to_list(length=50)
    for question in questions:
        question['id'] = str(question['_id'])
        del question['_id']
        question['user'] = await request.app.db.users.find_one({
            '_id': ObjectId(question['user_id'])
        }, {'_id': False})
        del question['user_id']
        cursor = request.app.db.requests.find({
            'question_id': question['id']
        }, {'_id': False})
        reqs = await cursor.to_list(length=50)
        question['requests'] = len(reqs)
        question['views'] = 0
    return res_json({ 'questions': questions })
コード例 #7
0
async def check_hash(request, file_id):
    # find update with given fileId
    update = await request.app.db.updates.find_one({'_id': ObjectId(file_id)})
    if not update:
        abort(404)

    # validation failed
    if update.hash != request.json['hash']:
        abort(400)

    # update device status
    res = await request.app.db.devices.update(
        {'wallet': request.json['wallet']}, {'$set': {
            'update': None
        }})
    if not res.acknowledged:
        abort(404)

    # log success
    log = {
        'type': 'success',
        'timestamp': int(time.time()),
        'json': {
            'route': update['route'],
            'hash': update['hash']
        }
    }
    await request.app.db.logs.insert_one(log)

    return res_json({})
コード例 #8
0
async def AuthLogin(request):
    email, password = request.json['email'], request.json['password']

    user = await request.app.db.users.find_one(
        {
            'email': email,
            'password': password
        }, {'password': False})
    if not user:
        abort(404)

    user['id'] = str(user['_id'])
    del user['_id']

    identity = {'id': user['id'], 'name': user['name']}
    token = await create_access_token(identity=identity,
                                      app=request.app,
                                      expires_delta=False)
    refresh_token = await create_refresh_token(identity=identity,
                                               app=request.app)
    return res_json({
        'token': token,
        'refresh_token': refresh_token,
        'user': user
    })
コード例 #9
0
async def ChatPost(request, token: Token, question_id):
    user = token.jwt_identity
    question = await request.app.db.questions.find_one(
        {'_id': ObjectId(question_id)})
    if not question:
        abort(404)
    if question['user_id'] == user['id']:
        # user is mentee
        sender = 'mentee'
    else:
        sender = 'mentor'

    # user_id로 sender 구하고, text 타입의 chat 만들어 저장
    chat = {
        'type': 'text',
        'question_id': question_id,
        'sender': sender,
        'message': request.json['message'],
        'timestamp': int(time.time())
    }
    res = await request.app.db.chats.insert_one(chat)
    if not res.acknowledged:
        abort(500)

    await sio.emit('update', {}, room=question_id)
    return res_json({})
コード例 #10
0
async def AuthLogin(request):
    _id, _password = request.json['id'], request.json['password']

    user = await request.app.db.users.find_one({'id': _id}
                                               )  # check if _id exists in DB
    if not user:
        # if not, query student profile with token and save to DB
        dimigoin_token = await dimigo_auth(_id, _password)
        if not dimigoin_token:  # 잘못된 로그인
            abort(404)

        student = await dimigo_profile(dimigoin_token)
        if not student:  # API server error
            abort(403)

        user = {'id': _id, 'student': student}
        res = await request.app.db.users.insert_one(user)
        if not res.acknowledged:
            abort(500)

    identity = {
        'id': str(user['_id']),
        'name': user['student']['name'],
        'serial': user['student']['serial']
    }
    token = await create_access_token(identity=identity, app=request.app)
    refresh_token = await create_refresh_token(identity=identity,
                                               app=request.app)
    return res_json({
        'id': identity['id'],
        'token': token,
        'refresh_token': refresh_token,
        # 'user': user['student']
    })
コード例 #11
0
async def AuthJoin(request):
    try:
        keys = [
            'name', 'school', 'grade', 'klass', 'number', 'photo', 'email',
            'password'
        ]
        user = {'user_type': 'S'}
        for key in keys:
            user[key] = request.json[key]
    except BaseException:
        return res_json(400)
    if await request.app.db.users.find_one({'email': user['email']}):
        abort(400)
    res = await request.app.db.users.insert_one(user)
    if not res.acknowledged:
        abort(500)
    return res_json({})
コード例 #12
0
async def list_post(request, identity: dict):
    cursor = request.app.db.posts.find({})
    posts = await cursor.to_list(length=50)
    for idx, post in enumerate(posts):
        post['id'] = str(post['_id'])
        del post['_id']
        post['idx'] = idx + 1
        post['likes'] = len(post['comments'])
        post['expire'] = '2019-09-15'  # test data
    return res_json({'posts': posts})
コード例 #13
0
async def check_update(request):
    # find device with given wallet
    device = await request.app.db.devices.find_one(
        {'wallet': request.json['wallet']})
    if not device:
        abort(404)

    # return update info if available
    if device['update']:
        update = await request.app.db.updates.find_one(
            {'_id': ObjectId(device['update'])})
        if not update:
            abort(500)
        return res_json({
            'update': True,
            'id': str(update['_id']),
            'txHash': update['txHash'],
        })
    return res_json({'update': False})
コード例 #14
0
async def edit_comments(request, identity: dict, post_id):
    res = await request.app.db.posts.update_one(
        {
            '_id': ObjectId(post_id),
            'comments.author_id': identity['id']
        }, {'$set': {
            'comments.$.content': request.json['content']
        }})
    if not res.acknowledged:
        abort(404)
    return res_json({})
コード例 #15
0
async def delete_comments(request, identity: dict, post_id):
    res = await request.app.db.posts.update_one(
        {'_id': ObjectId(post_id)},
        {'$pull': {
            'comments': {
                'author_id': identity['id']
            }
        }})
    if not res.acknowledged:
        abort(404)
    return res_json({})
コード例 #16
0
async def ChatEnd(request, token: Token, question_id):
    # user = token.jwt_identity

    # question_id의 status를 F로 변경
    res = await request.app.db.questions.update_one(
        {'_id': ObjectId(question_id)}, {'$set': {
            'status': 'F'
        }})
    if not res.acknowledged:
        abort(500)

    await sio.emit('end', {}, room=question_id)
    return res_json({})
コード例 #17
0
async def UploadProfile(request):
    profile_image = request.files.get('file')
    _, ext = os.path.splitext(profile_image.name)
    timestamp = int(time.time())
    file_path = './profile/{}'.format(str(timestamp) + ext)

    with open(
            os.path.join('.{}'.format(request.app.config['UPLOAD_PATH']),
                         file_path), 'wb') as fp:
        fp.write(profile_image.body)
    return res_json(
        {'url': urljoin(request.app.config['UPLOAD_PATH'], file_path)},
        escape_forward_slashes=False)
コード例 #18
0
async def view_post(request, post_id):
    post = await request.app.db.posts.find_one(ObjectId(post_id))
    if not post:
        abort(404)
    post['_id'] = str(post['_id'])

    # TODO: post metadata
    post['status'] = True
    post['start'] = '2019-08-12'
    post['expire'] = '2019-09-15'

    post['likes'] = len(post['comments'])
    return res_json(post)
コード例 #19
0
async def download(request):
    update = await request.app.db.updates.find_one({
        '_id': ObjectId(device['update'])
    })
    if not update:
        abort(404)
    if update['key'] != request.json['key']:
        abort(400)
    return res_json({
        'url': urljoin(
            request.url_root,
            update['route'].replace('server', '')
        )
    })
コード例 #20
0
async def QuestionPost(request, token: Token):
    user = token.jwt_identity
    question = {
        'user_id': user['id'],
        'status': 'P',
        'portfolio': None,
        'timestamp': int(time.time())
    }
    keys = ['title', 'article', 'category', 'photo']
    for key in keys:
        question[key] = request.json[key]
    res = await request.app.db.questions.insert_one(question)
    if not res.acknowledged:
        abort(500)
    return res_json({'id': str(res.inserted_id)})
コード例 #21
0
async def write_post(request, identity: dict):
    post = {
        'name': request.json['name'],
        'content': request.json['content'],
        'comments': [],
        'image': request.json.get('image'),
        'timestamp': int(time.time()),
        'author': identity['name'][0] + '**',
        'author_id': identity['id'],
        'topic': request.json['topic']
    }
    res = await request.app.db.posts.insert_one(post)
    if not res.acknowledged:
        abort(500)
    return res_json({'post_id': str(res.inserted_id)})
コード例 #22
0
async def MentoringList(request, token: Token):
    user = token.jwt_identity

    questions = {
        'user': {},
        'mentor': [],  # user가 멘토인 questions
        'mentee': []  # user가 멘티인 questions
    }

    questions['user'] = await request.app.db.users.find_one(
        {
            '_id': ObjectId(user['id']),
        }, {'_id': False})

    # 자신의 user_id를 가진 모든 question 쿼리 +
    cursor = request.app.db.questions.find({'user_id': user['id']})
    questions['mentee'] = await cursor.to_list(length=50)

    # 자신의 user_id를 가진 approve된 request 쿼리 -> question 쿼리
    cursor = request.app.db.requests.find({
        'user_id': user['id'],
        'approved': True,
    })
    requests = await cursor.to_list(length=50)
    questions['mentor'] = [
        await request.app.db.questions.find_one({
            '_id':
            ObjectId(req['question_id']),
        }) for req in requests
    ]

    for question in questions['mentor']:
        question['id'] = str(question['_id'])
        del question['_id']
        cursor = request.app.db.requests.find({'question_id': question['id']},
                                              {'_id': False})
        reqs = await cursor.to_list(length=50)
        question['requests'] = len(reqs)
    for question in questions['mentee']:
        question['id'] = str(question['_id'])
        del question['_id']
        cursor = request.app.db.requests.find({'question_id': question['id']},
                                              {'_id': False})
        reqs = await cursor.to_list(length=50)
        question['requests'] = len(reqs)
    return res_json({'mentorings': questions})
コード例 #23
0
async def edit_post(request, identity: dict, post_id):
    post = await request.app.db.posts.find_one(ObjectId(post_id))
    if not post:
        abort(404)
    _name = request.json.get('name')
    _content = request.json.get('content')
    _image = request.json.get('image')
    _topic = request.json.get('topic')
    res = await request.app.db.posts.update_one({'_id': ObjectId(post_id)}, {
        '$set': {
            'name': _name if _name else post['name'],
            'content': _name if _content else post['content'],
            'image': _name if _image else post['image'],
            'topic': _topic if _topic else post['topic']
        }
    })
    if not res.acknowledged:
        abort(500)
    return res_json({})
コード例 #24
0
async def MentoringRequest(request, token: Token, question_id):
    user = token.jwt_identity

    # 이미 신청한 멘토링은 아닌지 확인
    if await request.app.db.requests.find_one({
            'user_id': user['id'],
            'question_id': question_id,
    }):
        abort(400)

    req = {
        'user_id': user['id'],
        'question_id': question_id,
        'timestamp': int(time.time()),
        'approved': False
    }
    res = await request.app.db.requests.insert_one(req)
    if not res.acknowledged:
        abort(500)
    return res_json({'id': str(res.inserted_id)})
コード例 #25
0
async def UploadMath(request):
    profile_image = request.files.get('file')
    _, ext = os.path.splitext(profile_image.name)
    timestamp = int(time.time())
    file_path = './math/{}'.format(str(timestamp) + ext)

    with open(
            os.path.join('.{}'.format(request.app.config['UPLOAD_PATH']),
                         file_path), 'wb') as fp:
        fp.write(profile_image.body)
    image_url = reduce(urljoin, [
        request.app.config['BASE_URL'], request.app.config['UPLOAD_PATH'],
        file_path
    ])
    return res_json(
        {
            'url': image_url,
            'math': mathpix.api.image_to_math(image_url)
        },
        escape_forward_slashes=False)
コード例 #26
0
async def upload(request):
    print(request.files)
    file = request.files.get('file')
    upload_dir = os.path.join(request.app.config['UPLOAD_FOLDER'],
                              random_key() + hash_string(file.name) + '/')

    if not os.path.exists(upload_dir):
        os.makedirs(upload_dir)

    route = os.path.join(upload_dir, file.name)
    with open(route, 'wb') as _f:
        _f.write(file.body)

    update = {'route': route, 'key': random_key(), 'hash': hash_file(route)}

    # TODO: send update.key to blockchain and receive txHash
    update['txHash'] = 'test'

    # save update
    res = await request.app.db.updates.insert_one(update)
    if not res.acknowledged:
        abort(500)

    # update device
    devices = request.json.get('devices')
    for device in devices:
        await request.app.db.devices.update(
            {'name': device}, {'$set': {
                'update': update['key']
            }})

    # save log
    log = {
        'route': update['route'],
        'hash': update['hash'],
        'time': int(time.time())
    }
    await request.app.db.logs.insert_one(log)

    return res_json({'id': res.inserted_id, 'txHash': update['txHash']})
コード例 #27
0
async def MentoringApprove(request, token: Token, question_id):
    user = token.jwt_identity

    # question 쿼리, 작성자 확인
    question = await request.app.db.questions.find_one({
        '_id':
        ObjectId(question_id),
        'user_id':
        user['id'],
    })
    if not question:
        abort(404)

    # 다른 멘토링이 이미 승인된 것은 아닌지 확인
    if await request.app.db.requests.find_one({
            'question_id': question_id,
            'approved': True
    }):
        abort(400)

    # post로 받은 request_id를 가진 request의 approved를 True로 업데이트
    request_id = request.json['request_id']
    res = await request.app.db.requests.update_one(
        {'_id': ObjectId(request_id)}, {'$set': {
            'approved': True
        }})
    if not res.acknowledged:
        abort(500)

    # question의 status 변경
    res = await request.app.db.questions.update_one(
        {'_id': ObjectId(question_id)}, {'$set': {
            'status': 'M'
        }})
    if not res.acknowledged:
        abort(500)

    return res_json({})
コード例 #28
0
async def ChatView(request, token: Token, question_id):
    # user = token.jwt_identity
    # TODO: user['id']를 사용해서 사용자 정보 쿼리 근데 뭐 맞겠지

    # question_id로 question 쿼리
    question = await request.app.db.questions.find_one(
        {'_id': ObjectId(question_id)})
    if not question:
        abort(404)

    # 상태 확인 -> M이여야 함
    if question['status'] != 'M':
        abort(400)

    # question_id로 chat 쿼리, timestamp로 정렬해 반환
    cursor = request.app.db.chats.find({
        'question_id': question_id
    }).sort('timestamp', pymongo.ASCENDING)
    chats = await cursor.to_list(length=50)

    cursor = request.app.db.teachers.find({'question_id': question_id})
    teachers = await cursor.to_list(length=50)

    for chat in chats:
        chat['id'] = str(chat['_id'])
        del chat['_id']
        for teacher in teachers:
            if (chat['id'] == teacher['chat_id']):
                del teacher['question_id']
                del teacher['chat_id']
                teacher['id'] = str(teacher['_id'])
                del teacher['_id']
                chat['teacher'] = teacher
        chat['keywords'] = request.app.keywords.search(chat['message'])

    print(chats)
    return res_json({'chats': chats})
コード例 #29
0
async def register(request):
    wallet = request.json['wallet']
    if len(wallet) != 42:
        abort(404)

    # register device
    device = {'name': request.json['name'], 'wallet': wallet, 'update': None}
    res = await request.app.db.devices.insert_one(device)
    if not res.acknowledged:
        abort(500)

    # save log
    log = {
        'type': 'register',
        'timestamp': int(time.time()),
        'json': {
            'name': device['name'],
            'wallet': device['wallet']
        }
    }
    await request.app.db.logs.insert_one(log)
    # error handling is not necessary for logging

    return res_json({})  # 200
コード例 #30
0
async def device_info(request, wallet):
    res = await request.app.db.devices.delete_one({'wallet': wallet})
    if not res.acknowledged:
        abort(404)
    return res_json({})