class PrivateChatSchema(ma.Schema):
    """Class to serialize PrivateChat models."""

    RESOURCE_NAME = "private_chat"
    COLLECTION_NAME = "private_chats"

    _id = ma.UUID(required=True, data_key="id")
    _primary_user = ma.Nested(UserSchema(),
                              dump_only=True,
                              data_key="primary_user")
    _secondary_user = ma.Nested(UserSchema(),
                                dump_only=True,
                                data_key="secondary_user")
    resource_type = ma.Str(dump_only=True, default="PrivateChat")

    # Links
    messages_url = ma.URLFor("api.get_private_chat_messages",
                             private_chat_id="<_id>")

    @post_load
    def convert_uuid_to_hex(self, data, **kwargs):
        """Convert all UUID fields to their 32-character hexadecimal equivalent."""
        for key in data:
            value = data[key]
            if isinstance(value, uuid.UUID):
                data[key] = data[key].hex
        return data
class GroupChatSchema(ma.Schema):
    """Class for serializing and deserializing GroupChat models."""

    RESOURCE_NAME = "group_chat"
    COLLECTION_NAME = "group_chats"

    class Meta:
        unknown = EXCLUDE
    
    _id = ma.UUID(required=True, data_key="id")
    _community_id = ma.UUID(required=True, data_key="community_id")
    name = ma.Str(required=True, validate=validate.Length(min=1, max=32))
    description = ma.Str(required=True, validate=validate.Length(min=1, max=140))
    resource_type = ma.Str(default="GroupChat", dump_only=True)

    # Links
    self_url = ma.URLFor(
        "api.get_community_group_chat", community_id="<_community_id>", group_chat_id="<_id>"
    )
    messages_url = ma.URLFor("api.get_group_chat_messages", group_chat_id="<_id>")
    community_url = ma.URLFor("api.get_community", community_id="<_id>")
    members_url = ma.URLFor("api.get_community_group_chat_members", community_id="<_community_id>", group_chat_id="<_id>")


    @post_load
    def convert_uuid_to_hex(self, data, **kwargs):
        """Convert all UUID fields to their 32-character hexadecimal equivalent."""
        for key in data:
            value = data[key]
            if isinstance(value, uuid.UUID):
                data[key] = data[key].hex
        return data

    @pre_load
    def strip_unwanted_fields(self, data, many, **kwargs):
        """Remove unwanted fields from the input data before deserialization."""
        unwanted_fields = ["resource_type"]
        for field in unwanted_fields:
            if field in data:
                data.pop(field)
        return data
Exemple #3
0
class CommunitySchema(ma.Schema):
    """Class to serialize and deserialize Community models."""

    COLLECTION_NAME = "communities"
    RESOURCE_NAME = "community"

    class Meta:
        unknown = EXCLUDE

    _id = ma.UUID(data_key="id", dump_only=True)
    name = ma.Str(required=True, validate=validate.Length(min=1, max=64))
    description = ma.Str(required=True,
                         validate=validate.Length(min=1, max=280))
    topic = EnumField(CommunityTopic)
    avatar = ma.Nested(ImageSchema, dump_only=True)
    cover_photo = ma.Nested(ImageSchema, dump_only=True)
    location = ma.Nested(LocationSchema, required=True)
    _founder_id = ma.UUID(dump_only=True, data_key="founder_id")
    _created_at = ma.DateTime(data_key="founded_on",
                              dump_only=True)  # defaults to ISO 8601
    resource_type = ma.Str(default="Community", dump_only=True)

    # Links
    self_url = ma.URLFor("api.get_community", community_id="<_id>")
    founder_url = ma.URLFor("api.get_user", user_id="<_founder_id>")
    members_url = ma.URLFor("api.get_community_members", community_id="<_id>")
    group_chats_url = ma.URLFor("api.get_community_group_chats",
                                community_id="<_id>")

    @pre_load
    def strip_unwanted_fields(self, data, many, **kwargs):
        """Remove unwanted fields from the input data before deserialization."""
        unwanted_fields = ["resource_type"]
        for field in unwanted_fields:
            if field in data:
                data.pop(field)
        return data
