from flask import Blueprint, request, jsonify, g from sqlalchemy import select, and_ from werkzeug.datastructures import MultiDict import os import uuid from config import DEFAULT_COURSE_COVER from ...db.model import db, Course, Category, User, Chat from utils.utils import random_string_generator from utils.auth import auth_required, requires_role from constants import * from config import * from constants import PublishedStatus course = Blueprint('course', __name__) @course.route('/create', methods=['POST']) @auth_required() def create_course(): form_data: dict = request.form course_uploaded_cover_image: MultiDict|None = request.files.get('cover_image', None) course_uploaded_pdf: MultiDict|None = request.files.get('course_pdf', None) cover_file_name: str = DEFAULT_COURSE_COVER pdf_file_name: str = '' if course_uploaded_cover_image is not None: cover_file_name: str = random_string_generator(32)+course_uploaded_cover_image.filename.split('.')[-1] course_uploaded_cover_image.save(os.path.join(USER_UPLOADS_DIR, cover_file_name)) if course_uploaded_pdf is not None: pdf_file_name: str = random_string_generator(32) + course_uploaded_pdf.filename.split('.')[-1] course_uploaded_pdf.save(os.path.join(USER_UPLOADS_DIR, pdf_file_name)) published_status: PublishedStatus = PublishedStatus.DRAFT try: course_name: str = form_data['course_name'] except KeyError: return jsonify({'message': 'Course name cannot be empty'}), 401 course_description: str = form_data.get('course_description', '') category_id: uuid.UUID = uuid.UUID(form_data['category_uuid']) pages_required_for_community: int = int(form_data['community_unlock_at_pages']) # TODO: Add this field to model new_course: Course = Course( name=course_name, categoryID=category_id, authorID=g.current_user.id, description=course_description, isActive=True, publishedStatus=int(published_status), coverImage=cover_file_name, serverFilename =pdf_file_name, enrollments=[], quizzes=[], chats=[] ) # chat: Chat = Chat(courseID=new_course.id) TODO: Add a welcome chat for this course db.session.add_all(new_course) db.session.commit() return jsonify({'message': 'Course was created successfully.'}), 200 @course.route('/update', methods=['UPDATE', 'DELETE']) @auth_required() def update_course(): form_data = request.form course_id: uuid.UUID = uuid.UUID(form_data['course_id']) selected_course: Course|None = None if g.current_user.role == int(UserRole.ADMIN): selected_course: Course = db.session.execute(select(Course).where(and_( Course.id == course_id ))).scalar() else: selected_course: Course = db.session.execute(select(Course).where(and_( Course.id == course_id, Course.publishedStatus != int(PublishedStatus.BANNED) ))).scalar() if not selected_course: return jsonify({'message': 'The course could not be found'}), 404 if request.method == 'DELETE': if selected_course.authorID == g.current_user.id or g.current_user.role == int(UserRole.ADMIN): db.session.delete(selected_course) db.session.commit() return jsonify({'message': 'Course was deleted successfully'}), 200 else: return jsonify({'message': 'Unauthorized for this change'}), 401 else: # Update the data if selected_course.authorID == g.current_user.id or g.current_user.role == int(UserRole.ADMIN): if form_data.get('course_name'): selected_course.name = form_data.get('course_name') if form_data.get('course_description'): selected_course.description = form_data.get('course_description') if form_data.get('category_uuid'): selected_course.categoryID = uuid.UUID(form_data.get('category_uuid')) if form_data.get('isActive'): selected_course.isActive = bool(int(form_data.get('active'))) # Admin Guarded if form_data.get('published_status'): if g.current_user.role != int(UserRole.ADMIN): return jsonify({'message': 'Unauthorized'}), 401 valid_states: list[int] = [ int(e) for e in [PublishedStatus.APPROVED, PublishedStatus.PENDING, PublishedStatus.DECLINED, PublishedStatus.REVOKED, PublishedStatus.BANNED, PublishedStatus.DRAFT] ] if int(form_data.get('published_status')) not in valid_states: return jsonify({'message': 'Invalid state to update'}), 401 selected_course.publishedStatus = int(form_data.get('published_status')) if request.files.get('cover_image'): cover_file_name: str = random_string_generator(32) + request.files.get('cover_image').filename.split('.')[-1] request.files.get('cover_image').save(os.path.join(USER_UPLOADS_DIR, cover_file_name)) selected_course.coverImage = cover_file_name if request.files.get('course_pdf'): pdf_file_name: str = random_string_generator(32) + request.files.get('course_pdf').filename.split('.')[1] request.files.get('course_pdf').save(os.path.join(USER_UPLOADS_DIR, pdf_file_name)) selected_course.serverFilename = pdf_file_name if g.current_user.role != int(UserRole.ADMIN): selected_course.publishedStatus = int(PublishedStatus.PENDING) db.session.commit() return jsonify({'message': 'Course info updated'}), 200 else: return jsonify({'message': 'Unauthorized for this change'}), 401