Kushal Dotel 6 months ago
commit dc83e6a1b5
  1. 67
      backend/blueprints/chat/__init__.py
  2. 84
      backend/blueprints/course/__init__.py
  3. 5
      backend/db/model.py

@ -1,3 +1,66 @@
from flask import Blueprint from flask import Blueprint, request, jsonify
from uuid import UUID
from db.model import db, User, Course, Enrollment
chat = Blueprint('chat', __name__) chat = Blueprint('chat', __name__)
@chat.route('/course/<uuid:course_id>/users', methods=['POST'])
def get_users_assigned_to_course(course_id: UUID):
"""
Fetch all users assigned to a specific course.
:param course_id: ID of the course to fetch users for (UUID).
:return: JSON response with users assigned to the course.
"""
try:
# Query the course to ensure it exists
course = Course.query.get(course_id)
if not course:
return jsonify({"error": "Course not found."}), 404
# Get the list of users assigned to the course
users = User.query.filter(User.enrollments.any(course_id=course_id)).all()
# Prepare the response data
user_data = [
{
"id": user.id,
"email": user.email,
"username": user.username,
"firstName": user.firstName,
"lastName": user.lastName,
}
for user in users
]
return jsonify({"course": course.name, "users": user_data}), 200
except Exception as e:
return jsonify({"error": f"An error occurred: {str(e)}"}), 500
@chat.route('/course/<uuid:course_id>/chat', methods=['POST'])
def join_chat(course_id: UUID):
"""
Allow users to join the chat only if they are enrolled in the course.
:param course_id: ID of the course (UUID).
:return: JSON response indicating whether the user can join or not.
"""
try:
# Get the user from the request (assume user_id is passed in the request body)
user_id = request.json.get('user_id')
if not user_id:
return jsonify({"error": "User ID is required."}), 400
# Query the user and ensure they exist
user = User.query.get(user_id)
if not user:
return jsonify({"error": "User not found."}), 404
# Check if the user is enrolled in the course
enrollment = Enrollment.query.filter_by(userID=user_id, courseID=course_id).first()
if not enrollment:
return jsonify({"error": "User is not enrolled in this course."}), 403
# If enrolled, allow the user to join the chat
return jsonify({"message": f"User {user.username} is enrolled in the course and can join the chat."}), 200
except Exception as e:
return jsonify({"error": f"An error occurred: {str(e)}"}), 500

@ -1,3 +1,83 @@
from flask import Blueprint from flask import Blueprint, request, jsonify
from werkzeug.utils import secure_filename
from sqlalchemy.sql import func
import os
import uuid
from db.model import db, Course, Category, User
from utils.utils import random_string_generator
from constants import *
from config import *
course = Blueprint('course', __name__) course = Blueprint('course', __name__)
@course.route('/create/course', methods=['POST'])
def create_course():
"""
Endpoint to create a new course.
Ensures strict adherence to the Course model, with file handling and default behaviors.
"""
try:
# Retrieve form data
data = request.form
name :str= data.get('name', '').strip()
category_id :str = data.get('category_id', '').strip()
description :str= data.get('description', '')
is_active :bool = bool(int(data.get('is_active', 0)))
published_status :int = data.get('published_status', int(PublishedStatus.DRAFT.value)) # Defaults to DRAFT
author_id :str = data.get('author_id', '').strip()
# Validate required fields
if not name or not category_id or not author_id:
return jsonify({"error": "Missing required fields: 'name', 'category_id', or 'author_id'."}), 400
# Validate category existence
category :str= Category.query.get(category_id)
if not category:
return jsonify({"error": "Category not found."}), 404
# Validate author existence
author :str = User.query.get(author_id)
if not author:
return jsonify({"error": "Author not found."}), 404
# File handling
uploaded_cover_image = request.files.get('cover')
uploaded_file = request.files.get('pdf')
cover_filename_image :str= ''
pdf_file_filename :str= ''
if uploaded_cover_image is not None:
cover_filename_image :str = random_string_generator(10) + os.path.splitext(uploaded_cover_image.filename)[-1]
uploaded_cover_image.save(os.path.join(USER_UPLOADS_DIR, cover_filename_image))
if uploaded_file is not None:
pdf_file_filename :str= random_string_generator(10) + os.path.splitext(uploaded_file.filename)[-1]
uploaded_file.save( os.path.join(USER_UPLOADS_DIR, pdf_file_filename))
# Default to DRAFT if critical content is missing
if not uploaded_cover_image or not uploaded_file:
published_status :int= int(PublishedStatus.DRAFT.value)
# Create new course
new_course = Course(
name=name,
categoryID=uuid.UUID(category_id),
description=description,
isActive=is_active,
publishedStatus=int(published_status),
coverImage=cover_filename_image,
serverFilename=pdf_file_filename,
authorID=uuid.UUID(author_id),
creationDate=func.now(),
)
# Save the course to the database
db.session.add(new_course)
db.session.commit()
return jsonify({"message": "Course created successfully.", "course_id": str(new_course.id)}), 201
except Exception as e:
# Rollback in case of an error
db.session.rollback()
return jsonify({"error": f"An error occurred: {str(e)}"}), 500