Exemple #4
0
class UserSchema(ma.Schema):
    """Class to serialize and deserialize User models."""

    COLLECTION_NAME = "users"
    RESOURCE_NAME = "user"

    class Meta:
        unknown = EXCLUDE

    _id = ma.UUID(data_key="id", dump_only=True)
    username = ma.Str(required=True, validate=validate.Length(min=1, max=32))
    name = ma.Str(required=True, validate=validate.Length(min=1, max=32))
    email = ma.Email(required=True, validate=validate.Length(min=1, max=32))
    _created_at = ma.DateTime(data_key="joined_on",
                              dump_only=True)  # defaults to ISO 8601
    last_seen_at = ma.DateTime(dump_only=True)  # defaults to ISO 8601
    password = ma.Str(required=True, load_only=True)
    bio = ma.Str(validate=validate.Length(max=280))
    resource_type = ma.Str(default="User", dump_only=True)
    location = ma.Nested(LocationSchema, required=True)
    avatar = ma.Nested(ImageSchema, dump_only=True)
    cover_photo = ma.Nested(ImageSchema, dump_only=True)

    # links
    self_url = ma.URLFor("api.get_user", user_id="<_id>")
    communities_url = ma.URLFor("api.get_user_communities", user_id="<_id>")
    notifications_url = ma.URLFor("api.get_user_notifications",
                                  user_id="<_id>")
    private_chats_url = ma.URLFor("api.get_user_private_chats",
                                  user_id="<_id>")
    group_chats_url = ma.URLFor("api.get_user_group_chats", user_id="<_id>")

    @pre_load
    def strip_unwanted_fields(self, data, many, **kwargs):
        """Remove unwanted fields from the input data before deserialization."""
        unwanted_fields = ["resource_type"]
        for field in unwanted_fields:
            if field in data:
                data.pop(field)
        return data

    @post_dump(pass_original=True)
    def inject_extra_fields(self, data, original_model, **kwargs):
        """Post processing method to inject extra fields into the
        serialized data.
        """
        if hasattr(original_model, "role"):
            data["is_admin"] = original_model.is_admin()
        return data
class GroupChatUrlParamsSchema(UrlParamsSchema):
    """Class to parse and validate information from Group Chat url parameters."""
    class Meta:
        unknown = EXCLUDE

    community_id = ma.UUID(required=True)

    @post_load
    def convert_uuid_to_hex(self, data, **kwargs):
        """Convert all UUID fields to their 32-character hexadecimal equivalent."""
        for key in data:
            value = data[key]
            if isinstance(value, uuid.UUID):
                data[key] = data[key].hex
        return data
class NotificationSchema(ma.Schema):
    """Class to serialize and deserialize notification
    models.
    """

    RESOURCE_NAME = "notification"
    COLLECTION_NAME = "notifications"

    class Meta:
        unknown = EXCLUDE

    _id = ma.Str(required=True, data_key="id", dump_only=True)
    _user_id = ma.UUID(required=True, data_key="user_id", dump_only=True)
    _notification_type = EnumField(NotificationType, required=True, data_key="notification_type", dump_only=True)
    _message = ma.Str(required=True, data_key="message", validate=validate.Length(min=1, max=64), dump_only=True)
    _target_url = ma.URL(required=True, data_key="target_url", dump_only=True)
    _created_at = ma.DateTime(data_key="timestamp", dump_only=True)  # defaults to ISO 8601
    _read = ma.Boolean(data_key="read")
    _seen = ma.Boolean(data_key="seen")
    resource_type = ma.Str(default="Notification", dump_only=True)

    @validates_schema
    def validate_read_and_seen(self, data, **kwargs):
        """Raise a ValidationError if both read and seen aren't present
        in the data on load.
        """
        if "_read" not in data and "_seen" not in data:
            raise ValidationError(
                "Please provide at least one field to update. Valid fields to update are: read, seen"
            )
        return data

    @pre_load
    def strip_unwanted_fields(self, data, many, **kwargs):
        """Remove unwanted fields from the input data before deserialization."""
        unwanted_fields = ["resource_type"]
        for field in unwanted_fields:
            if field in data:
                data.pop(field)
        return data
from flask import current_app, url_for, g
from app.api import api
from app.repositories import database_repository
from app.repositories.exceptions import (
    DatabaseException,
    NotFoundException,
    UniqueConstraintException,
)
from app.schemas import UrlParamsSchema, PrivateChatMessageSchema, PrivateChatSchema
from app.decorators.views import handle_request, handle_response
from app.decorators.auth import permission_required
from app.models import RolePermission, PrivateChat, MessageType
from app.extensions import ma

PrivateChatGeneratedSchema = ma.Schema.from_dict(
    {"other_user_id": ma.UUID(required=True)})


@api.route("/private_chats/<private_chat_id>/messages")
@handle_request(UrlParamsSchema())
@handle_response(PrivateChatMessageSchema(many=True))
def get_private_chat_messages(url_params, private_chat_id):
    """Return a list of private chat message resources."""
    per_page = url_params.get("per_page",
                              current_app.config["RESULTS_PER_PAGE"])
    cursor = url_params.get("next_cursor")
    private_chat = database_repository.get_private_chat(private_chat_id)
    if not private_chat:
        return {"error": "Private chat not found"}, HTTPStatus.NOT_FOUND
    if not private_chat.is_member(g.current_user.id):
        return {