def route_delete_user_image(user_id: str, index: int): user = User.objects.get_or_404(id=user_id) user.identify(request) if user.available and user.status == User.Status.APPROVED: is_same = compare_user_images_and_temps( user.user_images, user.user_images_temp ) if is_same and len(user.user_images_temp) > 2: images = user.user_images images_to_update = [image for image in images if image.index != index] user.update(user_images=images_to_update) user.update(user_images_temp=images_to_update) user.reload() response = encode(user.to_mongo()) return Response(response, mimetype="application/json") user_image_to_remove = next( (user_image_temp for user_image_temp in user.user_images_temp if user_image_temp.index == index), None) user.update(pull__user_images_temp=user_image_to_remove) user.status = User.Status.OPENED user.save() user.reload() response = encode(user.to_mongo()) return Response(response, mimetype="application/json")
def route_upload_user_image(user_id: str, index: int): """Endpoint for uploading profile images.""" user = User.objects.get_or_404(id=user_id) user.identify(request) image_file = request.files["user_image"] if not re.match(IMAGE_MIMETYPE_REGEX, image_file.mimetype): raise ValueError("The file is not an image type.") bucket = storage.bucket() file_name_to_save = "{0}_{1}_{2}".format(user.uid, index, uuid.uuid1()) blob = bucket.blob("{0}/{1}/{2}".format(USER_IMAGE_FOLDER, user.uid, file_name_to_save)) blob.upload_from_file(image_file) user_images_temp = user.user_images_temp current_image_at_index = next((x for x in user_images_temp if x.index == index), None) if not current_image_at_index: # create new one user.user_images_temp.append(UserImage(index=index, url=blob.public_url)) else: # update existing one current_image_at_index.url = blob.public_url user.user_images_temp = sorted(user_images_temp, key=lambda x: x.index) user.status = User.Status.OPENED user.save() updated_image = next((x for x in user_images_temp if x.index == index), None) response = encode(updated_image.to_mongo()) return Response(response, mimetype="application/json")
def route_update_registration_token(device_token: str): """Endpoint for updating user registration token.""" uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) existing_device_token = user.device_token new_device_token = device_token is_update_required = existing_device_token != new_device_token if is_update_required: user.device_token = new_device_token user.save() if is_update_required and existing_device_token is not None: try: message = messaging.Message( data=dict(event=Alarm.Event.LOG_OUT), token=existing_device_token, apns=messaging.APNSConfig(), android=messaging.AndroidConfig(priority="high"), notification=messaging.Notification() ) messaging.send(message) except Exception as e: logging.exception(e) response = encode(user.to_mongo()) return Response(response, mimetype="application/json")
def route_list_requests(): """Endpoint for like request list.""" uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) result = user.list_requests_to_me() response = encode(result) return Response(response, mimetype="application/json")
def route_register_user(): uid = request.headers.get("uid", None) phone = request.form.get("phone", None) sms_code = request.form.get("sms_code", None) sms_token = request.form.get("sms_token", None) proof = verify_sms_token(sms_token, phone, sms_code) if not proof: abort(401) if not phone: raise ValueError("phone is required value to create an user.") user = User.objects(uid=uid).first() if not user: user = User(uid=uid, phone=phone, status=User.Status.OPENED, available=False, last_login_at=pendulum.now().int_timestamp) user.save() alarm = Alarm(owner=user, records=[]) alarm.save() response = encode(user.to_mongo()) return Response(response, mimetype="application/json")
def route_list_users_i_rated_high(user_id: str): user = User.objects.get_or_404(id=user_id) user.identify(request) users = user.list_users_i_rated_high() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_list_users_rated_me(user_id: str): """Endpoint for getting users rated me.""" user = User.objects.get_or_404(id=user_id) user.identify(request) users = user.list_users_rated_me() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_list_users_real_time(user_id: str): """Endpoint for getting users.""" user = User.objects.get_or_404(id=user_id) user.identify(request) user_ids = user.list_realtime_user_ids() users = User.list(id__in=user_ids).as_pymongo() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_update_user_status_pending(user_id: str): user = User.objects.get_or_404(id=user_id) user.identify(request) user.status = User.Status.PENDING user.save() response = encode(user.to_mongo()) return Response(response, mimetype="application/json")
def route_update_user_status_to_rejected(user_id: str): """Endpoint for updating user status rejected.""" user = User.objects.get_or_404(id=user_id) user.user_images = user.user_images_temp user.status = User.Status.REJECTED user.available = False user.save() response = encode(user.to_mongo()) return Response(response, mimetype="application/json")
def route_get_conversation(conversation_id): uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) conversation = Conversation.objects.get_or_404(id=conversation_id, participants=user).to_mongo() user_ids = get_conversation_reference_ids([conversation]) user_index = User.get_users_dict(user_ids) conversation["participants"] = [user_index.get(str(user_id), None) for user_id in conversation["participants"]] conversation["references"] = [user_index.get(str(user_id), None) for user_id in conversation["references"]] response = encode(conversation) return Response(response, mimetype="application/json")
def route_get_push_setting(user_id: str): user = User.objects.get_or_404(id=user_id) user.identify(request) setting = Setting.objects(owner=user).first() if not setting: setting = Setting(owner=user) setting.save() push_setting = setting.push push_setting = push_setting.to_mongo() response = encode(push_setting) return Response(response, mimetype="application/json")
def route_list_all_favorite_users(post_id): uid = request.headers.get("uid", None) post = Post.objects.get_or_404(id=post_id) if post.author.uid != uid: abort(401) favorite_user_ids = post.favorite_user_ids users = User.objects(id__in=favorite_user_ids) \ .exclude(*User.excludes()).as_pymongo() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_list_users_close(user_id: str, distance: int): """Endpoint for getting users.""" user = User.objects.get_or_404(id=user_id) user.identify(request) distance = distance or 5 if not user.location or not user.location["coordinates"]: return Response(json.dumps([]), mimetype="application/json") close_user_ids = user.list_user_ids_within_distance(distance=distance) users = User.list(id__in=close_user_ids).as_pymongo() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_admin_session(): """Checks session..""" uid = request.headers.get("uid", None) admin = Admin.objects(uid=uid).first() if not admin: admin = Admin(uid=uid, available=False) admin.save() admin.reload() uid = admin.user.uid if admin.user else None available = admin.available response = encode(dict(uid=uid, available=available)) return Response(response, mimetype="application/json")
def route_list_pending_users(status: str): """Retrieves all pending users.""" uid = request.headers.get("uid", None) admin = Admin.objects.get_or_404(uid=uid) if not admin.available: abort(401) status = status or "" status = status.upper() users = User.objects(status=status).as_pymongo() response = encode(list(users)) return Response(response, mimetype="application/json")
def route_list_posts(): uid = request.headers.get("uid", None) user = User.get(uid=uid) opposite_sex = "M" if user.sex == "F" else "F" last_id: str = request.args.get("last_id", None) per_page: int = int(request.args.get("per_page", 30)) params = dict(author_sex=opposite_sex, limit=per_page, is_deleted=False) if last_id: params["id__lt"] = last_id result = Post.list_posts(**params) response = encode(list(result)) return Response(response, mimetype="application/json")
def route_update_response_of_request(request_id: str, result: int): """Updates a received like request. ACCEPT: 1 DECLINE: 0 """ uid = request.headers.get("uid", None) me = User.objects.get_or_404(uid=uid) _request = Request.objects.get_or_404(id=request_id) if _request.user_to.id != me.id: abort(400) # update request table. _request.response = result _request.responded_at = pendulum.now().int_timestamp _request.save() _request.reload() if int(result) == 1: _request.user_to.remove_user_from_recommendation(_request.user_from) # create chat room conversation = Conversation( title=None, participants=[_request.user_from, _request.user_to], references=[_request.user_from, _request.user_to], created_at=pendulum.now().int_timestamp) conversation.save() conversation.reload() # alarm by push below user_alarm_from = _request.user_to user_alarm_to = _request.user_from alarm = Alarm.create_alarm(user_from=user_alarm_from, user_to=user_alarm_to, event=Alarm.Event.MATCHED, request=_request, conversation=conversation, message="{nickname} 님과 연결 되었습니다.".format( nickname=_request.user_to.nickname)) alarm_record = alarm.records[-1] data = alarm_record.as_dict() message_service.push(data, user_alarm_to) response = encode(Request.get(id=_request.id)) return Response(response, mimetype="application/json")
def route_list_user_conversations(): uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) conversations = Conversation.objects(participants=user).as_pymongo() user_ids = get_conversation_reference_ids(conversations) users_dict = User.get_users_dict(user_ids) converted = [] for conversation in conversations: participants = [users_dict.get(str(user_id), None) for user_id in conversation.get("participants")] references = [users_dict.get(str(user_id), None) for user_id in conversation.get("references")] if None not in participants and None not in references: conversation["participants"] = participants conversation["references"] = references converted.append(conversation) response = encode(converted) return Response(response, mimetype="application/json")
def route_list_posts(): """Lists all posts not filtering opposite sex things.""" uid = request.headers.get("uid", None) admin = Admin.objects.get_or_404(uid=uid) if not admin.available: abort(401) last_id: str = request.args.get("last_id", None) per_page: int = int(request.args.get("per_page", 30)) params = dict(is_deleted=False, limit=per_page) if last_id: params["id__lt"] = last_id result = Post.list_posts(**params) response = encode(list(result)) return Response(response, mimetype="application/json")
def route_create_message(conversation_id: str, message: str): uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) conversation = Conversation.objects.get_or_404(id=conversation_id, participants=user) embedded_message = EmbeddedMessage( conversation_id=conversation_id, category="MESSAGE", user_id=str(user.id), message=message, created_at=pendulum.now().int_timestamp ) conversation.messages.append(embedded_message) conversation.save() user_from = user user_image = next(iter(user.user_images or []), None) image_url = user_image.url if user_image else "" user_to_list = [p for p in conversation.participants if p.id != user.id] for user_to in user_to_list: message_service.push( dict( event=Alarm.Event.CONVERSATION, nickname=user_from.nickname, user_id=str(user_from.id), image_url=image_url, created_at=str(pendulum.now().int_timestamp), conversation_id=str(conversation.id), message_id=str(embedded_message.id), message=str(embedded_message.message), category="MESSAGE", ), user_to, priority="high" ) response = encode(embedded_message.to_mongo()) return Response(response, mimetype="application/json")
def route_create_comment(post_id: str): uid = request.headers.get("uid", None) if not uid: abort(401) # if exists, create a comment as a sub comment comment_id = request.form.get("comment_id", None) # parent_comment_id comment = request.form.get("comment", "") post = Post.objects.get_or_404(id=post_id) user = User.objects.get_or_404(uid=uid) comment_to_create = Comment( post_id=post_id, user_id=user.id, comment=comment, comments=[], # child comments created_at=pendulum.now().int_timestamp, is_deleted=False).save() post.add_comment(comment_to_create, parent_id=comment_id) alarm = Alarm.create_alarm( user_from=user, user_to=post.author, event=Alarm.Event.COMMENT, post=post, comment=comment_to_create, message="{nickname} 님이 당신의 게시물에 댓글을 남겼습니다.".format( nickname=user.nickname)) alarm_record = alarm.records[-1] data = alarm_record.as_dict() message_service.push(data, post.author) comment = comment_to_create.to_mongo() comment["commenter"] = User.get(id=user.id).to_mongo() response = encode(comment) return Response(response, mimetype="application/json")
def route_get_session(): """Endpoint for getting user session.""" uid = request.headers.get("uid", None) user = User.objects.get_or_404(uid=uid) user_id = user.id point = user.get_current_amount_of_point() user = user.to_mongo() star_rating = StarRating.objects(user_from=user_id).as_pymongo() received = Request.objects(user_to=user_id).as_pymongo() sent = Request.objects(user_from=user_id).as_pymongo() # 이미 성사 된 상대 matched_request_sent = [str(req["user_to"]) for req in sent if req.get("response") == 1] matched_request_received = [str(req["user_from"]) for req in received if req.get("response") == 1] user_ids_matched = matched_request_received + matched_request_sent # 성사 되지 않은 상대 unmatched_request_sent = [str(req["user_to"]) for req in sent if req.get("response") == 0] unmatched_request_received = [str(req["user_from"]) for req in received if req.get("response") == 0] user_ids_unmatched = unmatched_request_sent + unmatched_request_received # 이미 좋아요를 보냄 user_ids_i_sent_request = [str(req["user_to"]) for req in sent if req.get("response") != 1] # 내게 좋아요를 보냄 and 미수락 user_ids_sent_me_request = [str(req["user_from"]) for req in received if req.get("response") != 1] # 내가 평가 한 사람들 star_ratings_i_rated = [dict(user_id=str(x["user_to"]), score=x["score"]) for x in star_rating] user["user_ids_matched"] = user_ids_matched user["user_ids_unmatched"] = user_ids_unmatched user["user_ids_i_sent_request"] = user_ids_i_sent_request user["user_ids_sent_me_request"] = user_ids_sent_me_request user["star_ratings_i_rated"] = star_ratings_i_rated user["point"] = point response = encode(user) return Response(response, mimetype="application/json")
def route_list_users_recommendation(user_id: str): """Endpoint for getting recommended users.""" user = User.objects.get_or_404(id=user_id) user.identify(request) recommendation = user.get_recommendation() last_recommended_at = pendulum.from_timestamp( recommendation.last_recommended_at, tz="Asia/Seoul") is_today_recommended = last_recommended_at.date() == pendulum.today().date() if is_today_recommended and len(recommendation.user_ids) >= 2: user_ids = recommendation.user_ids else: user_ids = user.list_recommended_user_ids() user_ids.extend(recommendation.user_ids) recommendation.user_ids = user_ids recommendation.last_recommended_at = pendulum.now().int_timestamp recommendation.save() users = User.list(id__in=user_ids[:MAXIMUM_RECOMMENDATION_SHOW_COUNT]).as_pymongo() users = sort_order_by_ids(user_ids, users) response = encode(list(users)) return Response(response, mimetype="application/json")
def route_create_request(user_id: str, r_type: int): """Endpoint to request like.""" uid = request.headers.get("uid", None) # already verified uid. user = User.objects.get_or_404(uid=uid) user_from = user # me user_to = User.objects.get_or_404(id=user_id) # target # checks if there is a one I have already sent request_i_sent = Request.objects(user_to=user_to, user_from=user_from).first() if request_i_sent: raise ValueError("a duplicate request already exists.") # checks if there is a one I have already received. request_i_received = Request.objects(user_to=user_from, user_from=user_to).first() if request_i_received: if request_i_received.response is None: return route_update_response_of_request(request_i_received.id, 1) else: raise ValueError("a duplicate request already exists.") is_available_for_free = user_from.is_available_for_free_pass_token() amount_remaining = user_from.get_current_amount_of_point() if not is_available_for_free and amount_remaining <= 0: raise Exception("Unavailable for the request.") _request = Request(user_from=user_from, user_to=user_to, request_type_id=r_type, requested_at=pendulum.now().int_timestamp, response=None, responded_at=None) _request.save() _request.reload() # if the target exists in recommendation, remove them. user_from.remove_user_from_recommendation(user_to) if is_available_for_free: user_from.consume_free_pass_token() else: user_from.consume(5) alarm = Alarm.create_alarm( user_from=user_from, user_to=user_to, event=Alarm.Event.REQUEST, request=_request, message="{nickname} 님이 당신에게 친구 신청을 보냈습니다.".format( nickname=user_from.nickname)) alarm_record = alarm.records[-1] data = alarm_record.as_dict() message_service.push(data, user_to) response = encode(Request.get(id=_request.id)) return Response(response, mimetype="application/json")
def route_get_request(request_id: str): """Endpoint for like request list.""" _request = Request.get(id=request_id) response = encode(_request) return Response(response, mimetype="application/json")
def route_list_user_posts(user_id): user = User.get(id=user_id) result = user.list_posts() response = encode(list(result)) return Response(response, mimetype="application/json")
def route_create_conversation(): params = request.get_json() title = params.get("title", None) conversation = Conversation(title=title, created_at=pendulum.now().int_timestamp).save() conversation.reload() return Response(encode(conversation.to_mongo()), mimetype="application/json")
def route_get_post(post_id): post = Post.get_post(id=post_id) response = encode(post) return Response(response, mimetype="application/json")
def route_get_user(): """Endpoint for getting user.""" query_params = request.args.to_dict(flat=True) user = User.get(**query_params) response = encode(user.to_mongo()) return Response(response, mimetype="application/json")