@ -19,7 +19,7 @@ class User(db.Model):
email: Mapped[str] = mapped_column(String(64), nullable=False, unique=True) email: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
firstName: Mapped[str] = mapped_column(String(32), nullable=False) firstName: Mapped[str] = mapped_column(String(32), nullable=False)
lastName: Mapped[str] = mapped_column(String(32), nullable=False) lastName: Mapped[str] = mapped_column(String(32), nullable=False)
username: Mapped[str] = mapped_column(String(32), nullable=False, unique=True) username: Mapped[str] = mapped_column(String(32), nullable=False)
hash_password: Mapped[str] = mapped_column(String(256), nullable=False) hash_password: Mapped[str] = mapped_column(String(256), nullable=False)
activationKey: Mapped[str] = mapped_column(String(128), nullable=False) activationKey: Mapped[str] = mapped_column(String(128), nullable=False)
sessions: Mapped[List["Session"]] = relationship(back_populates="user", cascade="all, delete-orphan") sessions: Mapped[List["Session"]] = relationship(back_populates="user", cascade="all, delete-orphan")
@ -29,7 +29,6 @@ class User(db.Model):
chats: Mapped[List["Chat"]] = relationship(back_populates="user", cascade="all, delete-orphan") chats: Mapped[List["Chat"]] = relationship(back_populates="user", cascade="all, delete-orphan")
notifications: Mapped[List["Notification"]] = relationship(back_populates="user", cascade="all, delete-orphan") notifications: Mapped[List["Notification"]] = relationship(back_populates="user", cascade="all, delete-orphan")
user_badges: Mapped[List["UserBadge"]] = relationship(back_populates="user", cascade="all, delete-orphan") user_badges: Mapped[List["UserBadge"]] = relationship(back_populates="user", cascade="all, delete-orphan")
publications: Mapped[List["Course"]] = relationship(back_populates="author", cascade="all, delete-orphan")
dob: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.fromisocalendar(2002, 1, 1)) dob: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.fromisocalendar(2002, 1, 1))
pfpFilename: Mapped[str] = mapped_column(String(256), nullable=False, default=DEFAULT_PROFILE_FILE) pfpFilename: Mapped[str] = mapped_column(String(256), nullable=False, default=DEFAULT_PROFILE_FILE)
joinedDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now()) joinedDate: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=func.now())
@ -70,8 +69,6 @@ class Course(db.Model):
enrollments: Mapped[List["Enrollment"]] = relationship(back_populates="course", cascade="all, delete-orphan") enrollments: Mapped[List["Enrollment"]] = relationship(back_populates="course", cascade="all, delete-orphan")
quizzes: Mapped[List['Quiz']] = relationship(back_populates="course", cascade="all, delete-orphan") quizzes: Mapped[List['Quiz']] = relationship(back_populates="course", cascade="all, delete-orphan")
chats: Mapped[List["Chat"]] = relationship(back_populates="course", cascade="all, delete-orphan") chats: Mapped[List["Chat"]] = relationship(back_populates="course", cascade="all, delete-orphan")
authorID: Mapped[uuid.UUID] = mapped_column(ForeignKey("user.id"))
author: Mapped["User"] = relationship(back_populates="publications")
description: Mapped[str] = mapped_column(String(1024), nullable=False, default='') description: Mapped[str] = mapped_column(String(1024), nullable=False, default='')
isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) isActive: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True)
publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=PublishedStatus.DRAFT) publishedStatus: Mapped[int] = mapped_column(SmallInteger, nullable=False, default=PublishedStatus.DRAFT)

Loading…
Cancel
Save