from fastapi import APIRouter, Form, Depends, HTTPException, File, UploadFile from typing import List,Optional from fastapi.responses import FileResponse from random import randint from fastapi.security import OAuth2PasswordRequestForm from app.models.models import User,Favorite_course,Article_list from app.models.models import Class_list,Schools,Class_detail,Class_name,Registration,Group_name,Online_course 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 import requests import json classes = APIRouter() async def check_token(access_token: str): result = await User.filter(token=access_token).first() if not result: print("no access") return None user_id = result.id return user_id IMAGEDIR = "/var/www/ntcri/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=''), address : str = Form(default=''), update_time : datetime = Form(default=datetime.now()) ): try: new_school = await Schools.create( name=location_name, longitude=Lng, latitude=Lat, address = address, update_time = update_time ) 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=''), group_id : int = Form(default=1), group_sort :str = Form(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, group_id=group_id, group_sort=group_sort ) 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=''), registration_day: 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, registration_day=registration_day, 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()), content : str = Form(default='') ): try: session_list = await Class_detail.filter(class_list_id=class_event_id).all() session = 0 if session_list != []: for session_obj in session_list: if session < session_obj.sessions: session = session_obj.sessions new_session = await Class_detail.create( class_list_id=class_event_id, start_time=start_time, end_time=end_time, sessions=session +1, 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=''), 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 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=0), category: str = Form(default=''), introduction: str = Form(default=''), organizer: str = Form(default=''), cover_img_file:UploadFile = File(default=''), group_id : int = Form(default=0), group_sort : str = Form(default='') ): try: class_name = await Class_name.get(id=class_name_id) if name.strip() != '': class_name.name = name if location_id != 0: class_name.school_id = location_id update_location_time(location_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 group_id != 0 : class_name.group_id = group_id 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}" if group_sort != '': class_name.group_sort = group_sort await class_name.save() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_event") async def update_event( id: int = Form(default=0), 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=''), registration_day: 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 location.strip() != '': class_obj.location = location 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 registration_day.strip() != '': class_obj.registration_day = registration_day 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: Optional[int] = None, event_id : Optional[int] = None ): try: if event_id : class_list = await Class_list.filter(id=event_id).all() elif class_name_id: class_list = await Class_list.filter(name_id=class_name_id).all() else : return {"msg": "please input class_name_id or event_id", "code": 200} classes = [] for class_obj in class_list: class_name_obj = await Class_name.get(id=class_obj.name_id) class_name = class_name_obj.name 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, "registration_day": class_obj.registration_day, "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( location_id : Optional[int] = None ): try: if location_id : school_list = await Schools.filter(id = location_id).all() else : 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, "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 : Optional[int] = None , class_name_id : Optional[int] = None, group_id : Optional[int] = None, group_sort :Optional[str] = None, category :Optional[str] = None, page_num : Optional[int] = None, page_amount : Optional[int] = None ): try: class_name_list = Class_name.all() if group_sort: class_name_list = class_name_list.filter(group_sort = group_sort).all() if category: class_name_list = class_name_list.filter(Q(category__icontains=category)).all() if location_id : class_name_list = class_name_list.filter(school_id = location_id).all() if class_name_id : class_name_list = class_name_list.filter(id = class_name_id).all() class_name_list = await class_name_list.all() classes_name = [] count = 0 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 if not group_id or class_name_obj.group_id==group_id: 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, "group_id": class_name_obj.group_id, "cover_img": class_name_obj.cover_img, "group_sort":class_name_obj.group_sort } if page_num and page_amount: if count < page_num*page_amount and count >= (page_num-1)*page_amount : classes_name.append(class_data) count += 1 elif count >= page_num*page_amount: count += 1 else : count += 1 else : classes_name.append(class_data) count += 1 return {"msg": "success", "code": 200,"total_num" : count,"classes": classes_name} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_session") async def get_session( event_id : Optional[int] = None ): 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)|Q(group_sort__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_name_id: int, user_id = Depends(check_token), time_stemp: datetime = datetime.now() ): try: if not user_id: return {"msg": "no access", "code": 500} new_favorite_class = await Favorite_course.get_or_create( class_name_id=class_name_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 = Depends(check_token), no_details : Optional[int] = None ): try: class_list = await Favorite_course.filter(user_id = user_id).all() favorite_courses = [] for class_obj in class_list: if no_details: class_data = { "id": class_obj.id, "user_id": class_obj.user_id, "class_name_id" : class_obj.class_name_id, "time_stemp":class_obj.time_stemp } favorite_courses.append(class_data) else: class_data = { "id": class_obj.id, "user_id": class_obj.user_id, "class_name_id" : class_obj.class_name_id, "time_stemp":class_obj.time_stemp } result = await get_class_name(class_name_id = class_obj.class_name_id) class_detail = result["classes"][0] for class_tmp in class_detail.items(): class_data[class_tmp[0]] = class_tmp[1] favorite_courses.append(class_data) return {"msg": "success", "code": 200, "favorite_courses": favorite_courses} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/delete_favorite_class") async def delete_favorite_class( class_name_id: int, user_id = Depends(check_token) ): try: await Favorite_course.filter(class_name_id=class_name_id,user_id=user_id).delete() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/insert_online_course") async def insert_online_course( title : str = Form(default=''), category : str = Form(default=''), create_time :str = Form(default=datetime.now()), content : str = Form(default=''), vedio_url :str = Form(default='') ): try: new_online_course = await Online_course.create( title=title, create_time=create_time, category=category, content=content, vedio_url=vedio_url, group_id = 8 ) return {"msg": "success", "code": 200, "online_course_obj": new_online_course.id} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/update_online_course") async def update_online_course( id : int = Form(default=0), title : str = Form(default=''), category : str = Form(default=''), create_time :str = Form(default=datetime.now()), content : str = Form(default=''), vedio_url :str = Form(default='') ): try: online_course_obj = await Online_course.get(id=id) if title.strip() != '': online_course_obj.title = title if category.strip() != '': online_course_obj.category = category if create_time.strip() != '': online_course_obj.create_time = create_time if content.strip() != '': online_course_obj.content = content if vedio_url.strip() != '': online_course_obj.vedio_url = vedio_url await online_course_obj.save() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_online_courese") async def get_online_courese( online_courese_id : Optional[int] = None ): try: if online_courese_id : online_courese_list = await Online_course.filter(id = online_courese_id).all() else : online_courese_list = await Online_course.all() online_coureses = [] for online_coures_obj in online_courese_list: online_coures_data = { "id": online_coures_obj.id, "title": online_coures_obj.title, "category":online_coures_obj.category, "create_time": online_coures_obj.create_time, "click_time": online_coures_obj.click_time, "content": online_coures_obj.content, "vedio_url":online_coures_obj.vedio_url } online_coureses.append(online_coures_data) return {"msg": "success", "code": 200, "online_coures": online_coureses} except Exception as e: return {"msg": str(e), "code": 500} @classes.post("/delete_online_course") async def delete_online_course( online_course_id : int ): try: await Online_course.filter(id=online_course_id).delete() return {"msg": "success", "code": 200} except Exception as e: return {"msg": str(e), "code": 500} @classes.get("/get_group_classes_and_articles") async def get_group_classes_and_articles( group_id : int, page_num : Optional[int] = None, page_amount : Optional[int] = None ): try: class_name_list = await Class_name.filter(group_id = group_id).all() article_list = await Article_list.filter(group_id = group_id).all() article_objs = [] article_count = 0 for article_obj in article_list: article_tmp = { "article_id": article_obj.id, "title": article_obj.title, "school_id" :article_obj.school_id, "group_sort" :article_obj.group_sort, "group_id" :article_obj.group_id, "category": article_obj.category, "create_time" : article_obj.create_time, "click_time" : article_obj.click_time, "depiction" : article_obj.depiction, "content" : article_obj.content, "files" : article_obj.files, "vedio_url" : article_obj.vedio_url, "tags" : article_obj.tags, "cover_img": article_obj.cover_img } if page_num and page_amount: if article_count < page_num*page_amount and article_count >= (page_num-1)*page_amount : article_objs.append(article_tmp) article_count += 1 elif article_count >= page_num*page_amount: article_count += 1 else : article_count += 1 else : article_objs.append(article_tmp) article_count += 1 classes_name = [] class_count = 0 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 if not group_id or class_name_obj.group_id==group_id: 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, "group_id": class_name_obj.group_id, "cover_img": class_name_obj.cover_img, "group_sort":class_name_obj.group_sort } if page_num and page_amount: if class_count < page_num*page_amount and class_count >= (page_num-1)*page_amount : classes_name.append(class_data) class_count += 1 elif class_count >= page_num*page_amount: class_count += 1 else : class_count += 1 else : classes_name.append(class_data) class_count += 1 return {"msg": "success", "code": 200,"class_num" : class_count,"classes": classes_name,"article_num":article_count,"articles": article_objs} except Exception as e: return {"msg": str(e), "code": 500}