from fastapi import APIRouter, Form, Depends, HTTPException, File, UploadFile from typing import List from fastapi.responses import FileResponse from random import randint from fastapi.security import OAuth2PasswordRequestForm from app.models.models import User,Favorite_course from app.models.models import Class_list,Schools,Class_detail,Class_name,Registration,Group_name from app.api import deps from sqlalchemy.orm import Session from typing import Any, Dict import secrets from fastapi_login.exceptions import InvalidCredentialsException from fastapi_login import LoginManager from datetime import timedelta,datetime from app.config import settings from pathlib import Path from jose import jwt from emails.template import JinjaTemplate from tortoise.queryset import Q from fastapi.responses import HTMLResponse classes = APIRouter() IMAGEDIR = "/var/www/html/ntcri/assets/" IMAGEDIR_short = "assets/" async def update_location_time(location_id: int): if location_id: school = await Schools.get(id=location_id) school.update_time = datetime.now() await school.save() return {"msg": "success", "code": 200} @classes.post("/insert_school") async def insert_school( location_name: str = Form(default=''), Lng: str = Form(default=''), Lat: str = Form(default=''), group_id : int = Form(default=1), address : str = Form(default='') ): try: new_school = await Schools.create( name=location_name, longitude=Lng, latitude=Lat, group_id = group_id, address = address ) return {"msg": "success", "code": 200, "location_id": new_school.id} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/insert_class_name") async def insert_class_name( name: str = Form(default=''), location_id: int = Form(default=1), category: str = Form(default=''), introduction: str = Form(default=''), organizer: str = Form(default=''), cover_img_file:UploadFile = File(default='') ): try: cover_img = '' if cover_img_file != '': contents = await cover_img_file.read() #save the file with open(f"{IMAGEDIR}{cover_img_file.filename}", "wb") as f: f.write(contents) cover_img = f"{IMAGEDIR_short}{cover_img_file.filename}" new_class_name = await Class_name.create( name=name, school_id=location_id, category=category, introduction=introduction, organizer=organizer, cover_img=cover_img ) update_location_time(location_id= location_id) return {"msg": "success", "code": 200, "new_class_name_id": new_class_name.id} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/insert_event") async def insert_event( name_id: int = Form(default=0), event: str = Form(default=''), start_time: datetime = Form(default=datetime.now()), end_time: datetime = Form(default=datetime.now()), contact: str = Form(default=''), lecturer: str = Form(default=''), location: str = Form(default=''), content: str = Form(default=''), URL: str = Form(default=''), people : str = Form(default=''), fee_method: str = Form(default=''), registration_way: str = Form(default=''), remark : str = Form(default='') ): try: # 檢查是否有該課程 class_name_list = await Class_name.filter(id=name_id).all() if class_name_list == []: return {"msg": "沒有此課程", "code": 200} new_class = await Class_list.create( name_id=name_id, event =event, start_time=start_time, end_time=end_time, contact=contact, lecturer=lecturer, location=location, content=content, URL=URL, people=people, fee_method=fee_method, registration_way=registration_way, remark=remark ) return {"msg": "success", "code": 200, "class_id": new_class.id} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/insert_session") async def insert_session( class_event_id : int = Form(default=0), start_time: datetime = Form(default=datetime.now()), end_time: datetime = Form(default=datetime.now()), sessions: str = Form(default=0), content : str = Form(default='') ): try: new_session = await Class_detail.create( class_list_id=class_event_id, start_time=start_time, end_time=end_time, sessions=sessions, content = content ) return {"msg": "success", "code": 200, "new_session_id": new_session.id} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_school") async def update_school( location_id: int = Form(default=0), location_name: str = Form(default=''), Lng: str = Form(default=''), Lat: str = Form(default=''), group_id : int = Form(default=1), address : str = Form(default='') ): try: school = await Schools.get(id=location_id) if location_name.strip() != '': school.name = location_name if Lng != '': school.longitude = Lng if Lat.strip() != '': school.latitude = Lat if group_id != 1 : school.group_id = group_id if address.strip() != '': school.address = address await school.save() update_location_time(location_id= location_id) return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_class_name") async def update_class_name( class_name_id: int = Form(default=0), name: str = Form(default=''), location_id: int = Form(default=''), category: str = Form(default=''), introduction: str = Form(default=''), organizer: str = Form(default=''), cover_img_file:UploadFile = File(default='') ): try: class_name = await Class_name.get(id=class_name_id) if name.strip() != '': class_name.name = name if location_id != '': class_name.school_id = location_id if category.strip() != '': class_name.category = category if introduction.strip() != '': class_name.introduction = introduction if organizer.strip() != '': class_name.organizer = organizer if cover_img_file != '': contents = await cover_img_file.read() with open(f"{IMAGEDIR}{cover_img_file.filename}", "wb") as f: f.write(contents) class_name.cover_img = f"{IMAGEDIR_short}{cover_img_file.filename}" await class_name.save() update_location_time(location_id= location_id) return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_event") async def update_class( id: int = Form(default=0), name_id: str = Form(default=0), event: str = Form(default=''), start_time: datetime = Form(default=datetime.now()), end_time: datetime = Form(default=datetime.now()), contact: str = Form(default=''), lecturer: str = Form(default=''), content: str = Form(default=''), URL: str = Form(default=''), people : str = Form(default=''), fee_method: str = Form(default=''), registration_way: str = Form(default=''), remark : str = Form(default='') ): try: class_obj = await Class_list.get(id=id) if name_id != 0: class_obj.name_id = name_id if event.strip() != '': class_obj.event = event if start_time: class_obj.start_time = start_time if end_time: class_obj.end_time = end_time if lecturer.strip() != '': class_obj.lecturer = lecturer if contact.strip() != '': class_obj.contact = contact if content.strip() != '': class_obj.content = content if URL.strip() != '': class_obj.URL = URL if people.strip() != '': class_obj.people = people if fee_method.strip() != '': class_obj.fee_method = fee_method if registration_way.strip() != '': class_obj.registration_way = registration_way if remark.strip() != '': class_obj.remark = remark await class_obj.save() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_session") async def update_session( session_id : int = Form(default=0), class_event_id : int = Form(default=0), start_time: datetime = Form(default=datetime.now()), end_time: datetime = Form(default=datetime.now()), sessions: str = Form(default=0), content : str = Form(default='') ): try: class_session_obj = await Class_detail.get(id=session_id) if class_event_id != 0: class_session_obj.class_list_id = class_event_id if start_time != '': class_session_obj.start_time = start_time if end_time != '': class_session_obj.end_time = end_time if sessions.strip() != '': class_session_obj.sessions = sessions if content.strip() != '': class_session_obj.content = content await class_session_obj.save() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/delete_school") async def delete_school(location_id: int): if location_id: await Schools.filter(id=location_id).delete() return {"msg": "success", "code": 200} @classes.post("/delete_session") async def delete_session(id: int): if id: await Class_detail.filter(id=id).delete() return {"msg": "success", "code": 200} @classes.post("/delete_event") async def delete(id: int): if id: await Class_detail.filter(class_list_id=id).delete() await Class_list.filter(id=id).delete() return {"msg": "success", "code": 200} @classes.post("/delete_class_name") async def delete(id: int): if id: class_event_list = await Class_list.filter(name_id=id).all() for class_event_obj in class_event_list: await Class_detail.filter(class_list_id=class_event_obj.id).delete() await Class_list.filter(name_id=id).delete() await Class_name.filter(id=id).delete() return {"msg": "success", "code": 200} @classes.get("/get_event") async def search_event(class_name_id: int = 0): try: class_list = await Class_list.filter(name_id=class_name_id).all() class_name_obj = await Class_name.get(id=class_name_id) class_name = class_name_obj.name classes = [] for class_obj in class_list: class_data = { "class_name" : class_name, "event_id": class_obj.id, "name_id": class_obj.name_id, "event": class_obj.event, "start_time": class_obj.start_time, "end_time": class_obj.end_time, "location": class_obj.location, "lecturer": class_obj.lecturer, "contact": class_obj.contact, "content": class_obj.content, "URL": class_obj.URL, "people": class_obj.people, "fee_method": class_obj.fee_method, "registration_way": class_obj.registration_way, "remark": class_obj.remark } classes.append(class_data) return {"msg": "success", "code": 200, "classes": classes} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_school") async def get_school(): try: school_list = await Schools.all() schools = [] for school_obj in school_list: school_data = { "location_id": school_obj.id, "location_name": school_obj.name, "Lng": school_obj.longitude, "Lat": school_obj.latitude, "group_id": school_obj.group_id, "address": school_obj.address, "update_time":school_obj.update_time } schools.append(school_data) return {"msg": "success", "code": 200, "schools": schools} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_group_name") async def get_school_group(): try: school_group_list = await Group_name.all() school_groups = [] for school_obj in school_group_list: school_data = { "group_id": school_obj.id, "group_name": school_obj.group_name } school_groups.append(school_data) return {"msg": "success", "code": 200, "school_groups": school_groups} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_class_name") async def get_class_name( location_id : int = 0 , class_name_id : int = 0 ): try: if location_id == 0: if class_name_id == 0 : class_name_list = await Class_name.all() else : class_name_list = await Class_name.filter(id = class_name_id).all() else: class_name_list = await Class_name.filter(school_id = location_id).all() classes_name = [] for class_name_obj in class_name_list: school_obj = await Schools.filter(id=class_name_obj.school_id).all() school_name = "" if school_obj == []: school_name = "未設定據點" else : school_obj = await Schools.get(id=class_name_obj.school_id) school_name = school_obj.name class_data = { "class_name_id": class_name_obj.id, "name": class_name_obj.name, "school":school_name, "category": class_name_obj.category, "introduction": class_name_obj.introduction, "organizer": class_name_obj.organizer, "cover_img": class_name_obj.cover_img } classes_name.append(class_data) return {"msg": "success", "code": 200, "classes": classes_name} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_session") async def get_session( event_id : int = 0 ): try: class_session_list = await Class_detail.filter(class_list_id=event_id).all() classe_sessions = [] for class_session_obj in class_session_list: class_session_data = { "session_id": class_session_obj.id, "class_event_id": class_session_obj.class_list_id, "start_time": class_session_obj.start_time, "end_time": class_session_obj.end_time, "sessions": class_session_obj.sessions, "content": class_session_obj.content } classe_sessions.append(class_session_data) return {"msg": "success", "code": 200, "classe_sessions": classe_sessions} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/search_class_like") async def search_class_like(keyword: str): try: class_list = await Class_list.filter(Q(lecturer__icontains=keyword)).all() classes = [] for class_obj in class_list: class_name = await Class_name.get(id=class_obj.name_id) school_obj = await Schools.get(id=class_name.school_id) class_data = { "msg": "success", "code": 200, "class_id": class_obj.id, "name": class_name.name, "school":school_obj.name, "category": class_name.category, "introduction": class_name.introduction, "organizer": class_name.organizer, "cover_img": class_name.cover_img, "event": class_obj.event, "start_time": class_obj.start_time, "end_time": class_obj.end_time, "location": class_obj.location, "lecturer": class_obj.lecturer, "contact": class_obj.contact, "content": class_obj.content, "URL": class_obj.URL, "people": class_obj.people, "fee_method": class_obj.fee_method, "registration_way": class_obj.registration_way, "remark": class_obj.remark } classes.append(class_data) class_name_list = await Class_name.filter(Q(name__icontains=keyword)).all() for class_name in class_name_list: class_list = await Class_list.filter(name_id=class_name.id).all() for class_obj in class_list: school_obj = await Schools.get(id=class_name.school_id) class_data = { "msg": "success", "code": 200, "class_id": class_obj.id, "name": class_name.name, "school":school_obj.name, "category": class_name.category, "introduction": class_name.introduction, "organizer": class_name.organizer, "cover_img": class_name.cover_img, "event": class_obj.event, "start_time": class_obj.start_time, "end_time": class_obj.end_time, "location": class_obj.location, "lecturer": class_obj.lecturer, "contact": class_obj.contact, "content": class_obj.content, "URL": class_obj.URL, "people": class_obj.people, "fee_method": class_obj.fee_method, "registration_way": class_obj.registration_way, "remark": class_obj.remark } classes.append(class_data) return {"msg": "success", "code": 200, "classes": classes} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/add_favorite_class") async def add_favorite_class( class_event_id: int, user_id : int, time_stemp: datetime = datetime.now() ): try: new_favorite_class = await Favorite_course.get_or_create( class_event_id=class_event_id, user_id=user_id, defaults={'time_stemp': time_stemp} ) return {"msg": "success", "code": 200,"is exist": not new_favorite_class[1],"id":new_favorite_class[0].id} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("get_favorite_class") async def get_favorite_class( user_id : int ): try: class_list = await Favorite_course.filter(user_id = user_id).all() favorite_courses = [] for class_obj in class_list: class_event = await Class_list.get(id = class_obj.class_event_id) class_name = await Class_name.get(id = class_event.name_id) class_data = { "id": class_obj.id, "user_id": class_obj.user_id, "class_event_id":class_obj.class_event_id, "class_name_id" : class_name.id, "time_stemp":class_obj.time_stemp } favorite_courses.append(class_data) return {"msg": "success", "code": 200, "school_groups": favorite_courses} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/delete_favorite_class") async def delete_favorite_class( class_event_id: int, user_id : int ): try: await Favorite_course.filter(class_event_id=class_event_id,user_id=user_id).delete() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/uploadfiles/") async def create_upload_files(files: List[UploadFile]): return {"filenames": [file.filename for file in files]}